[Bug c++/117512] [14/15 Regression] ICE on x86_64-linux-gnu: in cp_gimplify_expr, at cp/cp-gimplify.cc:911 with aligned on a field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512 Marek Polacek changed: What|Removed |Added Resolution|--- |FIXED Status|ASSIGNED|RESOLVED --- Comment #10 from Marek Polacek --- Fixed.
[Bug c++/117512] [14/15 Regression] ICE on x86_64-linux-gnu: in cp_gimplify_expr, at cp/cp-gimplify.cc:911 with aligned on a field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512 --- Comment #9 from GCC Commits --- The releases/gcc-14 branch has been updated by Marek Polacek : https://gcc.gnu.org/g:a27b24c9f4ee7fc12d077ea111200223e4a95c7d commit r14-11406-ga27b24c9f4ee7fc12d077ea111200223e4a95c7d Author: Marek Polacek Date: Wed Mar 12 14:49:53 2025 -0400 c++: ICE with aligned member and trivial assign op [PR117512] build_over_call has: t = build2 (MODIFY_EXPR, void_type_node, build2 (MEM_REF, array_type, arg0, alias_set), build2 (MEM_REF, array_type, arg, alias_set)); val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to); which creates an expression that can look like: d = MEM [(struct A *)&TARGET_EXPR [(struct A *)(const struct A &) &e], TARGET_EXPR that is, a COMPOUND_EXPR where a TARGET_EXPR is used twice, and its address is taken in the left-hand side operand, so it can't be elided. But set_target_expr_eliding simply recurses on the second operand of a COMPOUND_EXPR and marks the TARGET_EXPR as eliding. This then causes a crash. cp_build_indirect_ref_1 should not be changing the value category. While *&TARGET_EXPR is an lvalue, folding it into TARGET_EXPR would render is a prvalue of class type. PR c++/117512 gcc/cp/ChangeLog: * typeck.cc (cp_build_indirect_ref_1): Only do the *&e -> e folding if the result would be an lvalue. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alignas23.C: New test. * g++.dg/ext/align3.C: New test. * g++.dg/ext/align4.C: New test. * g++.dg/ext/align5.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 3dd7b598065ea0280fc65ce656c575c5142fa4fc)
[Bug c++/117512] [14/15 Regression] ICE on x86_64-linux-gnu: in cp_gimplify_expr, at cp/cp-gimplify.cc:911 with aligned on a field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512 --- Comment #8 from GCC Commits --- The trunk branch has been updated by Marek Polacek : https://gcc.gnu.org/g:3dd7b598065ea0280fc65ce656c575c5142fa4fc commit r15-8011-g3dd7b598065ea0280fc65ce656c575c5142fa4fc Author: Marek Polacek Date: Wed Mar 12 14:49:53 2025 -0400 c++: ICE with aligned member and trivial assign op [PR117512] build_over_call has: t = build2 (MODIFY_EXPR, void_type_node, build2 (MEM_REF, array_type, arg0, alias_set), build2 (MEM_REF, array_type, arg, alias_set)); val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to); which creates an expression that can look like: d = MEM [(struct A *)&TARGET_EXPR [(struct A *)(const struct A &) &e], TARGET_EXPR that is, a COMPOUND_EXPR where a TARGET_EXPR is used twice, and its address is taken in the left-hand side operand, so it can't be elided. But set_target_expr_eliding simply recurses on the second operand of a COMPOUND_EXPR and marks the TARGET_EXPR as eliding. This then causes a crash. cp_build_indirect_ref_1 should not be changing the value category. While *&TARGET_EXPR is an lvalue, folding it into TARGET_EXPR would render is a prvalue of class type. PR c++/117512 gcc/cp/ChangeLog: * typeck.cc (cp_build_indirect_ref_1): Only do the *&e -> e folding if the result would be an lvalue. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alignas23.C: New test. * g++.dg/ext/align3.C: New test. * g++.dg/ext/align4.C: New test. * g++.dg/ext/align5.C: New test. Reviewed-by: Jason Merrill
[Bug c++/117512] [14/15 Regression] ICE on x86_64-linux-gnu: in cp_gimplify_expr, at cp/cp-gimplify.cc:911 with aligned on a field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512 Marek Polacek changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |mpolacek at gcc dot gnu.org Status|NEW |ASSIGNED
[Bug c++/117512] [14/15 Regression] ICE on x86_64-linux-gnu: in cp_gimplify_expr, at cp/cp-gimplify.cc:911 with aligned on a field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512 --- Comment #7 from Marek Polacek --- I think the problem is that we create something like d = MEM [(struct A *)&TARGET_EXPR [(struct A *)(const struct A &) &e], TARGET_EXPR in build_over_call: t = build2 (MODIFY_EXPR, void_type_node, build2 (MEM_REF, array_type, arg0, alias_set), build2 (MEM_REF, array_type, arg, alias_set)); val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to); so the same TARGET_EXPR is used in both operands of the COMPOUND_EXPR, and in op0 we're taking its address so it can't be elided. But set_target_expr_eliding simply recurses on the second operand of a COMPOUND_EXPR and marks the TARGET_EXPR as eliding. But it cannot be elided so we crash later. cp_genericize_r could see if a TARGET_EXPR is wrapped in & and reset TARGET_EXPR_ELIDING_P if so. That would certainly fix it but whether that's the right fix, I'm not sure.
[Bug c++/117512] [14/15 Regression] ICE on x86_64-linux-gnu: in cp_gimplify_expr, at cp/cp-gimplify.cc:911 with aligned on a field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512
--- Comment #6 from Jakub Jelinek ---
And the change is in between
TARGET_EXPR
from cp_build_fold_indirect_ref and
*&TARGET_EXPR
from what we used to get before.
That actually changed behavior even on #c4 variant with 1 * instead of 2 *, but
with 1 * the original dump difference is:
@@ -12,15 +12,15 @@
{
struct A d;
< = *(const struct A &) &e, (const struct A &) SAVE_EXPR
<&TARGET_EXPR >>> = *(const struct A &) &e, (const struct A &) &TARGET_EXPR
)) >;
+ 0 )) >;
try
{
and it doesn't ICE, while with the extra alignment there is a MEM_REF involved:
@@ -12,15 +12,15 @@
{
struct A d;
< [(struct A *)SAVE_EXPR
<&TARGET_EXPR [(struct A *)&TARGET_EXPR ] = MEM [(struct A *)(const struct A &)
&e], TARGET_EXPR >>>] = MEM [(struct A *)(const struct A &)
&e], TARGET_EXPR >) >;
+ 0 ) >;
try
{
and it does ICE.
[Bug c++/117512] [14/15 Regression] ICE on x86_64-linux-gnu: in cp_gimplify_expr, at cp/cp-gimplify.cc:911 with aligned on a field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512
Jakub Jelinek changed:
What|Removed |Added
CC||jason at gcc dot gnu.org
--- Comment #5 from Jakub Jelinek ---
In particular, it regressed because of the
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -10330,10 +10330,7 @@ build_over_call (struct z_candidate *cand, int flags,
tsubst_flags_t complain)
&& DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR)
&& trivial_fn_p (fn))
{
- /* Don't use cp_build_fold_indirect_ref, op= returns an lvalue even if
-the object argument isn't one. */
- tree to = cp_build_indirect_ref (input_location, argarray[0],
- RO_ARROW, complain);
+ tree to = cp_build_fold_indirect_ref (argarray[0]);
tree type = TREE_TYPE (to);
tree as_base = CLASSTYPE_AS_BASE (type);
tree arg = argarray[1];
hunk in that commit.
[Bug c++/117512] [14/15 Regression] ICE on x86_64-linux-gnu: in cp_gimplify_expr, at cp/cp-gimplify.cc:911 with aligned on a field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512
--- Comment #4 from Jakub Jelinek ---
And the non-static data member doesn't have to be aligned itself,
struct __attribute__((aligned (2 * sizeof (int A {
int b;
~A ();
};
A foo (int);
void
bar ()
{
A e = { 0 };
A d = foo (0) = e;
}
ICEs too.
[Bug c++/117512] [14/15 Regression] ICE on x86_64-linux-gnu: in cp_gimplify_expr, at cp/cp-gimplify.cc:911 with aligned on a field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512
Jakub Jelinek changed:
What|Removed |Added
CC||jakub at gcc dot gnu.org
--- Comment #3 from Jakub Jelinek ---
Doesn't have to be at global scope and doesn't need to assign uninitialized
var.
struct A {
__attribute__((aligned)) int b;
~A ();
};
A foo (int);
void
bar ()
{
A e = { 0 };
A d = foo (0) = e;
}
ICEs too. Just foo (0) = e; or A d; d = foo (0) = e; doesn't ICE though.
[Bug c++/117512] [14/15 Regression] ICE on x86_64-linux-gnu: in cp_gimplify_expr, at cp/cp-gimplify.cc:911 with aligned on a field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512 Marek Polacek changed: What|Removed |Added Summary|ICE on x86_64-linux-gnu: in |[14/15 Regression] ICE on |cp_gimplify_expr, at|x86_64-linux-gnu: in |cp/cp-gimplify.cc:911 with |cp_gimplify_expr, at |aligned on a field |cp/cp-gimplify.cc:911 with ||aligned on a field Priority|P3 |P2 Target Milestone|--- |14.3
