Created attachment 35988 [details] prog.cc used in the command line Compile the attached program with the following command line: gcc prog.cc The output is the following: prog.cc:6:22: error: definition of ‘void A::f()’ is not in namespace enclosing ‘A’ [-fpermissive] class A { void f() {} }; ^ The expected behaviour is not to get this error message. The error message seem to suggest that the compiler thinks that the program violates [class.mfct]/2 where one sentence says: "A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition." Observe however that the member function definition in the given program is made inside the class definition. Note that if we remove the member function definition in the given program it compiles without errors. Output of gcc -v: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
Clang compiles it OK, but EDG says: "a.cc", line 5: error: class "A" cannot be defined in the current scope class A { void f() {} }; This seems similar to the G++ error, which is due to the name A referring to ::A, which should be defined in the global scope. I'm not sure whether the definition of Y::A should be an error, or (as Clang thinks) should declare a new type, which cannot be referred to due to the ambiguity caused by the using-declaration.
(In reply to Anders Granlund from comment #0) > Note that if we remove the member function definition in the given program > it compiles without errors. I think that's the real bug. G++ should not accept this program: class A; namespace Y { using ::A; class A { }; } int main() { Y::A a; ::A* p = &a; } Clang rejects it because Y::A in main() is ambiguous, but EDG rejects it with the same error as for the original testcase: "a.cc", line 5: error: class "A" cannot be defined in the current scope class A { }; ^ I believe EDG is right to reject that class-specifier because the class name A has already been introduced into that scope, and it cannot be a definition of ::A because it doesn't use a nested-name-specifier and it isn't in the namespace (or an enclosing namespace) of ::A.
Thanks for the comments! Now I remember the following bug report that I sent to clang: https://llvm.org/bugs/show_bug.cgi?id=24030 That bug has now been confirmed and fixed in clang, so yes this is the actual bug and it should be fixed in gcc also.
So confirming as accepts-invalid with this testcase: class A; namespace Y { using ::A; class A { }; }
*** Bug 66888 has been marked as a duplicate of this bug. ***
*** Bug 66889 has been marked as a duplicate of this bug. ***
(In reply to Jonathan Wakely from comment #4) > So confirming as accepts-invalid with this testcase: > > class A; > > namespace Y { > using ::A; > class A { }; > } Here are two similar test cases pulled in from my related bug reports (i have marked them as resolved duplicates). The following ill-formed programs are also accepted by gcc: namespace R { struct f; } namespace S { using R::f; } struct S::f {}; int main() {} The above is ill-formed by [dcl.meaning]p1 ( http://eel.is/c++draft/dcl.meaning#1 ) namespace P { struct S; } namespace R { using namespace P; } struct R::S {}; int main() {} The above is also ill-formed by [dcl.meaning]p1 In general redeclarations must be done directly and not indirectly.
*** Bug 66901 has been marked as a duplicate of this bug. ***
*** Bug 66878 has been marked as a duplicate of this bug. ***
Here comes two more test cases moved in from my related ICE on compile bug reports: namespace X { struct S; namespace Y { namespace Z = X; struct Z::S {}; } } int main() {} struct S; namespace H { namespace P { using ::S; } struct P::S {}; } int main() {} The above programs bot gives ICE on compile (infinite recursion in push_inner_scope_r -> stack overflow). They also involve trying to perform redeclarations indirectly.