aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2018-03-28 05:05:14 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2018-03-28 05:05:14 +0000
commit977bc3ee11383e76acde2835ab4e2070904cf0bb (patch)
tree72d8d670b2283dea022de70c80a412d6b390705f
parent04acc378eb62c937576065668df01a23fa1b0680 (diff)
downloadgcc-977bc3ee11383e76acde2835ab4e2070904cf0bb.zip
gcc-977bc3ee11383e76acde2835ab4e2070904cf0bb.tar.gz
gcc-977bc3ee11383e76acde2835ab4e2070904cf0bb.tar.bz2
[PR c++/84973] don't defer output of uninstantiated templates
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
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/pr84973-2.C13
-rw-r--r--gcc/testsuite/g++.dg/template/pr84973-3.C13
-rw-r--r--gcc/testsuite/g++.dg/template/pr84973.C8
6 files changed, 46 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 23f5d3a..fc7b6b9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index e522b9e..fa75374 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 929d4dd..252854e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..41c205a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr84973-2.C
@@ -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
index 0000000..eeac214
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr84973-3.C
@@ -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
index 0000000..b3f7170
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr84973.C
@@ -0,0 +1,8 @@
+// { dg-do compile }
+
+template <int> void a() {
+ typedef struct {
+ void b() try { b; } catch (short) {
+ }
+ } c;
+}