On Thu, Nov 12, 2020 at 01:27:23PM -0500, Patrick Palka wrote: > 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 but under different settings of current_function_decl may > compare equal according to cp_tree_equal, but find_template_parameters > returns 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 use 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 assumption violation by removing the source > of these templated TARGET_EXPRs. The relevant call to get_target_expr was > added in r9-6043, but 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). > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk?
Looks OK to me, thanks! > 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. > --- > gcc/cp/semantics.c | 7 +------ > gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C | 15 +++++++++++++++ > 2 files changed, 16 insertions(+), 6 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C > > diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c > index 33d715edaec..172286922e7 100644 > --- a/gcc/cp/semantics.c > +++ b/gcc/cp/semantics.c > @@ -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) > { > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C > b/gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C > new file mode 100644 > index 00000000000..837855ce8ac > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C > @@ -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>(); > +} > -- > 2.29.2.260.ge31aba42fb > Marek