[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-28 Thread carlosgalvezp at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #19 from Carlos Galvez  ---
I can confirm that recent versions of trunk fixed the problem described in this
thread, thank you so much!

> Sounds like another regression?

I need to run more tests to confirm. It is a very huge file, it could simply be
that we were close to the limits of the machine and now GCC does slightly more
work and goes over the threshold. Anyhow, off-topic for this issue, I'll open a
separate one if needed!

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-28 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #18 from Patrick Palka  ---
(In reply to Carlos Galvez from comment #17)
> (FYI I'm trying to test this but now I get out-of-memory errors when trying
> to compile a single .cpp file, will test with a newer patch in case it got
> fixed)
Sounds like another regression? Please open a new PR if anything :)

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-22 Thread carlosgalvezp at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #17 from Carlos Galvez  ---
(FYI I'm trying to test this but now I get out-of-memory errors when trying to
compile a single .cpp file, will test with a newer patch in case it got fixed)

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-22 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #16 from GCC Commits  ---
The trunk branch has been updated by Marek Polacek :

https://gcc.gnu.org/g:cb828691fe692f9df002a2e3757a1aec68857e85

commit r15-7127-gcb828691fe692f9df002a2e3757a1aec68857e85
Author: Marek Polacek 
Date:   Tue Jan 21 14:48:46 2025 -0500

c++: further tweak to cxx_eval_outermost_constant_expr [PR118396]

This patch adds an error in a !allow_non_constant case when the
initializer/object types don't match.

PR c++/118396

gcc/cp/ChangeLog:

* constexpr.cc (cxx_eval_outermost_constant_expr): Add an error
call
when !allow_non_constant.

Reviewed-by: Jason Merrill 

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-21 Thread carlosgalvezp at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #15 from Carlos Galvez  ---
Thank you for the quick fix! I'll test it right away :)

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-21 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

Marek Polacek  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|ASSIGNED|RESOLVED

--- Comment #14 from Marek Polacek  ---
Should be fixed.

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-21 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #13 from GCC Commits  ---
The trunk branch has been updated by Marek Polacek :

https://gcc.gnu.org/g:f3f02493dfa8858c3fb2bc0da0d6d7320921408a

commit r15-7103-gf3f02493dfa8858c3fb2bc0da0d6d7320921408a
Author: Marek Polacek 
Date:   Thu Jan 16 11:22:59 2025 -0500

c++: fix wrong-code with constexpr prvalue opt [PR118396]

The recent r15-6369 unfortunately caused a bad wrong-code issue.
Here we have

  TARGET_EXPR 

and call cp_fold_r -> maybe_constant_init with object=D.2996.  In
cxx_eval_outermost_constant_expr we now take the type of the object
if present.  An object can't have type 'void' and so we continue to
evaluate the initializer.  That evaluates into a VOID_CST, meaning
we disregard the whole initializer, and terrible things ensue.

For non-simple TARGET_EXPRs, we should return ctx.ctor rather than
the result of cxx_eval_constant_expression.

PR c++/118396
PR c++/118523

gcc/cp/ChangeLog:

* constexpr.cc (cxx_eval_outermost_constant_expr): For non-simple
TARGET_EXPRs, return ctx.ctor rather than the result of
cxx_eval_constant_expression.  If TYPE and the type of R don't
match, return the original expression.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/constexpr-prvalue4.C: New test.
* g++.dg/cpp1y/constexpr-prvalue3.C: New test.

Reviewed-by: Jason Merrill 

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-16 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #12 from Marek Polacek  ---
So I think I'll test this:

--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -8871,9 +8871,17 @@ cxx_eval_outermost_constant_expr (tree t, bool
allow_non_constant,
   /* Turn off -frounding-math for manifestly constant evaluation.  */
   warning_sentinel rm (flag_rounding_math,
   ctx.manifestly_const_eval == mce_true);
-  tree type = (object
-  ? cv_unqualified (TREE_TYPE (object))
-  : initialized_type (t));
+  tree type;
+  if (object)
+{
+  type = cv_unqualified (TREE_TYPE (object));
+  /* If there is an object to initialize, make sure we don't throw
+away the initializer.  */
+  gcc_assert (!VOID_TYPE_P (initialized_type (t)) || constexpr_dtor);
+}
+  else
+type = initialized_type (t);
+
   tree r = t;
   bool is_consteval = false;
   if (VOID_TYPE_P (type))
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index c7074b00cef..283c0fa3e26 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1475,7 +1475,9 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_)
  cp_walk_tree (&init, cp_fold_r, data, NULL);
  cp_walk_tree (&TARGET_EXPR_CLEANUP (stmt), cp_fold_r, data, NULL);
  *walk_subtrees = 0;
- if (!flag_no_inline)
+ /* Only attempt to evaluate the initializer if we're inlining and
+the TARGET_EXPR is simple.  */
+ if (!flag_no_inline && !VOID_TYPE_P (TREE_TYPE (init)))
{
  tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt));
  if (folded != init && TREE_CONSTANT (folded))

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-16 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

Marek Polacek  changed:

   What|Removed |Added

 CC||jason at gcc dot gnu.org

--- Comment #11 from Marek Polacek  ---
One idea would be to only fold simple TARGET_EXPR's initializer:

--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1475,7 +1475,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_)
  cp_walk_tree (&init, cp_fold_r, data, NULL);
  cp_walk_tree (&TARGET_EXPR_CLEANUP (stmt), cp_fold_r, data, NULL);
  *walk_subtrees = 0;
- if (!flag_no_inline)
+ if (!flag_no_inline && !VOID_TYPE_P (TREE_TYPE (init)))
{
  tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt));
  if (folded != init && TREE_CONSTANT (folded))

