aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-01-14 02:27:38 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-01-14 02:27:38 +0000
commitce12ed20c60bd16c44aad271ca0fd9cf1ec00310 (patch)
tree6d4aae9e7e4d1f63ac873504019b7f554f15267a
parent2eb4d4468f1fe5326fef536c660b9246c74ce41d (diff)
downloadllvm-ce12ed20c60bd16c44aad271ca0fd9cf1ec00310.zip
llvm-ce12ed20c60bd16c44aad271ca0fd9cf1ec00310.tar.gz
llvm-ce12ed20c60bd16c44aad271ca0fd9cf1ec00310.tar.bz2
Sema: Check type compatibility with the most recent decl when merging
We would check the type information from the declaration found by lookup but we would neglect checking compatibility with the most recent declaration. This would make it possible for us to not correctly diagnose inconsistencies with declarations which were made in a different scope. llvm-svn: 225934
-rw-r--r--clang/lib/Sema/SemaDecl.cpp9
-rw-r--r--clang/test/Sema/var-redecl.c8
2 files changed, 14 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1bf57f6..b967e17 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3239,8 +3239,15 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
}
// Merge the types.
- MergeVarDeclTypes(New, Old, mergeTypeWithPrevious(*this, New, Old, Previous));
+ VarDecl *MostRecent = Old->getMostRecentDecl();
+ if (MostRecent != Old) {
+ MergeVarDeclTypes(New, MostRecent,
+ mergeTypeWithPrevious(*this, New, MostRecent, Previous));
+ if (New->isInvalidDecl())
+ return;
+ }
+ MergeVarDeclTypes(New, Old, mergeTypeWithPrevious(*this, New, Old, Previous));
if (New->isInvalidDecl())
return;
diff --git a/clang/test/Sema/var-redecl.c b/clang/test/Sema/var-redecl.c
index 5ba6965..811e9f1 100644
--- a/clang/test/Sema/var-redecl.c
+++ b/clang/test/Sema/var-redecl.c
@@ -4,7 +4,7 @@ int outer1; // expected-note{{previous definition is here}}
extern int outer2; // expected-note{{previous definition is here}}
int outer4;
int outer4; // expected-note{{previous definition is here}}
-int outer5; // expected-note{{previous definition is here}}
+int outer5;
int outer6(float); // expected-note{{previous definition is here}}
int outer7(float);
@@ -13,7 +13,7 @@ void outer_test() {
extern float outer2; // expected-error{{redefinition of 'outer2' with a different type}}
extern float outer3; // expected-note{{previous definition is here}}
double outer4;
- extern int outer5;
+ extern int outer5; // expected-note{{previous definition is here}}
extern int outer6; // expected-error{{redefinition of 'outer6' as different kind of symbol}}
int outer7;
extern int outer8; // expected-note{{previous definition is here}}
@@ -64,3 +64,7 @@ int a; // expected-error {{non-static declaration of 'a' follows static declarat
void f(int x) { // expected-note {{previous definition is here}}
extern int x; // expected-error {{extern declaration of 'x' follows non-extern declaration}}
}
+
+extern int b[];
+void g20() { extern int b[3]; } // expected-note{{previous definition is here}}
+void g21() { extern int b[4]; } // expected-error{{redefinition of 'b' with a different type: 'int [4]' vs 'int [3]'}}