On Sat, Mar 14, 2026 at 03:50:17PM -0400, Jason Merrill wrote: > There's a second fallback (to tsubst_decl) after name lookup, I would think > that we just want to skip the lookup if DECL_NAME is null.
>From quick testing, this seems to work too. Ok for trunk if it passes full bootstrap/regtest? 2026-03-14 Jakub Jelinek <[email protected]> PR c++/120039 PR c++/122559 * pt.cc (tsubst_expr) <case VAR_DECL>: Don't call lookup_name on DECL_NAME (t) if it is NULL_TREE. * g++.dg/cpp26/decomp28.C: New test. * g++.dg/cpp26/decomp29.C: New test. --- gcc/cp/pt.cc.jj 2026-03-14 09:46:16.671478112 +0100 +++ gcc/cp/pt.cc 2026-03-14 21:06:22.139092954 +0100 @@ -22731,7 +22731,8 @@ tsubst_expr (tree t, tree args, tsubst_f else if (r == NULL_TREE) { /* First try name lookup to find the instantiation. */ - r = lookup_name (DECL_NAME (t)); + if (DECL_NAME (t)) + r = lookup_name (DECL_NAME (t)); if (r) { if (!VAR_P (r)) --- gcc/testsuite/g++.dg/cpp26/decomp28.C.jj 2026-03-14 21:05:50.802252148 +0100 +++ gcc/testsuite/g++.dg/cpp26/decomp28.C 2026-03-14 21:05:50.802252148 +0100 @@ -0,0 +1,23 @@ +// PR c++/120039 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct S { + int a; long long b; short c; + explicit operator bool () const noexcept { return true; } +}; + +template <int N> +void +foo () +{ + S s = S { 1, 2, 3 }; + if (auto [sx, sy, sz] : s) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } } + ; // { dg-error "expected initializer before ':' token" "" { target *-*-* } .-1 } +} // { dg-error "expected '\\\)' before ':' token" "" { target *-*-* } .-2 } + +int +main () +{ + foo <0> (); +} --- gcc/testsuite/g++.dg/cpp26/decomp29.C.jj 2026-03-14 21:05:50.802350073 +0100 +++ gcc/testsuite/g++.dg/cpp26/decomp29.C 2026-03-14 21:05:50.802350073 +0100 @@ -0,0 +1,19 @@ +// PR c++/122559 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +enum class A : bool { B, C }; + +template <typename T> +A type (T &&x) +{ + if (auto [value = x ()]) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } } + return A::C; // { dg-error "expected '\\\]' before '=' token" "" { target *-*-* } .-1 } + return A::B; // { dg-error "expected initializer before '\\\)' token" "" { target *-*-* } .-2 } +} + +int +main () +{ + auto _ = type (A::B); +} Jakub
