When an anon struct gets a name through a typedef, we reset its
linkage and that of its members. Member functions may get vague
linkage, which schedules them for deferred output, but we don't want
to add them to the queue if they're uninstantiated templates,
e.g. because the enclosing function is a template. They will be added
as needed when the enclosing template is instantiated.
for gcc/cp/ChangeLog
PR c++/84973
* decl2.c (note_vague_linkage_fn): Don't defer uninstantiated
templates.
for gcc/testsuite/ChangeLog
PR c++/84973
* g++.dg/template/pr84973.C: New.
* g++.dg/template/pr84973-2.C: New.
* g++.dg/template/pr84973-3.C: New.
From-SVN: r258914
2018-03-28 Alexandre Oliva <aoliva@redhat.com>
+ PR c++/84973
+ * decl2.c (note_vague_linkage_fn): Don't defer uninstantiated
+ templates.
+
PR c++/84968
* tree.c (strip_typedefs_expr): Reject STATEMENT_LISTs.
void
note_vague_linkage_fn (tree decl)
{
+ if (processing_template_decl)
+ return;
+
DECL_DEFER_OUTPUT (decl) = 1;
vec_safe_push (deferred_fns, decl);
}
2018-03-28 Alexandre Oliva <aoliva@redhat.com>
+ PR c++/84973
+ * g++.dg/template/pr84973.C: New.
+ * g++.dg/template/pr84973-2.C: New.
+ * g++.dg/template/pr84973-3.C: New.
+
PR c++/84968
* g++.dg/eh/pr84968.C: New.
--- /dev/null
+// { dg-do compile }
+
+template <int> void a() {
+ typedef struct {
+ void b() try { b; } catch (short) { // { dg-error "invalid use" }
+ }
+ } c;
+}
+
+int
+main() {
+ a<0>();
+}
--- /dev/null
+// { dg-do link }
+
+template <int> void a() {
+ typedef struct {
+ void b() try { b(); } catch (short) {
+ }
+ } c;
+}
+
+int
+main() {
+ a<0>();
+}
--- /dev/null
+// { dg-do compile }
+
+template <int> void a() {
+ typedef struct {
+ void b() try { b; } catch (short) {
+ }
+ } c;
+}