aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-11 22:33:48 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-11 22:33:48 +0000
commitec3bd728cc6505c98543b001a1988c237f5fb9a9 (patch)
treed09c14bc89326623b761885792cc44ae464289fa
parentdc98cd0cdd2eee8290b624ef69c6d91ce626d85e (diff)
Improve the diagnostic when trying to redefine a typedef with a
variably-modified type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147973 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaDecl.cpp13
-rw-r--r--test/Sema/c11-typedef-redef.c2
3 files changed, 15 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 74189ca947..4341dbbfa9 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2754,6 +2754,8 @@ def note_used_here : Note<"used here">;
def warn_redefinition_of_typedef : ExtWarn<
"redefinition of typedef %0 is a C11 feature">,
InGroup<DiagGroup<"typedef-redefinition"> >;
+def err_redefinition_variably_modified_typedef : Error<
+ "redefinition of %select{typedef|type alias}0 for variably-modified type %1">;
def err_inline_declaration_block_scope : Error<
"inline declaration of %0 not allowed in block scope">;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 588fc14044..f30f1fa5be 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1383,10 +1383,21 @@ bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {
OldType = Context.getTypeDeclType(Old);
QualType NewType = New->getUnderlyingType();
+ if (NewType->isVariablyModifiedType()) {
+ // Must not redefine a typedef with a variably-modified type.
+ int Kind = isa<TypeAliasDecl>(Old) ? 1 : 0;
+ Diag(New->getLocation(), diag::err_redefinition_variably_modified_typedef)
+ << Kind << NewType;
+ if (Old->getLocation().isValid())
+ Diag(Old->getLocation(), diag::note_previous_definition);
+ New->setInvalidDecl();
+ return true;
+ }
+
if (OldType != NewType &&
!OldType->isDependentType() &&
!NewType->isDependentType() &&
- !Context.hasSameType(OldType, NewType)) {
+ !Context.hasSameType(OldType, NewType)) {
int Kind = isa<TypeAliasDecl>(Old) ? 1 : 0;
Diag(New->getLocation(), diag::err_redefinition_different_typedef)
<< Kind << NewType << OldType;
diff --git a/test/Sema/c11-typedef-redef.c b/test/Sema/c11-typedef-redef.c
index 7e213f49cf..a6720a171b 100644
--- a/test/Sema/c11-typedef-redef.c
+++ b/test/Sema/c11-typedef-redef.c
@@ -10,5 +10,5 @@ void f(int N) {
typedef int type2;
typedef int vla[N]; // expected-note{{previous definition is here}}
- typedef int vla[N]; // expected-error{{typedef redefinition with different types ('int [N]' vs 'int [N]')}}
+ typedef int vla[N]; // expected-error{{redefinition of typedef for variably-modified type 'int [N]'}}
}