[Bug c++/70820] New: GCC incorrectly accepts code that accesses nested names in an incomplete type

2016-04-27 Thread fdrocha at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70820

Bug ID: 70820
   Summary: GCC incorrectly accepts code that accesses nested
names in an incomplete type
   Product: gcc
   Version: 5.2.0
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: fdrocha at gmail dot com
  Target Milestone: ---

Consider the following code

template
struct Base {
static constexpr int i = Derived::j;
// static_assert(i>1, "First assert"); // First Assert
// int array[i]; // Array declation
};

struct Derived : public Base {
static  constexpr int j = 5 ;
};

static constexpr int k = Base::i; 
static_assert(Derived::i > 0, "Second Assert");
static_assert(Base::i > 0, "Third Assert");
int array[Derived::i];

GCC compiles this (I tried all versions between 4.9.0 and 5.3.0) with no errors
or warnings even with -Wall -Wextra.
If you uncomment either the line marked "First Assert" or "Array Declaration"
it correctly gives the error "error: incomplete type 'Derived' used in nested
name specifier". It should also not accept the code without those lines, for
the same reason.

[Bug c++/70820] GCC incorrectly accepts code that accesses nested names in an incomplete type

2016-04-27 Thread fdrocha at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70820

Fabio Rocha  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |FIXED

--- Comment #2 from Fabio Rocha  ---
(In reply to Jason Merrill from comment #1)
> 14.7.1:  "The implicit instantiation of a class template specialization
> causes the implicit instantiation of the declarations, but not of the
> definitions, default arguments, or exception-specifications of the class
> member functions, member classes, scoped member enumerations, static data
> members and member templates; and it causes the implicit instantiation of
> the definitions of unscoped member enumerations and member anonymous unions."
> 
> So I don't think that the instantiation of Base requires the
> instantiation of the definition of Base::i.

You may be correct, not sure this is actually bug. 
Still, it feels pretty strange that uncommenting the "First Assert" is what
makes the code incorrect...

[Bug c++/70820] GCC incorrectly accepts code that accesses nested names in an incomplete type

2016-04-27 Thread fdrocha at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70820

Fabio Rocha  changed:

   What|Removed |Added

 Resolution|FIXED   |INVALID

[Bug c++/70820] GCC incorrectly accepts code that accesses nested names in an incomplete type

2016-04-27 Thread fdrocha at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70820

--- Comment #3 from Fabio Rocha  ---
(In reply to Jason Merrill from comment #1)
> 14.7.1:  "The implicit instantiation of a class template specialization
> causes the implicit instantiation of the declarations, but not of the
> definitions, default arguments, or exception-specifications of the class
> member functions, member classes, scoped member enumerations, static data
> members and member templates; and it causes the implicit instantiation of
> the definitions of unscoped member enumerations and member anonymous unions."
> 
> So I don't think that the instantiation of Base requires the
> instantiation of the definition of Base::i.

You may be correct, not sure this is actually bug. 
Still, it feels pretty strange that uncommenting the "First Assert" is what
makes the code incorrect...

[Bug c++/70820] GCC incorrectly accepts code that accesses nested names in an incomplete type

2016-04-28 Thread fdrocha at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70820

--- Comment #5 from Fabio Rocha  ---
(In reply to Jonathan Wakely from comment #4)
> (In reply to Fabio Rocha from comment #3) 
> > Still, it feels pretty strange that uncommenting the "First Assert" is what
> > makes the code incorrect...
> 
> That's not strange at all, the assertion requires the value of the static
> data member, so it causes it to be instantiated, while the type is
> incomplete.
> 
> Without that assertion the static data member is not instantiated until the
> definition of ::k, after the types are complete.

That makes sense, it's pretty nice that it works out like this.
For what it's worth, clang rejects the code, but I am convinced gcc is in the
right.