[PR c++/84973] don't defer output of uninstantiated templates
authorAlexandre Oliva <aoliva@redhat.com>
Wed, 28 Mar 2018 05:05:14 +0000 (05:05 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Wed, 28 Mar 2018 05:05:14 +0000 (05:05 +0000)
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

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/pr84973-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/pr84973-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/pr84973.C [new file with mode: 0644]

index 23f5d3a..fc7b6b9 100644 (file)
@@ -1,5 +1,9 @@
 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.
 
index e522b9e..fa75374 100644 (file)
@@ -739,6 +739,9 @@ check_classfn (tree ctype, tree function, tree template_parms)
 void
 note_vague_linkage_fn (tree decl)
 {
+  if (processing_template_decl)
+    return;
+
   DECL_DEFER_OUTPUT (decl) = 1;
   vec_safe_push (deferred_fns, decl);
 }
index 929d4dd..252854e 100644 (file)
@@ -1,5 +1,10 @@
 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.
 
diff --git a/gcc/testsuite/g++.dg/template/pr84973-2.C b/gcc/testsuite/g++.dg/template/pr84973-2.C
new file mode 100644 (file)
index 0000000..41c205a
--- /dev/null
@@ -0,0 +1,13 @@
+// { dg-do compile }
+
+template <int> void a() {
+  typedef struct {
+    void b() try { b; } catch (short) { // { dg-error "invalid use" }
+    }
+  } c;
+}
+
+int
+main() {
+  a<0>();
+}
diff --git a/gcc/testsuite/g++.dg/template/pr84973-3.C b/gcc/testsuite/g++.dg/template/pr84973-3.C
new file mode 100644 (file)
index 0000000..eeac214
--- /dev/null
@@ -0,0 +1,13 @@
+// { dg-do link }
+
+template <int> void a() {
+  typedef struct {
+    void b() try { b(); } catch (short) {
+    }
+  } c;
+}
+
+int
+main() {
+  a<0>();
+}
diff --git a/gcc/testsuite/g++.dg/template/pr84973.C b/gcc/testsuite/g++.dg/template/pr84973.C
new file mode 100644 (file)
index 0000000..b3f7170
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-do compile }
+
+template <int> void a() {
+  typedef struct {
+    void b() try { b; } catch (short) {
+    }
+  } c;
+}