From: Alexandre Oliva Date: Wed, 28 Mar 2018 05:05:14 +0000 (+0000) Subject: [PR c++/84973] don't defer output of uninstantiated templates X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=977bc3ee11383e76acde2835ab4e2070904cf0bb;p=gcc.git [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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 23f5d3a7e1b..fc7b6b9ce13 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2018-03-28 Alexandre Oliva + 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 e522b9ebe55..fa753749e1a 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 929d4dd575a..252854e34c8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2018-03-28 Alexandre Oliva + 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 00000000000..41c205ad524 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr84973-2.C @@ -0,0 +1,13 @@ +// { dg-do compile } + +template 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 00000000000..eeac214f2e1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr84973-3.C @@ -0,0 +1,13 @@ +// { dg-do link } + +template 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 00000000000..b3f7170bc0d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr84973.C @@ -0,0 +1,8 @@ +// { dg-do compile } + +template void a() { + typedef struct { + void b() try { b; } catch (short) { + } + } c; +}