On 8/25/25 2:52 AM, Jakub Jelinek wrote:
Hi!
The following testcase shows an ICE when a parameter of a non-template
function is referenced in expansion stmt body.
tsubst_expr in that case assumes that either the PARM_DECL has registered
local specialization, or is this argument or it is in unevaluated context.
Parameters are always defined outside of the expansion statement
for-range-declaration or body, so for the instantiation of the body
outside of templates should always map to themselves.
It could be fixed by registering local self-specializations for all the
function parameters, but just handling it in tsubst_expr seems to be easier
and less costly.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2025-08-25 Jakub Jelinek <ja...@redhat.com>
PR c++/121575
* pt.cc (tsubst_expr) <case PARM_DECL>: During expansion stmt body
instantiation outside of templates return t for PARM_DECLs without
local specialization.
* g++.dg/cpp26/expansion-stmt20.C: New test.
--- gcc/cp/pt.cc.jj 2025-08-23 15:00:04.262787988 +0200
+++ gcc/cp/pt.cc 2025-08-23 15:51:08.726081054 +0200
@@ -22321,6 +22321,13 @@ tsubst_expr (tree t, tree args, tsubst_f
if (DECL_NAME (t) == this_identifier && current_class_ptr)
RETURN (current_class_ptr);
+ /* Parameters during expansion stmt body instantiation outside
+ of templates map to themselves. */
+ if (current_tinst_level
+ && (TREE_CODE (current_tinst_level->tldcl)
+ == TEMPLATE_FOR_STMT))
+ RETURN (t);
Rather than checking specifically for an expansion stmt, I'd prefer to
check for the general case of the parameter not being in a template,
perhaps with
if (!uses_template_parms (DECL_CONTEXT (t))
since that test is already used in the controlling if?
Jason