From ce12ed20c60bd16c44aad271ca0fd9cf1ec00310 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 14 Jan 2015 02:27:38 +0000 Subject: 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 --- clang/lib/Sema/SemaDecl.cpp | 9 ++++++++- clang/test/Sema/var-redecl.c | 8 ++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'clang') diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1bf57f6cee7..b967e17148d 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 5ba6965f718..811e9f10bf2 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]'}} -- cgit v1.2.3