summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp9
-rw-r--r--clang/test/SemaCXX/typedef-redecl.cpp12
2 files changed, 20 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 7408507f234..0b05177dd37 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -344,7 +344,14 @@ TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
if (getLangOptions().Microsoft) return New;
- // Redeclaration of a type is a constraint violation (6.7.2.3p1).
+ // 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 && !isa<CXXRecordDecl>(CurContext))
+ return New;
+
+ // In C, redeclaration of a type is a constraint violation (6.7.2.3p1).
// Apparently GCC, Intel, and Sun all silently ignore the redeclaration if
// *either* declaration is in a system header. The code below implements
// this adhoc compatibility rule. FIXME: The following code will not
diff --git a/clang/test/SemaCXX/typedef-redecl.cpp b/clang/test/SemaCXX/typedef-redecl.cpp
new file mode 100644
index 00000000000..c37a08ab3aa
--- /dev/null
+++ b/clang/test/SemaCXX/typedef-redecl.cpp
@@ -0,0 +1,12 @@
+// RUN: clang -fsyntax-only -verify %s
+
+typedef int INT;
+typedef INT REALLY_INT; // expected-error{{previous definition is here}}
+typedef REALLY_INT REALLY_REALLY_INT;
+typedef REALLY_INT BOB;
+typedef float REALLY_INT; // expected-error{{typedef redefinition with different types ('float' vs 'INT')}}
+
+class X {
+ typedef int result_type; // expected-error{{previous definition is here}}
+ typedef INT result_type; // expected-error{{redefinition of 'result_type'}}
+};
OpenPOWER on IntegriCloud