https://gcc.gnu.org/g:a1999cbc816ecd382c7af4ca44153379de49dcaf

commit r15-2792-ga1999cbc816ecd382c7af4ca44153379de49dcaf
Author: Simon Martin <si...@nasilyan.com>
Date:   Wed Aug 7 12:45:12 2024 +0200

    c++: Fix ICE on valid involving variadic constructor [PR111592]
    
    We currently ICE upon the following valid code, due to the fix made through
    commit 9efe5fbde1e8
    
    === 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.

Diff:
---
 gcc/cp/call.cc                           |  1 +
 gcc/testsuite/g++.dg/cpp0x/variadic186.C | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index a75e2e5e3afd..67d38e2a78a7 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -10365,6 +10365,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 000000000000..4a25a1a96bf8
--- /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); }

Reply via email to