[Bug c++/85548] New: Zero-initialization of padding bits of an aggregate class (class A) member of a non-aggregate class (class B) is not performed when B is value-initialized.

2018-04-27 Thread jenda.tusil at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85548

Bug ID: 85548
   Summary: Zero-initialization of padding bits of an aggregate
class (class A) member of a non-aggregate class (class
B) is not performed when B is value-initialized.
   Product: gcc
   Version: 7.3.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: jenda.tusil at gmail dot com
  Target Milestone: ---

Consider classes A and B:

```
struct A {
char c1;
int i1;
char c2;
int i2;
};

struct B {
virtual void foo(){}
A a;
};
```

The class `A` is an aggregate, `B` is not.
Now consider this declaration:

```
B b{};
```

When an instance of `B` is list-initialized with an empty list, it should be
value-initialized, because `B` is not an aggregate, and because it has a
default-constructor (the implicitly-generated `B::B()`). In this case,
value-initialization means zero-initialization, because `B` is a class-type
without deleted or user-provided default-constructor. Therefore the non-static
member `B::a` is zero-initialized, as well as the padding bits of `B` (there
are none on x86-64). The zero-initialization of 'b.a' means zero-initialization
of `c1`, `i1`, `c2`, `i2`, and of all the padding. However, GCC 6 and GCC 7
does not perform the zero-initialization of the padding (clang 5 and clang 6
does).



A full program:

```
extern "C" void abort();
#define assert(x) if(!(x)) abort();

struct A {
char c1;
int i1;
char c2;
int i2;
};

struct B {
virtual void foo(){}
A a;
};

int main() {
B my_b{};

assert(my_b.a.c1 == 0); // the members are zero-initialized

int const alig_size_1 = int(((char *)_b.a.i1 - _b.a.c1) -
sizeof(my_b.a.c1));

// This does not have to hold, but holds for x86-64
assert(alig_size_1 > 0);

for (int i = 0; i < alig_size_1; i++) {
assert(*(_b.a.c1 + 1 + i) == 0); // fails
}

// The same for the padding between A::c2 and A::i2

int const alig_size_2 = int(((char *)_b.a.i2 - _b.a.c2) -
sizeof(my_b.a.c2));
assert(alig_size_2 > 0);
for (int i = 0; i < alig_size_2; i++) {
assert(*(_b.a.c2 + 1 + i) == 0);
}
}
```

Also, when optimizing with -O1, GCC 7.3 gives the following warnings:
```
warning: '*((void*)& my_b +9)' is used uninitialized in this function

   assert(*(_b.a.c1 + 1 + i) == 0);

  ^

warning: '*((void*)& my_b +10)' may be used uninitialized in this function

warning: '*((void*)& my_b +11)' may be used uninitialized in this function

warning: '*((void*)& my_b +17)' may be used uninitialized in this function

   assert(*(_b.a.c2 + 1 + i) == 0);

  ^

warning: '*((void*)& my_b +18)' may be used uninitialized in this function

warning: '*((void*)& my_b +19)' may be used uninitialized in this function
```

[Bug c++/83132] Error while redeclaring an enum with extra qualification

2017-11-23 Thread jenda.tusil at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83132

--- Comment #2 from Jan Tušil  ---
The 'struct' version can be simplified to:

struct E;
struct ::E {};

Which gives the following error:
2:12: error: global qualification of class name is invalid before '{' token

[Bug c++/83132] New: Error while redeclaring an enum with extra qualification

2017-11-23 Thread jenda.tusil at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83132

Bug ID: 83132
   Summary: Error while redeclaring an enum with extra
qualification
   Product: gcc
   Version: 7.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: jenda.tusil at gmail dot com
  Target Milestone: ---

g++ -std=c++14 does not compile this:

enum E : int;
enum ::E : int{};

It says:
2:10: error: expected unqualified-id before ‘:’ token

Clang compiles it without errors, but gives a little wierd warning:
warning: extra qualification on member 'E' [-Wextra-qualification]

The bug was found in the context of this SO thread:
https://stackoverflow.com/q/47383199/6209703

It manifestes in most (all?) gcc versions on https://gcc.godbolt.org/