https://gcc.gnu.org/g:5f75fc37b131c701a5b5c627239fa4e4dfabe230

commit r16-7358-g5f75fc37b131c701a5b5c627239fa4e4dfabe230
Author: Jakub Jelinek <[email protected]>
Date:   Fri Feb 6 11:27:52 2026 +0100

    tree: Fix up build_function_type for (...) fntypes [PR123977]
    
    The following testcase ICEs in -std=c++26 mode since my r16-4338 C++26
    va_start changes.
    The problem is that if we have anything non-canonical in a function
    type with (...) in C++26 (or C23/C2Y) mode, in this case the R typedef
    on return type rather than void, then we try to build TYPE_CANONICAL
    for that, but weren't passing in the no_named_args_stdarg_p, so
    a type with TYPE_NO_NAMED_ARGS_STDARG_P flag set got TYPE_CANONICAL
    with TYPE_NO_NAMED_ARGS_STDARG_P flag cleared and comptypes then
    didn't like that as those aren't really compatible types
    (...) vs. the C89-ish () which even C++ uses for some type-generic
    etc. builtins.
    
    2026-02-05  Jakub Jelinek  <[email protected]>
    
            PR c++/123977
            * tree.cc (build_function_type): Pass no_named_args_stdarg_p
            as last argument to recursive call.
    
            * g++.dg/cpp26/stdarg10.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/cpp26/stdarg10.C | 19 +++++++++++++++++++
 gcc/tree.cc                           |  3 ++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/cpp26/stdarg10.C 
b/gcc/testsuite/g++.dg/cpp26/stdarg10.C
new file mode 100644
index 000000000000..a8e1ddaee1e8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/stdarg10.C
@@ -0,0 +1,19 @@
+// PR c++/123977
+// { dg-do compile }
+
+typedef void R;
+struct A {
+  R foo (...) const volatile;
+  void foo ();
+};
+
+template <class T>
+struct B {
+  static void bar () { (T (A::*)) &A::foo; }
+};
+
+void
+baz ()
+{
+  B <R (...) const volatile>::bar;
+}
diff --git a/gcc/tree.cc b/gcc/tree.cc
index cf47f0ee64da..22effa6bcd19 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -7780,7 +7780,8 @@ build_function_type (tree value_type, tree arg_types,
     gcc_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
   else if (any_noncanonical_p)
     TYPE_CANONICAL (t) = build_function_type (TYPE_CANONICAL (value_type),
-                                             canon_argtypes);
+                                             canon_argtypes,
+                                             no_named_args_stdarg_p);
 
   if (!COMPLETE_TYPE_P (t))
     layout_type (t);

Reply via email to