On Fri, Jan 17, 2025 at 09:11:15PM +0100, Jakub Jelinek wrote:
> This is the second bug discovered today with the
> https://gcc.gnu.org/pipermail/gcc-patches/2025-January/673945.html
> hack but then turned into proper testcases where embed-2[23].C FAILed
> since introduction of optimized #embed support and the others when
> optimizing large C++ initializers using RAW_DATA_CST.
> 
> The add_list_candidates problem is the same as with
> make_tree_vector_from_ctor, unfortunately it can't call that
> function because it can have those additional artificial arguments
> that need to be pushed earlier.
> When working on the patch, I've also noticed an error where we didn't
> know how to dump RAW_DATA_CST, so I've added support for that too.

Here is updated patch similarly to the PR118528 changes.
Tested so far with
GXX_TESTSUITE_STDS=98,11,14,17,20,23,26 make check-g++ 
RUNTESTFLAGS="dg.exp='embed* class-deduction-aggr*.C explicit*.C pr11853[24]*'"

2025-01-18  Jakub Jelinek  <ja...@redhat.com>

        PR c++/118532
        * call.cc (add_list_candidates): Handle RAW_DATA_CST among init_list
        elts.
        * error.cc (dump_expr_init_vec): Handle RAW_DATA_CST among v elts.

        * g++.dg/cpp/embed-22.C: New test.
        * g++.dg/cpp/embed-23.C: New test.
        * g++.dg/cpp0x/pr118532.C: New test.
        * g++.dg/cpp2a/explicit20.C: New test.

