public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++] Possible GCC bug
@ 2012-11-14 17:10 Piotr Wyderski
  2012-11-14 19:51 ` Ulf Magnusson
  0 siblings, 1 reply; 7+ messages in thread
From: Piotr Wyderski @ 2012-11-14 17:10 UTC (permalink / raw)
  To: GCC Mailing List

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [C++] Possible GCC bug
  2012-11-14 17:10 [C++] Possible GCC bug Piotr Wyderski
@ 2012-11-14 19:51 ` Ulf Magnusson
  2012-11-14 21:10   ` Jiri Palecek
  0 siblings, 1 reply; 7+ messages in thread
From: Ulf Magnusson @ 2012-11-14 19:51 UTC (permalink / raw)
  To: Piotr Wyderski; +Cc: GCC Mailing List

On Wed, Nov 14, 2012 at 6:10 PM, Piotr Wyderski
<piotr.wyderski@gmail.com> 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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [C++] Possible GCC bug
  2012-11-14 19:51 ` Ulf Magnusson
@ 2012-11-14 21:10   ` Jiri Palecek
  2012-11-16  9:23     ` Dodji Seketeli
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Palecek @ 2012-11-14 21:10 UTC (permalink / raw)
  To: Ulf Magnusson; +Cc: gcc

Ulf Magnusson wrote:
> On Wed, Nov 14, 2012 at 6:10 PM, Piotr Wyderski
> <piotr.wyderski@gmail.com>  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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [C++] Possible GCC bug
  2012-11-14 21:10   ` Jiri Palecek
@ 2012-11-16  9:23     ` Dodji Seketeli
  2012-11-16 15:15       ` Piotr Wyderski
  0 siblings, 1 reply; 7+ messages in thread
From: Dodji Seketeli @ 2012-11-16  9:23 UTC (permalink / raw)
  To: Jiri Palecek; +Cc: Ulf Magnusson, gcc

Jiri Palecek <jpalecek@web.de> a écrit:

> Ulf Magnusson wrote:
>> On Wed, Nov 14, 2012 at 6:10 PM, Piotr Wyderski
>> <piotr.wyderski@gmail.com>  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. ...

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.

-- 
		Dodji

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [C++] Possible GCC bug
  2012-11-16  9:23     ` Dodji Seketeli
@ 2012-11-16 15:15       ` Piotr Wyderski
  2012-11-16 17:22         ` Andrew Pinski
  2012-11-16 17:25         ` Jiri Palecek
  0 siblings, 2 replies; 7+ messages in thread
From: Piotr Wyderski @ 2012-11-16 15:15 UTC (permalink / raw)
  To: gcc

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;}
    }

    Best regards, Piotr

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [C++] Possible GCC bug
  2012-11-16 15:15       ` Piotr Wyderski
@ 2012-11-16 17:22         ` Andrew Pinski
  2012-11-16 17:25         ` Jiri Palecek
  1 sibling, 0 replies; 7+ messages in thread
From: Andrew Pinski @ 2012-11-16 17:22 UTC (permalink / raw)
  To: Piotr Wyderski; +Cc: gcc

On Fri, Nov 16, 2012 at 7:15 AM, Piotr Wyderski
<piotr.wyderski@gmail.com> 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;}
>     }
>

The scope is obvious:

 class X : public super::X

 {
   typedef super::X super;
    };

> 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. ...

The N here is supper, the class S here is X.  supper at the context of
the declaration of supper means the out scope supper and then its
meaning has changed by the end of the completed scope of X.  So GCC is
correct in erroring If you go by the literal use of 3.3.6/1.  The
other compilers are correct only because no diagnostic is required but
this is still invalid code.

Thanks,
Andrew Pinski

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [C++] Possible GCC bug
  2012-11-16 15:15       ` Piotr Wyderski
  2012-11-16 17:22         ` Andrew Pinski
@ 2012-11-16 17:25         ` Jiri Palecek
  1 sibling, 0 replies; 7+ messages in thread
From: Jiri Palecek @ 2012-11-16 17:25 UTC (permalink / raw)
  To: Piotr Wyderski; +Cc: gcc

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



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-11-16 17:25 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-14 17:10 [C++] Possible GCC bug Piotr Wyderski
2012-11-14 19:51 ` Ulf Magnusson
2012-11-14 21:10   ` Jiri Palecek
2012-11-16  9:23     ` Dodji Seketeli
2012-11-16 15:15       ` Piotr Wyderski
2012-11-16 17:22         ` Andrew Pinski
2012-11-16 17:25         ` Jiri Palecek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).