Hi!

The following testcase ICEs since the conditional
eltinit = buil2 (INIT_EXPR, ...) has been added to cxx_eval_vec_init_1.

If there are errors, eltinit will be error_mark_node and we can ICE during
constant evaluation of that.

Fixed by skipping it for error operands.
When touching it, I've tried to improve formatting of the
call before this too.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2026-01-03  Jakub Jelinek  <[email protected]>

        PR c++/123331
        * constexpr.cc (cxx_eval_vec_init_1): Don't build INIT_EXPR if
        eltinit is erroneous.  Formatting fix.

        * g++.dg/other/pr123331.C: New test.

--- gcc/cp/constexpr.cc.jj      2026-01-02 09:56:10.099337665 +0100
+++ gcc/cp/constexpr.cc 2026-01-02 11:51:24.742507592 +0100
@@ -6724,10 +6724,13 @@ cxx_eval_vec_init_1 (const constexpr_ctx
          eltinit = cp_build_array_ref (input_location, init, idx, complain);
          if (!lvalue_p (init))
            eltinit = move (eltinit);
-         eltinit = (perform_implicit_conversion_flags
-                    (elttype, eltinit, complain,
-                     LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING));
-         if (CLASS_TYPE_P (elttype) && new_ctx.object)
+         eltinit
+           = perform_implicit_conversion_flags (elttype, eltinit, complain,
+                                                LOOKUP_IMPLICIT
+                                                | LOOKUP_NO_NARROWING);
+         if (CLASS_TYPE_P (elttype)
+             && new_ctx.object
+             && !error_operand_p (eltinit))
            /* Clarify what object is being initialized (118285).  */
            eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
          eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
--- gcc/testsuite/g++.dg/other/pr123331.C.jj    2026-01-02 12:04:07.060586513 
+0100
+++ gcc/testsuite/g++.dg/other/pr123331.C       2026-01-02 12:01:23.822349558 
+0100
@@ -0,0 +1,20 @@
+// PR c++/123331
+// { dg-do compile }
+// { dg-additional-options "-O2" }
+
+struct A { virtual void foo () = 0; };
+struct B { A a[1]; };  // { dg-error "cannot declare field 'B::a' to be of 
abstract type 'A'" }
+// { dg-error "cannot construct an object of abstract type 'A'" "" { target 
*-*-* } .-1 }
+
+template <typename T>
+void
+bar (T x)
+{
+} 
+
+int
+main ()
+{
+  B b;
+  bar (b); 
+}

        Jakub

Reply via email to