r225934 - Sema: Check type compatibility with the most recent decl when merging

David Majnemer david.majnemer at gmail.com
Tue Jan 13 18:27:39 PST 2015


Author: majnemer
Date: Tue Jan 13 20:27:38 2015
New Revision: 225934

URL: http://llvm.org/viewvc/llvm-project?rev=225934&view=rev
Log:
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.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Sema/var-redecl.c

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=225934&r1=225933&r2=225934&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jan 13 20:27:38 2015
@@ -3239,8 +3239,15 @@ void Sema::MergeVarDecl(VarDecl *New, Lo
   }
 
   // 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;
 

Modified: cfe/trunk/test/Sema/var-redecl.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/var-redecl.c?rev=225934&r1=225933&r2=225934&view=diff
==============================================================================
--- cfe/trunk/test/Sema/var-redecl.c (original)
+++ cfe/trunk/test/Sema/var-redecl.c Tue Jan 13 20:27:38 2015
@@ -4,7 +4,7 @@ int outer1; // expected-note{{previous d
 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 de
 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]'}}





More information about the cfe-commits mailing list