On 1/18/25 4:06 AM, Jakub Jelinek wrote:
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. */

Maybe we could factor out a function called something like append_ctor_to_tree_vector from the common code between this and make_tree_vector_from_ctor?

But this is OK as is if you don't want to pursue that.

    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