From: Jason Merrill Date: Mon, 27 Jan 2020 10:45:01 +0000 (-0500) Subject: c++: Avoid ICE with dependent attribute on type. X-Git-Tag: misc/first-auto-changelog-9~76 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=aa988998be8f85334665a6b049d5d9139408c250;p=thirdparty%2Fgcc.git c++: Avoid ICE with dependent attribute on type. We previously happened to accept this testcase, but never actually did anything useful with the attribute. The patch for PR86379 stopped using TREE_TYPE as USING_DECL_SCOPE, so 'using A::b' no longer had TREE_TYPE set, so the language-independent decl_attributes started crashing on it. GNU attributes are more flexible in their placement than C++11 attributes, so if we encounter a dependent GNU attribute that syntactically appertains to a type rather than the declaration as a whole, move it to the declaration; that's almost certainly what the user meant, anyway. gcc/cp/ChangeLog 2020-01-27 Jason Merrill PR c++/90750 PR c++/79585 * decl.c (grokdeclarator): Move dependent attribute to decl. * decl2.c (splice_template_attributes): No longer static. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f8070a550557..fe53cc0c0bd3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2020-04-27 Jason Merrill + + PR c++/90750 + PR c++/79585 + * decl.c (grokdeclarator): Move dependent attribute to decl. + * decl2.c (splice_template_attributes): No longer static. + 2020-04-21 Martin Sebor Jason Merrill diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 0e0efd749bc9..1f013c172cec 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6492,6 +6492,7 @@ extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *, tree, bool, tree, tree); extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *, tree, tree, tree); +extern tree splice_template_attributes (tree *, tree); extern bool any_dependent_type_attributes_p (tree); extern tree cp_reconstruct_complex_type (tree, tree); extern bool attributes_naming_typedef_ok (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 04d0b38ddf08..79f61dfe0646 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11259,9 +11259,13 @@ grokdeclarator (const cp_declarator *declarator, attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT; if (declarator->kind == cdk_array) attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT; + /* Assume that any attributes that get applied late to templates will + DTRT when applied to the declaration as a whole. */ + tree late_attrs = splice_template_attributes (&attrs, type); returned_attrs = decl_attributes (&type, chainon (returned_attrs, attrs), attr_flags); + returned_attrs = chainon (late_attrs, returned_attrs); } inner_declarator = declarator->declarator; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a46cbce08f4d..a15bb3c45cc4 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1208,7 +1208,7 @@ is_late_template_attribute (tree attr, tree decl) the declaration itself is dependent, so all attributes should be applied at instantiation time. */ -static tree +tree splice_template_attributes (tree *attr_p, tree decl) { tree *p = attr_p; diff --git a/gcc/testsuite/g++.dg/ext/attr-type1.C b/gcc/testsuite/g++.dg/ext/attr-type1.C new file mode 100644 index 000000000000..6e84cccea1f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-type1.C @@ -0,0 +1,19 @@ +// PR c++/90750 +// { dg-do compile { target c++11 } } + +template struct S +{ + static const int b = 64; +}; + +template struct T: S +{ + using A = S; + using A::b; + char* __attribute__((aligned(b))) c; +}; + +T t; + +#define SA(X) static_assert (X,#X) +SA (alignof(T) == S::b); diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-26.C b/gcc/testsuite/g++.dg/warn/Wunused-var-26.C index b3e020b60078..89c53de88a46 100644 --- a/gcc/testsuite/g++.dg/warn/Wunused-var-26.C +++ b/gcc/testsuite/g++.dg/warn/Wunused-var-26.C @@ -47,10 +47,10 @@ template void f_var_type_unused () { // The variable's type is marked unused. - T* UNUSED t = new T; // { dg-bogus "unused variable" "bug 79585" { xfail *-*-* } } + T* UNUSED t = new T; // { dg-bogus "unused variable" "bug 79585" } typedef T U; - U* UNUSED u = new U; // { dg-bogus "unused variable" "bug 79585" { xfail *-*-* } } + U* UNUSED u = new U; // { dg-bogus "unused variable" "bug 79585" } typedef T UNUSED U; U v = U (); // { dg-bogus "unused variable" "bug 79585" }