[cfe-commits] r93188 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp

Douglas Gregor dgregor at apple.com
Mon Jan 11 13:54:40 PST 2010


Author: dgregor
Date: Mon Jan 11 15:54:40 2010
New Revision: 93188

URL: http://llvm.org/viewvc/llvm-project?rev=93188&view=rev
Log:
Allow redefinitions of typedef-names within class scope when the type
they redefine is a class-name but not a typedef-name, per C++0x
[dcl.typedef]p4. The code in the test was valid C++98 and is valid
C++0x, but an unintended consequence of DR56 made it ill-formed in
C++03 (which we were luck enough to implement). Fixes PR5455.


Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=93188&r1=93187&r2=93188&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jan 11 15:54:40 2010
@@ -803,13 +803,38 @@
   if (getLangOptions().Microsoft)
     return;
 
-  // C++ [dcl.typedef]p2:
-  //   In a given non-class scope, a typedef specifier can be used to
-  //   redefine the name of any type declared in that scope to refer
-  //   to the type to which it already refers.
   if (getLangOptions().CPlusPlus) {
+    // C++ [dcl.typedef]p2:
+    //   In a given non-class scope, a typedef specifier can be used to
+    //   redefine the name of any type declared in that scope to refer
+    //   to the type to which it already refers.
     if (!isa<CXXRecordDecl>(CurContext))
       return;
+
+    // C++0x [dcl.typedef]p4:
+    //   In a given class scope, a typedef specifier can be used to redefine 
+    //   any class-name declared in that scope that is not also a typedef-name
+    //   to refer to the type to which it already refers.
+    //
+    // This wording came in via DR424, which was a correction to the
+    // wording in DR56, which accidentally banned code like:
+    //
+    //   struct S {
+    //     typedef struct A { } A;
+    //   };
+    //
+    // in the C++03 standard. We implement the C++0x semantics, which
+    // allow the above but disallow
+    //
+    //   struct S {
+    //     typedef int I;
+    //     typedef int I;
+    //   };
+    //
+    // since that was the intent of DR56.
+    if (New->getUnderlyingType()->getAs<ElaboratedType>())
+      return;
+
     Diag(New->getLocation(), diag::err_redefinition)
       << New->getDeclName();
     Diag(Old->getLocation(), diag::note_previous_definition);

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp?rev=93188&r1=93187&r2=93188&view=diff

==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp Mon Jan 11 15:54:40 2010
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -verify %s
-// XFAIL: *
 
 struct S {
   typedef struct A {} A; // expected-note {{previous definition is here}}





More information about the cfe-commits mailing list