Message ID | 01020190984579a0-d9edaf97-be78-416c-aa9b-203556ebadb9-000000@eu-west-1.amazonses.com |
---|---|
State | New |
Headers | show |
Series | c++: Fix ICE on valid involving variadic constructor [PR111592] | expand |
On 7/9/24 12:13 PM, Simon Martin wrote: > We currently ICE upon the following valid code, due to the fix made through > commit 9efe5fbde1e8 OK. > === cut here === > struct ignore { ignore(...) {} }; > template<class... Args> > void InternalCompilerError(Args... args) > { ignore{ ignore(args) ... }; } > int main() { InternalCompilerError(0, 0); } > === cut here === > > Change 9efe5fbde1e8 avoids infinite recursion in build_over_call by returning > error_mark_node if one invokes ignore::ignore(...) with an argument of type > ignore, because otherwise we end up calling convert_arg_to_ellipsis for that > argument, and recurse into build_over_call with the exact same parameters. > > This patch tightens the condition to only return error_mark_node if there's one > and only one parameter to the call being processed - otherwise we won't > infinitely recurse. > > Successfully tested on x86_64-pc-linux-gnu. > > PR c++/111592 > > gcc/cp/ChangeLog: > > * call.cc (build_over_call): Only error out if there's a single > parameter of type A in a call to A::A(...). > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/variadic186.C: New test. > > --- > gcc/cp/call.cc | 1 + > gcc/testsuite/g++.dg/cpp0x/variadic186.C | 11 +++++++++++ > 2 files changed, 12 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic186.C > > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc > index 83070b2f633..0e4e9a80408 100644 > --- a/gcc/cp/call.cc > +++ b/gcc/cp/call.cc > @@ -10335,6 +10335,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) > a = decay_conversion (a, complain); > } > else if (DECL_CONSTRUCTOR_P (fn) > + && vec_safe_length (args) == 1 > && same_type_ignoring_top_level_qualifiers_p (DECL_CONTEXT (fn), > TREE_TYPE (a))) > { > diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic186.C b/gcc/testsuite/g++.dg/cpp0x/variadic186.C > new file mode 100644 > index 00000000000..4a25a1a96bf > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/variadic186.C > @@ -0,0 +1,11 @@ > +// PR c++/111592 > +// { dg-do compile { target c++11 } } > + > +struct ignore { ignore(...) {} }; > + > +template<class... Args> > +void InternalCompilerError(Args... args) > +{ ignore{ ignore(args) ... }; } > + > +int main() > +{ InternalCompilerError(0, 0); }
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 83070b2f633..0e4e9a80408 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -10335,6 +10335,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) a = decay_conversion (a, complain); } else if (DECL_CONSTRUCTOR_P (fn) + && vec_safe_length (args) == 1 && same_type_ignoring_top_level_qualifiers_p (DECL_CONTEXT (fn), TREE_TYPE (a))) { diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic186.C b/gcc/testsuite/g++.dg/cpp0x/variadic186.C new file mode 100644 index 00000000000..4a25a1a96bf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic186.C @@ -0,0 +1,11 @@ +// PR c++/111592 +// { dg-do compile { target c++11 } } + +struct ignore { ignore(...) {} }; + +template<class... Args> +void InternalCompilerError(Args... args) +{ ignore{ ignore(args) ... }; } + +int main() +{ InternalCompilerError(0, 0); }