Re: [C++] Possible GCC bug

2012-11-14 Thread Jiri Palecek

Ulf Magnusson wrote:

On Wed, Nov 14, 2012 at 6:10 PM, Piotr Wyderski
  wrote:

The following snippet:

class A {};
class B : public A {

typedef A super;

public:

class X {};
};


class C : public B {

typedef B super;

class X : public super::X {

   typedef super::X super;
};
};

compiles without a warning on Comeau and MSVC, but GCC (4.6.1 and
4.7.1) failes with the following message:

$ gcc -c bug.cpp
bug.cpp:18:24: error: declaration of ‘typedef class B::X C::X::super’
[-fpermissive]
bug.cpp:14:14: error: changes meaning of ‘super’ from ‘typedef class B
C::super’ [-fpermissive]

Should I file a report?

 Best regards, Piotr

Here's a two-line TC:

typedef struct { typedef int type; } s1;
struct S2 { s1::type s1; };

Fails with GCC 4.6.3; succeeds with clang 3.0. Looks like a bug to me.

/Ulf


In your example, GCC is in fact right. Basically, you mustn't have a name refer 
to two things in a class:

3.3.6/1: ... A name N used in a class S shall refer to the same declaration in 
its context and when re-evaluated in the
completed scope of S. No diagnostic is required for a violation of this rule. 
...

Regards
Jiří Paleček




Re: [C++] Possible GCC bug

2012-11-16 Thread Jiri Palecek

Piotr Wyderski wrote:

Dodji Seketeli wrote:


That, and [dcl.typedef]/6 says:

 In a given scope, a typedef specifier shall not be used to redefine
 the name of any type declared in that scope to refer to a different
 type.

So, I tend to think that GCC is right here.

Right *where*? In case of the snippet provided by Ulf -- yes, obviously.
In my case there is no "that scope", i.e. I redefine the type "super" defined
in the *surrounding* scope, not in the very same, as Ulf did. It is exactly
the same situation as:

 { int i;
   float i;
 }

and:

 {int i;
 { float i;}
 }


GCC is right in both cases and, similarly, [dcl.typedef]/6 doesn't affect any 
of them at all, because, as you noted, there aren't any redeclarations in the 
same scope in any of the two snippets.

However, you should not forget about [basic.scope.class]/1. I will not post the 
wording again, but it means a name used in a class must mean the same thing in 
all uses and at the end of the class. [basic.lookup.unqual]/7 says

A name used in the definition of a class X outside of a member function 
body or nested class definition [This refers to unqualified names following the 
class name; such a name may be used in the base-clause or may be used in the 
class definition.] ...

So, the name of the base class *is* used in the derived class and as such, must not be 
redefined throughout the whole class; in your example, "super" is violating 
that rule.

Note that no diagnostic is required for violation of this rule, so the compiler 
might just accept it. However, it is still invalid code and gcc is right to 
reject it.

Regards
Jiří Paleček