c++: Don't form a templated TARGET_EXPR in finish_compound_literal
The atom_cache in normalize_atom relies on the assumption that two equivalent (templated) trees (in the sense of cp_tree_equal) must use the same template parameters (according to find_template_parameters). This assumption unfortunately doesn't always hold for TARGET_EXPRs, because cp_tree_equal ignores an artificial target of a TARGET_EXPR, but find_template_parameters walks this target (and its DECL_CONTEXT). Hence two TARGET_EXPRs built by force_target_expr with the same initializer and under different settings of current_function_decl will compare equal according to cp_tree_equal, but find_template_parameters may return a different set of template parameters for them. This breaks the below testcase because during normalization we build two such TARGET_EXPRs (one under current_function_decl=f and another under =g), and then share the same ATOMIC_CONSTR for the two corresponding atoms, leading to a crash during satisfaction of g's associated constraints. This patch works around this issue by removing the source of these templated TARGET_EXPRs. The relevant call to get_target_expr_sfinae was added in r9-6043, and it seems it's no longer necessary (according to https://gcc.gnu.org/pipermail/gcc-patches/2019-February/517323.html, the call was added in order to avoid regressing on initlist109.C at the time). gcc/cp/ChangeLog: * semantics.c (finish_compound_literal): Don't wrap the original compound literal in a TARGET_EXPR when inside a template. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-decltype3.C: New test.
This commit is contained in:
parent
93fc477468
commit
de6f64f955
2 changed files with 16 additions and 6 deletions
|
@ -3006,12 +3006,7 @@ finish_compound_literal (tree type, tree compound_literal,
|
|||
|
||||
/* If we're in a template, return the original compound literal. */
|
||||
if (orig_cl)
|
||||
{
|
||||
if (!VECTOR_TYPE_P (type))
|
||||
return get_target_expr_sfinae (orig_cl, complain);
|
||||
else
|
||||
return orig_cl;
|
||||
}
|
||||
return orig_cl;
|
||||
|
||||
if (TREE_CODE (compound_literal) == CONSTRUCTOR)
|
||||
{
|
||||
|
|
15
gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C
Normal file
15
gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C
Normal file
|
@ -0,0 +1,15 @@
|
|||
// { dg-do compile { target c++20 } }
|
||||
|
||||
template <class T> concept C = requires(T t) { t; };
|
||||
|
||||
template <class T> using A = decltype((T{}, int{}));
|
||||
|
||||
template <class T> concept D = C<A<T>>;
|
||||
|
||||
template <class T, class U> void f() requires D<T>;
|
||||
template <class T> void g() requires D<T>;
|
||||
|
||||
void h() {
|
||||
f<int, int>();
|
||||
g<int>();
|
||||
}
|
Loading…
Add table
Reference in a new issue