but maybe we also need an assert in cxx_eval_outermost_constant_expr checking
that if there's an object, we don't fold away all the initializing bits?

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-15 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #10 from Marek Polacek  ---
We have:

  TARGET_EXPR 

so object=D.2996 whose type is Data, so we do not go down the VOID_TYPE_P path
in cxx_eval_outermost_constant_expr, and evaluate the whole init to VOID_CST. 
Obviously, that should not happen.

I'm not sure why we create TARGET_EXPRs that look like this.

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-15 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #9 from Marek Polacek  ---
This difference seems to be the problem:

-vector::vector (&items_, (const struct Data &) &TARGET_EXPR >>>) >;
+vector::vector (&items_, (const struct Data &) &TARGET_EXPR ) >;

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-15 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #8 from Andrew Pinski  ---
Created attachment 60165
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=60165&action=edit
Fixed up removing hard coded size_t, use __SIZE_TYPE__ instead and removed
__assert_failure

Just some small changes to the testcase in comment #7 fixing up a few x86_64
linux-isms.

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-15 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #7 from Marek Polacek  ---
// PR c++/118396

extern "C"  void __assert_fail(const char *, const char *);
void *operator new(unsigned long, void *__p) { return __p; }

struct Foo {
  virtual ~Foo() = default;
};
struct Data {
  int status;
  Foo data{};
};

Data *P, *Q;

struct vector {
  vector (const Data &__value) {
P = static_cast(__builtin_operator_new(0));
new (P) Data (__value);
Q = P + 1;
  }
  Data *begin() { return P; }
  Data *end() { return Q; }
};

int
main ()
{
  vector items_(Data{});
  for (auto item : items_)
item.status == 0 ? void() : __assert_fail("oy", "118396.C");
}

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-15 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #6 from Marek Polacek  ---
Somewhat reduced but it's still ugly:

```
extern "C" void __assert_fail(const char *, const char *);
struct Data;
void *operator new(unsigned long, void *__p) { return __p; }
template  struct __new_allocator {
  Data *allocate(long __n) {
return static_cast(__builtin_operator_new(__n));
  }
  template 
  void construct(_Up *__p, _Args... __args) {
new (__p) _Up(__args...);
  }
};
template  struct allocator_traits;
template  using rebind_alloc = __new_allocator<_Up>;
template  struct allocator_traits<__new_allocator<_Tp>> {
  using allocator_type = __new_allocator<_Tp>;
  using pointer = _Tp *;
  static pointer allocate() {
allocator_type __a;
return __a.allocate(0);
  }
  template 
  static void construct(allocator_type __a, _Up __p, _Args... __args) {
__a.construct(__p, __args...);
  }
};
struct __alloc_traits : allocator_traits<__new_allocator> {};
template 
_ForwardIterator __uninitialized_fill_n_a(_ForwardIterator __first, long __n,
  const Data &__x,
  __new_allocator __alloc) {
  for (; __n; --__n, ++__first) {
Data *__trans_tmp_1(__first);
__alloc_traits::construct(__alloc, __trans_tmp_1, __x);
  }
  return __first;
}
typedef __alloc_traits::pointer pointer;
pointer P, _M_impl_1;
struct _Vector_base {
  _Vector_base(long __n) {
P = __alloc_traits::allocate();
  }
};
struct vector : _Vector_base {
  vector(long __n, const Data &__value) : _Vector_base(__n) {
long __trans_tmp_4 = __n;
rebind_alloc __trans_tmp_2;
_M_impl_1 = __uninitialized_fill_n_a(P,
 __trans_tmp_4, __value,
__trans_tmp_2);
  }
  pointer begin() { return P; }
  pointer end() { return _M_impl_1; }
};


struct Foo {
  virtual ~Foo() = default;
};
struct Data {
  int status;
  Foo data{};
};
int kValue;
struct Vector : vector {
  Vector(long size) : vector(size, Data{}) {}
};

int main() {
  Vector items_(10);
  for (auto item : items_)
item.status == kValue ? void() : __assert_fail("", __builtin_FILE());
}
```

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-15 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #5 from Sam James  ---
*** Bug 118475 has been marked as a duplicate of this bug. ***

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-10 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #4 from Sam James  ---
Testing trunk regularly is more than enough ;)

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-10 Thread carlosgalvezp at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

--- Comment #3 from Carlos Galvez  ---
Thanks for the quick confirmation! Let me know if I can be of help.

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present since r15-6369-gfa99002538bc91

2025-01-10 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

Marek Polacek  changed:

   What|Removed |Added

   Priority|P3  |P1
   Assignee|unassigned at gcc dot gnu.org  |mpolacek at gcc dot 
gnu.org
 Status|NEW |ASSIGNED

--- Comment #2 from Marek Polacek  ---
Oy.  Mine then.

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present

2025-01-10 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

Patrick Palka  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2025-01-10
 CC||mpolacek at gcc dot gnu.org,
   ||ppalka at gcc dot gnu.org
 Ever confirmed|0   |1

--- Comment #1 from Patrick Palka  ---
Confirmed, seems to have started with r15-6369-gfa99002538bc91 "c++: ICE in
TARGET_EXPR evaluation in cp_fold_r [PR117980]".

[Bug c++/118396] [15 regression] -O1+ leads to reading uninitialized data when virtual destructor is present

2025-01-10 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118396

Sam James  changed:

   What|Removed |Added

   Target Milestone|--- |15.0
Summary|Regression: -O1+ leads to   |[15 regression] -O1+ leads
   |reading uninitialized data  |to reading uninitialized
   |when virtual destructor is  |data when virtual
   |present |destructor is present
   Keywords||wrong-code