[Bug c++/70820] New: GCC incorrectly accepts code that accesses nested names in an incomplete type
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
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
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
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
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.