[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