Bug 87518 - namespace and typedef : scope problem
Summary: namespace and typedef : scope problem
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.1.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-10-04 13:14 UTC by pierreblavy
Modified: 2018-10-04 13:55 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
test code (96 bytes, text/plain)
2018-10-04 13:14 UTC, pierreblavy
Details

Note You need to log in before you can comment on or make changes to this bug.
Description pierreblavy 2018-10-04 13:14:05 UTC
Created attachment 44784 [details]
test code

Hello.

The following c++ code compiles with 'clang++ -std=c++17 test.cpp' but not with  'g++ -std=c++17 test.cpp'

I don't know who's right between clang and gcc, but I suspect that gcc reads the 'typedef t t' line backward, and therefore override the first 't' with the second one.

This bug might be related to bug number 23594

Best regards


--- test.cpp ---
namespace test{
   typedef double t;

   struct A{
     typedef t t;
   };
}

int main(int,char**){return 0;}



--- g++ error message ---
g++ -std=c++17 test.cpp 
test.cpp:5:16: error: declaration of ‘typedef test::t test::A::t’ [-fpermissive]
      typedef t t;
                ^
test.cpp:2:19: error: changes meaning of ‘t’ from ‘typedef double test::t’ [-fpermissive]
    typedef double t;



--- g++ --version ---
g++ (GCC) 8.1.1 20180712 (Red Hat 8.1.1-5)
Comment 1 Jonathan Wakely 2018-10-04 13:51:48 UTC
The standard says:

  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.

Before the typedef the name 't' refers to the declaration of test::t, but after the typedef the name 't' refers to the declaration of A::t.

Even though the two declarations denote the same type, they are distinct declarations, which violates the rule. Clang is less strict and does not diagnose the violation of the rule.

Arguably a special case could be given to allow it when the two declarations refer to the same entity, but since the typedef seems completely pointless anyway I don't see any benefit to adding a special case.
Comment 2 Jonathan Wakely 2018-10-04 13:52:40 UTC
P.S. it has nothing to do with namespaces:

typedef double t;

struct A{
  typedef t t;
};

int main() { }
Comment 3 Jonathan Wakely 2018-10-04 13:55:36 UTC
Also see [dcl.typedef] paragraphs 3 and 4 in the standard, which has an example very similar to this:

struct S {
  typedef struct A { } A;    // OK
  typedef struct B B;        // OK
  typedef A A;               // error
};