https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118277
--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
static_assert does:
/* Parse the message expression. */
bool string_lit = true;
for (unsigned int i = 1; ; ++i)
{
cp_token *tok = cp_lexer_peek_nth_token (parser->lexer, i);
if (cp_parser_is_pure_string_literal (tok))
continue;
else if (tok->type == CPP_CLOSE_PAREN)
break;
string_lit = false;
break;
}
if (!string_lit)
{
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
if (cxx_dialect < cxx26)
pedwarn (loc, OPT_Wc__26_extensions,
"%<static_assert%> with non-string message only "
"available with %<-std=c++2c%> or %<-std=gnu++2c%>");
message = cp_parser_conditional_expression (parser);
if (TREE_CODE (message) == STRING_CST)
message = build1_loc (loc, PAREN_EXPR, TREE_TYPE (message),
message);
}
else if (cxx_dialect >= cxx26)
message = cp_parser_unevaluated_string_literal (parser);
else
message = cp_parser_string_literal (parser, /*translate=*/false,
/*wide_ok=*/true);
...
/* Complete the static assertion, which may mean either processing
the static assert now or saving it for template instantiation. */
finish_static_assert (condition, message, assert_loc, member_p,
/*show_expr_p=*/false);
Inside finish_static_assert then does:
cexpr_str cstr(message);
if (!cstr.type_check (location))
return;
/* Save the condition in case it was a concept check. */
tree orig_condition = condition;
if (instantiation_dependent_expression_p (condition)
|| instantiation_dependent_expression_p (message))
{
/* We're in a template; build a STATIC_ASSERT and put it in
the right place. */
defer:
tree assertion = make_node (STATIC_ASSERT);
STATIC_ASSERT_CONDITION (assertion) = orig_condition;
STATIC_ASSERT_MESSAGE (assertion) = cstr.message;
STATIC_ASSERT_SOURCE_LOCATION (assertion) = location;
if (member_p)
maybe_add_class_template_decl_list (current_class_type,
assertion,
/*friend_p=*/0);
else
add_stmt (assertion);
return;
}
...
int len;
const char *msg = NULL;
if (!cstr.extract (location, msg, len))
return;
And finish_static_assert is called again from pt.c for STATIC_ASSERT.
Notice instantiation_dependent_expression_p (message) here.
So the processing of the const expr is left outside and done during semantics
rather than inside the parser to handle dependent arguments and such.