For the following code:
struct foo {};
struct A
{
    typedef foo foo_type;
    void foo();
};
GCC gives a compiler error:
test.cpp:7:14: error: declaration of 'void A::foo()' [-fpermissive]
     void foo();
              ^
test.cpp:1:8: error: changes meaning of 'foo' from 'struct foo' [-fpermissive]
 struct foo {};
        ^
But clang accepts it without compiler errors. Who is right?
Note that if the typedef is removed, or changed to typedef ::foo foo_type, both gcc and clang accept the code.
                        
gcc is correct, but clang is not required to give a diagnostic (3.3.7):
This is because of how class scope works. The
fooofvoid foo();is visible within the entire scope of the classA, so the declaration ofvoid foo();changes the meaning offooin the typedef from referring tostruct footo the name of the functionfoo.