diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-01-11 22:33:48 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-01-11 22:33:48 +0000 |
commit | ec3bd728cc6505c98543b001a1988c237f5fb9a9 (patch) | |
tree | d09c14bc89326623b761885792cc44ae464289fa | |
parent | dc98cd0cdd2eee8290b624ef69c6d91ce626d85e (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.td | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 13 | ||||
-rw-r--r-- | test/Sema/c11-typedef-redef.c | 2 |
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]'}} } |