[Bug c++/81051] virtual base access during construction crashes

2022-12-24 Thread mattlloydhouse at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81051

Matthew House  changed:

   What|Removed |Added

 CC||mattlloydhouse at gmail dot com

--- Comment #4 from Matthew House  ---
Both of these example programs result in undefined behavior.

The cited subclause, C++14 12.7 [class.dtor] p3, does not apply, since the call
expression neither forms a pointer to a member nor accesses the value of a
member. Instead, the relevant subclause is C++14 12.6.2 [class.base.init] p14.
The example for that subclause demonstrates that a member function inherited
from an initialized base class may not be called directly from the derived
object until all base class subobjects are initialized.

In the first program, this->Func() calls the inherited member function Func of
Derived, but the initializer for B has not completed yet, so the behavior is
undefined. The same applies to the p->Func() call in the second program. 

However, this segfault persists if this->Func() or p->Func() is replaced with
((A*)this)->Func() or ((A*)p)->Func() in either example. The conversion doesn't
result in UB, since the construction of Derived has started, and the function
call doesn't result in UB, since the A subobject is already initialized. Thus,
the behavior of GCC is still erroneous in this case.

struct A
{
  int Func () { return x++; }
  int x = 5;
};

struct B { B (int) {} };

struct Derived : virtual A, B
{
  friend int f (Derived *p) { return ((A *) p)->Func (); }
  Derived () : A (), B (f (this)) {}
};

int main()
{
  Derived d;
}

[Bug c/105294] restrict pointer - disagreement with specification

2022-12-24 Thread mattlloydhouse at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105294

Matthew House  changed:

   What|Removed |Added

 CC||mattlloydhouse at gmail dot com

--- Comment #2 from Matthew House  ---
Isn't this example invalid per the spec? At `*r = 42;`, `&*r` is based on `s`.
However, `*p = 13;` modifies the same object that `*r` refers to, and `&*p` is
not based on `s`, so the behavior is undefined.

I've recently found another example which is valid under the current spec as
well as the two new proposed definitions in N3025 and N3058. 

https://godbolt.org/z/ezvMfPd78

static int x;

__attribute__ ((noinline))
int f(int * restrict p) {
  *p = 1;
  if (p == &x) {
*p = 2;
  }
  return *p;
}

int main(void) {
  return f(&x);
}

At `*p = 2;`, `&*p` is based on `p` under every definition. However, both GCC
and Clang incorrectly assume that the write to `*p` inside the `if` block
cannot affect the return value.