[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

2025-03-12 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
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

2025-03-12 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
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

2025-03-12 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
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

2025-03-10 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
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

2025-03-07 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
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

2024-12-09 Thread jakub at gcc dot gnu.org via Gcc-bugs
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

2024-12-09 Thread jakub at gcc dot gnu.org via Gcc-bugs
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

2024-12-09 Thread jakub at gcc dot gnu.org via Gcc-bugs
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

2024-11-26 Thread jakub at gcc dot gnu.org via Gcc-bugs
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

2024-11-11 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
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