--- gcc/cp/call.cc.jj   2025-01-15 18:24:36.135503866 +0100
+++ gcc/cp/call.cc      2025-01-17 14:42:38.201643385 +0100
@@ -4258,11 +4258,30 @@ add_list_candidates (tree fns, tree firs
 
   /* Expand the CONSTRUCTOR into a new argument vec.  */
   vec<tree, va_gc> *new_args;
-  vec_alloc (new_args, nart + CONSTRUCTOR_NELTS (init_list));
+  unsigned nelts = nart + CONSTRUCTOR_NELTS (init_list);
+  vec_alloc (new_args, nelts);
   for (unsigned i = 0; i < nart; ++i)
     new_args->quick_push ((*args)[i]);
   for (unsigned i = 0; i < CONSTRUCTOR_NELTS (init_list); ++i)
-    new_args->quick_push (CONSTRUCTOR_ELT (init_list, i)->value);
+    if (TREE_CODE (CONSTRUCTOR_ELT (init_list, i)->value) == RAW_DATA_CST)
+      {
+       tree raw_data = CONSTRUCTOR_ELT (init_list, i)->value;
+       nelts += RAW_DATA_LENGTH (raw_data) - 1;
+       vec_safe_reserve (new_args, nelts - new_args->length ());
+       if (TYPE_PRECISION (TREE_TYPE (raw_data)) > CHAR_BIT
+           || TYPE_UNSIGNED (TREE_TYPE (raw_data)))
+         for (unsigned j = 0; j < (unsigned) RAW_DATA_LENGTH (raw_data); ++j)
+           new_args->quick_push (build_int_cst (TREE_TYPE (raw_data),
+                                                RAW_DATA_UCHAR_ELT (raw_data,
+                                                                    j)));
+       else
+         for (unsigned j = 0; j < (unsigned) RAW_DATA_LENGTH (raw_data); ++j)
+           new_args->quick_push (build_int_cst (TREE_TYPE (raw_data),
+                                                RAW_DATA_SCHAR_ELT (raw_data,
+                                                                    j)));
+      }
+    else
+      new_args->quick_push (CONSTRUCTOR_ELT (init_list, i)->value);
 
   /* We aren't looking for list-ctors anymore.  */
   flags &= ~LOOKUP_LIST_ONLY;
--- gcc/cp/error.cc.jj  2025-01-10 10:26:37.390685341 +0100
+++ gcc/cp/error.cc     2025-01-17 16:20:44.089508010 +0100
@@ -2289,7 +2289,26 @@ dump_expr_init_vec (cxx_pretty_printer *
 
   FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
     {
-      dump_expr (pp, value, flags | TFF_EXPR_IN_PARENS);
+      if (TREE_CODE (value) == RAW_DATA_CST)
+       for (unsigned i = 0; i < (unsigned) RAW_DATA_LENGTH (value); ++i)
+         {
+           if (TYPE_UNSIGNED (TREE_TYPE (value))
+               || TYPE_PRECISION (TREE_TYPE (value)) > CHAR_BIT)
+             pp_decimal_int (pp, RAW_DATA_UCHAR_ELT (value, i));
+           else
+             pp_decimal_int (pp, RAW_DATA_SCHAR_ELT (value, i));
+           if (i == RAW_DATA_LENGTH (value) - 1U)
+             break;
+           else if (i == 9 && RAW_DATA_LENGTH (value) > 20)
+             {
+               pp_string (pp, ", ..., ");
+               i = RAW_DATA_LENGTH (value) - 11;
+             }
+           else
+             pp_separate_with_comma (pp);
+         }
+      else
+       dump_expr (pp, value, flags | TFF_EXPR_IN_PARENS);
       if (idx != v->length () - 1)
        pp_separate_with_comma (pp);
     }
--- gcc/testsuite/g++.dg/cpp/embed-22.C.jj      2025-01-17 17:06:54.731279618 
+0100
+++ gcc/testsuite/g++.dg/cpp/embed-22.C 2025-01-17 16:56:02.499282953 +0100
@@ -0,0 +1,24 @@
+// PR c++/118532
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct S {
+  S (int, int, int);
+#define I8 int, int, int, int, int, int, int, int
+#define I64 I8, I8, I8, I8, I8, I8, I8, I8
+  S (I64, I64, I64, I64, I8);
+};
+
+void
+foo (S &)
+{
+}
+
+int
+main ()
+{
+  S s = {
+#embed __FILE__ limit (264)
+  };
+  foo (s);
+}
--- gcc/testsuite/g++.dg/cpp/embed-23.C.jj      2025-01-17 17:02:17.333105186 
+0100
+++ gcc/testsuite/g++.dg/cpp/embed-23.C 2025-01-17 17:02:32.650893591 +0100
@@ -0,0 +1,21 @@
+// PR c++/118532
+// { dg-do compile { target c++20 } }
+// { dg-options "" }
+
+constexpr int fn0 () { return 0; }
+constexpr int fn1 () { return 1; }
+
+struct S {
+  explicit(fn0()) S(int, int, int);
+#define I8 int, int, int, int, int, int, int, int
+#define I64 I8, I8, I8, I8, I8, I8, I8, I8
+  explicit(fn1()) S(I64, I64, I64, I64, I8);
+};
+
+int
+main ()
+{
+  S s4 = {
+#embed __FILE__ limit (264)
+  }; // { dg-error "converting" }
+}
--- gcc/testsuite/g++.dg/cpp0x/pr118532.C.jj    2025-01-17 16:56:25.849960395 
+0100
+++ gcc/testsuite/g++.dg/cpp0x/pr118532.C       2025-01-17 16:56:42.419731513 
+0100
@@ -0,0 +1,25 @@
+// PR c++/118532
+// { dg-do compile { target c++11 } }
+
+struct S {
+  S (int, int, int);
+#define I8 int, int, int, int, int, int, int, int
+#define I64 I8, I8, I8, I8, I8, I8, I8, I8
+  S (I64, I64, I64, I64, I8);
+};
+
+void
+foo (S &)
+{
+}
+
+int
+main ()
+{
+  S s = {
+#undef I8
+#define I8 1, 2, 3, 4, 5, 6, 7, 8
+    I64, I64, I64, I64, I8
+  };
+  foo (s);
+}
--- gcc/testsuite/g++.dg/cpp2a/explicit20.C.jj  2025-01-17 17:02:56.475564490 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/explicit20.C     2025-01-17 17:03:22.240208592 
+0100
@@ -0,0 +1,23 @@
+// PR c++/118532
+// { dg-do compile { target c++20 } }
+// { dg-options "" }
+
+constexpr int fn0 () { return 0; }
+constexpr int fn1 () { return 1; }
+
+struct S {
+  explicit(fn0()) S(int, int, int);
+#define I8 int, int, int, int, int, int, int, int
+#define I64 I8, I8, I8, I8, I8, I8, I8, I8
+  explicit(fn1()) S(I64, I64, I64, I64, I8);
+};
+
+int
+main ()
+{
+  S s4 = {
+#undef I8
+#define I8 1, 2, 3, 4, 5, 6, 7, 8
+    I64, I64, I64, I64, I8
+  }; // { dg-error "converting" }
+}


        Jakub

Reply via email to