https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118277
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Calling cxx_constant_value on a random expression when processing_template_decl is wrong, the function to call when processing_template_decl is fold_non_dependent_expr instead. If it returns the desired constant expression (non-dependent), great, it can be used as is, otherwise it should be saved and the cxx_constant_value and extraction etc. repeated only during instantiation time. In many places, if some expressions are non-dependent when processing_template_decl, a lot of routines try to use them (to be able to diagnose errors already when parsing a template rather than only when instantiating it), but in the end usually for the processing_template_decl case it will build something with the original expressions and then repeat from pt.cc (which can be again with processing_template_decl if it is partial specialization, or with !processing_template_decl otherwise). In the finish_asm_stmt case we actually don't bother though, for processing_template_decl most of the function is actually skipped and it just builds ASM_EXPR at the end. So, I'd suggest to move most of the cp_parser_asm_string_expression handling to the start of finish_asm_stmt (right into the if (!processing_template_decl) block). cp_parser_asm_string_expression should just handle the STRING_CST case as it was handling it before, and for the CPP_OPEN_PAREN case just similarly to the static_assert handling just ensure that string from it will never be a STRING_CST. So, in cp_parser_asm_string_expression just: if (tok->type == CPP_OPEN_PAREN) { matching_parens parens; parens.consume_open (parser); tree string = cp_parser_constant_expression (parser); if (TREE_CODE (string) == STRING_CST) string = build1_loc (tok->location, PAREN_EXPR, TREE_TYPE (string), string); parens.require_close (parser); return string; } and in finish_asm_stmt call a helper function which will do the if (string != error_mark_node) string = cxx_constant_value (string, tf_error); cexpr_str cstr (string); if (!cstr.type_check (tok->location)) return error_mark_node; if (!cstr.extract (tok->location, string)) string = error_mark_node; handling if TREE_CODE (string) != STRING_CST. But needs to do it not just in the case of the asm template string, but all the clobbers and constraints. It isn't that easy though, because cp_parser_asm_string_expression isn't used just for asm statements with extended and basic syntax (i.e. asm ((...) : ...); and asm ((...));) but also in cp_parser_asm_specification_opt. That is mostly for declarations, void foo (int) asm ("bar"); I'm not really sure if that was intentionally changed, I don't see that covered in the testsuite, stuff like template <typename T> constexpr S<T> bar () { ... } template <typename T> void foo (T, T) asm ((bar<T> ()); void baz () { foo (0, 0); } and the like. If you want to handle it, you'll need to handle it during instantiation in all the places into which the cp_parser_asm_specification_opt result is stored (plus add testcases). BTW, another possibility would be to keep doing the cp_parser_asm_string_expression extra part I've left out by calling the helper function in there too for !processing_template_decl, but that could only hide that it needs to be repeated at instantiation time if it was skipped during parsing time.