[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 23f5d3a7e1b6be2b97f93f5f87df5c0d8e993c60..fc7b6b9ce13566653697ac25bb5bcff42a0e1800 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 e522b9ebe55a708ec97adc163f050fb63294191d..fa753749e1a6b63f2497f529e35cdb211fca883c 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 929d4dd575ad050d14714e0b9ccbb064933695f5..252854e34c805fd075c5c6e79b4b807c4ebc0be5 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;
+}