On 4/1/21 10:30 AM, Patrick Palka wrote:
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?
OK for trunk.
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}>{};