mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-26 09:50:40 +08:00
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-04-27 Jason Merrill <jason@redhat.com> PR c++/90750 PR c++/79585 * decl.c (grokdeclarator): Move dependent attribute to decl. * decl2.c (splice_template_attributes): No longer static.
This commit is contained in:
parent
bb7ed17aa1
commit
5f1cd1da1a
@ -1,3 +1,10 @@
|
||||
2020-04-27 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/90750
|
||||
PR c++/79585
|
||||
* decl.c (grokdeclarator): Move dependent attribute to decl.
|
||||
* decl2.c (splice_template_attributes): No longer static.
|
||||
|
||||
2020-04-27 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
PR c++/94772
|
||||
|
@ -6626,6 +6626,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);
|
||||
|
@ -11937,9 +11937,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;
|
||||
|
@ -1228,7 +1228,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;
|
||||
|
19
gcc/testsuite/g++.dg/ext/attr-type1.C
Normal file
19
gcc/testsuite/g++.dg/ext/attr-type1.C
Normal file
@ -0,0 +1,19 @@
|
||||
// PR c++/90750
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
template <typename> struct S
|
||||
{
|
||||
static const int b = 64;
|
||||
};
|
||||
|
||||
template <typename a> struct T: S<a>
|
||||
{
|
||||
using A = S<a>;
|
||||
using A::b;
|
||||
char* __attribute__((aligned(b))) c;
|
||||
};
|
||||
|
||||
T<int> t;
|
||||
|
||||
#define SA(X) static_assert (X,#X)
|
||||
SA (alignof(T<int>) == S<int>::b);
|
@ -47,10 +47,10 @@ template <class T>
|
||||
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" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user