]> granicus.if.org Git - clang/commitdiff
Diagnose if extern local variable is followed by non-extern and vice-versa.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 31 Jan 2011 07:04:46 +0000 (07:04 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 31 Jan 2011 07:04:46 +0000 (07:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124579 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/Sema/private-extern.c

index 7bec4c73dae7b6705ac08d497b126d357dbd755d..47174b76b04a5b137bd21ac6592c813ca95370fc 100644 (file)
@@ -1963,6 +1963,10 @@ def err_static_non_static : Error<
   "static declaration of %0 follows non-static declaration">;
 def err_non_static_static : Error<
   "non-static declaration of %0 follows static declaration">;
+def err_extern_non_extern : Error<
+  "extern declaration of %0 follows non-extern declaration">;
+def err_non_extern_extern : Error<
+  "non-extern declaration of %0 follows extern declaration">;
 def err_non_thread_thread : Error<
   "non-thread-local declaration of %0 follows thread-local declaration">;
 def err_thread_non_thread : Error<
index bcc67b2e9a98f236d4176d8ba687fc4b7fc72a2b..24307c98a97f5359c52bc844561cc4e3deaed3de 100644 (file)
@@ -1548,6 +1548,20 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
     return New->setInvalidDecl();
   }
 
+  // Check if extern is followed by non-extern and vice-versa.
+  if (New->hasExternalStorage() &&
+      !Old->hasLinkage() && Old->isLocalVarDecl()) {
+    Diag(New->getLocation(), diag::err_extern_non_extern) << New->getDeclName();
+    Diag(Old->getLocation(), diag::note_previous_definition);
+    return New->setInvalidDecl();
+  }
+  if (Old->hasExternalStorage() &&
+      !New->hasLinkage() && New->isLocalVarDecl()) {
+    Diag(New->getLocation(), diag::err_non_extern_extern) << New->getDeclName();
+    Diag(Old->getLocation(), diag::note_previous_definition);
+    return New->setInvalidDecl();
+  }
+
   // Variables with external linkage are analyzed in FinalizeDeclaratorGroup.
 
   // FIXME: The test for external storage here seems wrong? We still
index d3c12651098a02e2bce2789dcfb4a8d1e4453340..25591dc5b1f2f058ccc2abfc57feee7395f9b68d 100644 (file)
@@ -19,27 +19,23 @@ __private_extern__ int g5; // expected-note{{previous definition}}
 static int g5; // expected-error{{static declaration of 'g5' follows non-static declaration}}
 
 void f0() {
-  // FIXME: Diagnose this?
-  int g6;
-  extern int g6;
+  int g6; // expected-note {{previous}}
+  extern int g6; // expected-error {{extern declaration of 'g6' follows non-extern declaration}}
 }
 
 void f1() {
-  // FIXME: Diagnose this?
-  int g7;
-  __private_extern__ int g7;
+  int g7; // expected-note {{previous}}
+  __private_extern__ int g7; // expected-error {{extern declaration of 'g7' follows non-extern declaration}}
 }
 
 void f2() {
   extern int g8; // expected-note{{previous definition}}
-  // FIXME: Improve this diagnostic.
-  int g8; // expected-error{{redefinition of 'g8'}}
+  int g8; // expected-error {{non-extern declaration of 'g8' follows extern declaration}}
 }
 
 void f3() {
   __private_extern__ int g9; // expected-note{{previous definition}}
-  // FIXME: Improve this diagnostic.
-  int g9; // expected-error{{redefinition of 'g9'}}
+  int g9; // expected-error {{non-extern declaration of 'g9' follows extern declaration}}
 }
 
 void f4() {