In the below testcase, during finish_compound_literal for A<B{V}>{}, type_uses_auto finds and returns the CTAD placeholder for B{V}, which tricks us into attempting CTAD on A<B{V}>{} and leads to bogus errors.
AFAICT 'type' will always be a bare 'auto' in the CTAD case, so we don't need to look deeply to find it; checking template_placeholder_p instead should suffice here. Bootstrapped and regtested on x86_64-pc-linux-gnu, and also on cmcstl2 and range-v3. Does this look OK for trunk, or perhaps stage1? gcc/cp/ChangeLog: PR c++/99586 * semantics.c (finish_compound_literal): Check template_placeholder_p instead of type_uses_auto. gcc/testsuite/ChangeLog: PR c++/99586 * g++.dg/cpp2a/nontype-class42.C: New test. --- gcc/cp/semantics.c | 15 +++++++-------- gcc/testsuite/g++.dg/cpp2a/nontype-class42.C | 8 ++++++++ 2 files changed, 15 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class42.C diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b02596f73bd..8eaaaefe2d6 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3036,14 +3036,13 @@ finish_compound_literal (tree type, tree compound_literal, return error_mark_node; } - if (tree anode = type_uses_auto (type)) - if (CLASS_PLACEHOLDER_TEMPLATE (anode)) - { - type = do_auto_deduction (type, compound_literal, anode, complain, - adc_variable_type); - if (type == error_mark_node) - return error_mark_node; - } + if (template_placeholder_p (type)) + { + type = do_auto_deduction (type, compound_literal, type, complain, + adc_variable_type); + if (type == error_mark_node) + return error_mark_node; + } /* Used to hold a copy of the compound literal in a template. */ tree orig_cl = NULL_TREE; diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class42.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class42.C new file mode 100644 index 00000000000..a688bee6f3d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class42.C @@ -0,0 +1,8 @@ +// PR c++/99586 +// { dg-do compile { target c++20 } } + +template <class T> +struct B { constexpr B(T) { } }; + +template <auto> struct A{}; +template <auto V> auto a = A<B{V}>{}; -- 2.31.1.133.g84d06cdc06