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.

Reply via email to