[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-10-12 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

Andrew Pinski  changed:

   What|Removed |Added

 CC||iamsupermouse at mail dot ru

--- Comment #15 from Andrew Pinski  ---
*** Bug 111771 has been marked as a duplicate of this bug. ***

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-21 Thread m.cencora at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

--- Comment #14 from m.cencora at gmail dot com ---
Yeah, in CWG issue comments it is much more clear - but I cannot find such a
wording in C++ latest draft.

English is not my native language so this one is on me.

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-21 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

--- Comment #13 from Jonathan Wakely  ---
And that's clearly the committee's intent:
https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#302

"Zero the object, then call the default generated constructor" ... "Zero first,
and generate the object code for the default constructor when it's needed for
value-initialization cases"

https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#543

"Change 9.4 [dcl.init] to specify that non-union class objects with no
user-declared constructor are value-initialized by first zero-initializing the
object and then calling the (implicitly-defined) default constructor,"

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-21 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

--- Comment #12 from Jonathan Wakely  ---
I don't see any ambiguity:

"otherwise, the object is zero-initialized and the semantic constraints for
default-initialization are checked, **and** if T has a non-trivial default
constructor, the object is default-initialized;"

It doesn't say zero-init OR default-init, it very clearly says zero-init AND
default-init.

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-21 Thread m.cencora at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

--- Comment #11 from m.cencora at gmail dot com ---
Nvm, I understood this rule differently. You are saying that initialization is
two step:
 - first zero-initialized,
 - then default-initialized.

For me the way this rule is written is ambiguous.

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-21 Thread m.cencora at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

m.cencora at gmail dot com changed:

   What|Removed |Added

 CC||m.cencora at gmail dot com

--- Comment #10 from m.cencora at gmail dot com ---
Does it really apply?

Base constructor is user-provided hence non-trivial, hence Derived defaulted
default constructor is non-trivial as well.
Which means we end up in this clause:
"and if T has a non-trivial default constructor, the object is
default-initialized"

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-21 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

Jonathan Wakely  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
 Ever confirmed|0   |1
   Last reconfirmed||2023-04-21

--- Comment #9 from Jonathan Wakely  ---
Confirmed.

using size_t = decltype(sizeof(0));
extern "C" void* memset(void*, int, size_t);
extern "C" int printf(const char*, ...);
void* operator new(size_t, void* p) { return p; }

struct Base {
Base() {} // user-provided constructor
int x;
};

struct Derived : public Base {
Derived() = default; // default constructor satisfying (2) of
// https://en.cppreference.com/w/cpp/language/value_initialization
  private:
int y;
};

int main () {
char b_mem[sizeof(Derived)];
memset(b_mem, 0x55, sizeof(Derived));
printf("b_mem[0]: %d\n", int(b_mem[0]));
Derived* b = new(b_mem) Derived{};
printf("b->x (should be 0): %d\n", b->x);
b->~Derived();
}

With any optimization level except -O0 this prints:

b_mem[0]: 85
b->x (should be 0): 1431655765

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-20 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

--- Comment #8 from Andrew Pinski  ---
(In reply to Pablo Anigstein from comment #7)
> Here is an updated example: https://godbolt.org/z/YePjhxKE4.

I don't see an updated example, all I see is an URL ...

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-20 Thread panigstein at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

--- Comment #7 from Pablo Anigstein  ---
(In reply to Jonathan Wakely from comment #5)
> (In reply to Jonathan Wakely from comment #3)
> > (In reply to Pablo Anigstein from comment #2)
> > > (In reply to Andrew Pinski from comment #1)
> > > > Hmm,
> > > >  I noticed that since GCC 7 with -std=c++17, the b.x is not initialized 
> > > > at
> > > > all. So the question I have is there a difference between C++ standards 
> > > > here?
> > 
> > Derived is an aggregate in C++17, so b{} does aggregate init, not value 
> > init.
> 
> And that means its Base subobject is copy-initialized from {} which means we
> get a value-initialized object, so it's correct that b.x is not initialized
> in C++17 (which is what is shown in your godbolt link, because you didn't
> specify any -std option to override the -std=gnu++17 default).
> 
> With -std=c++14 it looks like b.x is always set to zero, if I'm reading the
> assembly output correctly (but I'm probably not).

Here is an updated example: https://godbolt.org/z/YePjhxKE4. Note that now
Derived is not an aggregate for any standard version due to the private member.
Still zero-initialization does not happen for the Base sub-object for the case
where Base has a user-provided default constructor when compiling with -O1 and
above.

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-20 Thread panigstein at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

--- Comment #6 from Pablo Anigstein  ---
(In reply to Jonathan Wakely from comment #3)
> (In reply to Pablo Anigstein from comment #2)
> > (In reply to Andrew Pinski from comment #1)
> > > Hmm,
> > >  I noticed that since GCC 7 with -std=c++17, the b.x is not initialized at
> > > all. So the question I have is there a difference between C++ standards 
> > > here?
> 
> Derived is an aggregate in C++17, so b{} does aggregate init, not value init.
> 
> > > Note the issue is we call Base's constructor after doing the zero
> > > initialization and the Base's constructor has a clobber in it which I 
> > > think
> > > is correct.
> 
> Maybe we should only clobber in the complete object constructor _ZN4BaseC1Ev
> and not in _ZN4BaseC2Ev.
> 
> > > This is all front-end generation and not exactly related to the
> > > optimizations directly.
> > 
> > There is no difference between C++ standards in this respect.
> 
> Before C++11 there was no zero-init at all. Since C++11 the spec keeps
> changing, but the effects of zero-init are substantially the same. But
> Derived is an aggregate since C++17.
Thank you for the correction. I still think there is non-conformance for all
standards including C++17, I will post a modified example in a comment below.

> 
> Aside: What does the comment "not a default constructor" mean in the
> testcase?
I guess he meant "user-provided".

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-20 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

--- Comment #5 from Jonathan Wakely  ---
(In reply to Jonathan Wakely from comment #3)
> (In reply to Pablo Anigstein from comment #2)
> > (In reply to Andrew Pinski from comment #1)
> > > Hmm,
> > >  I noticed that since GCC 7 with -std=c++17, the b.x is not initialized at
> > > all. So the question I have is there a difference between C++ standards 
> > > here?
> 
> Derived is an aggregate in C++17, so b{} does aggregate init, not value init.

And that means its Base subobject is copy-initialized from {} which means we
get a value-initialized object, so it's correct that b.x is not initialized in
C++17 (which is what is shown in your godbolt link, because you didn't specify
any -std option to override the -std=gnu++17 default).

With -std=c++14 it looks like b.x is always set to zero, if I'm reading the
assembly output correctly (but I'm probably not).

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-20 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

--- Comment #4 from Jonathan Wakely  ---
(In reply to Jonathan Wakely from comment #3)
> Derived is an aggregate since C++17.

Correction, it's an aggregate *only* in C++17. In C++20 the rule changed again
so the user-declared (but not user-provided) constructor makes it a
non-aggregate.

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-20 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

--- Comment #3 from Jonathan Wakely  ---
(In reply to Pablo Anigstein from comment #2)
> (In reply to Andrew Pinski from comment #1)
> > Hmm,
> >  I noticed that since GCC 7 with -std=c++17, the b.x is not initialized at
> > all. So the question I have is there a difference between C++ standards 
> > here?

Derived is an aggregate in C++17, so b{} does aggregate init, not value init.

> > Note the issue is we call Base's constructor after doing the zero
> > initialization and the Base's constructor has a clobber in it which I think
> > is correct.

Maybe we should only clobber in the complete object constructor _ZN4BaseC1Ev
and not in _ZN4BaseC2Ev.

> > This is all front-end generation and not exactly related to the
> > optimizations directly.
> 
> There is no difference between C++ standards in this respect.

Before C++11 there was no zero-init at all. Since C++11 the spec keeps
changing, but the effects of zero-init are substantially the same. But Derived
is an aggregate since C++17.

Aside: What does the comment "not a default constructor" mean in the testcase?

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-04-19 Thread panigstein at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

panigstein at hotmail dot com changed:

   What|Removed |Added

 CC||panigstein at hotmail dot com

--- Comment #2 from panigstein at hotmail dot com ---
(In reply to Andrew Pinski from comment #1)
> Hmm,
>  I noticed that since GCC 7 with -std=c++17, the b.x is not initialized at
> all. So the question I have is there a difference between C++ standards here?
> 
> Note the issue is we call Base's constructor after doing the zero
> initialization and the Base's constructor has a clobber in it which I think
> is correct.
> 
> This is all front-end generation and not exactly related to the
> optimizations directly.

There is no difference between C++ standards in this respect. For a class that
has a defaulted default constructor (Derived), value-initialization consists of
zero-initialization followed by default-initialization. The clobbering of the
Base sub-object is incorrect here and makes the implementation of
value-initialization non-conforming.

[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5

2023-03-02 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993

Andrew Pinski  changed:

   What|Removed |Added

   Keywords||wrong-code

--- Comment #1 from Andrew Pinski  ---
Hmm,
 I noticed that since GCC 7 with -std=c++17, the b.x is not initialized at all.
So the question I have is there a difference between C++ standards here?

Note the issue is we call Base's constructor after doing the zero
initialization and the Base's constructor has a clobber in it which I think is
correct.

This is all front-end generation and not exactly related to the optimizations
directly.