On Wed, Jan 29, 2020 at 10:06:51PM +0100, Paolo Carlini wrote: > Hi, > > On 29/01/20 19:00, Jason Merrill wrote: > > On 1/29/20 4:31 AM, Paolo Carlini wrote: > > > Hi, > > > > > > in this regression we issue a diagnostic about an incomplete type > > > (only a warning by default) and then we crash when we try to query > > > has_attribute on a member of the type because in such cases the > > > member remains an IDENTIFIER_NODE which of course doesn't have a > > > TREE_TYPE neither a DECL_ATTRIBUTES... Simply recognizing > > > IDENTIFIER_NODEs and returning false works fine, not sure if we want > > > to do something more sophisticated. Tested x86_64-linux. > > > > Why are we getting to has_attribute at all for a type-dependent argument? > > Because the implementation of __builtin_has_attribute, largely shared with > the C front-end, doesn't know about templates at all? :-/ > > Not sure it's the best time to complete it, but shouldn't be too difficult.
This ICEs even with a more reasonable test like template<typename T> void foo () { static_assert(!__builtin_has_attribute(T::a, aligned)); } The problem here is that __builtin_has_attribute doesn't handle type-dependent arguments at all. To handle type-dependent arguments we'd have to introduce a new template code, like STATIC_ASSERT or ADDRESSOF_EXPR (or a new generic template code for built-ins?), but that's always a pain. Or, meanwhile, we could just sorry. Martin, what do you think? --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -8682,7 +8682,12 @@ cp_parser_has_attribute_expression (cp_parser *parser) location_t atloc = cp_lexer_peek_token (parser->lexer)->location; if (tree attr = cp_parser_gnu_attribute_list (parser, /*exactly_one=*/true)) { - if (oper != error_mark_node) + if (oper == error_mark_node) + /* Nothing. */; + else if (type_dependent_expression_p (oper)) + sorry_at (atloc, "%<__builtin_has_attribute%> with dependent argument " + "not supported yet"); + else { /* Fold constant expressions used in attributes first. */ cp_check_const_attributes (attr); Marek