]> granicus.if.org Git - clang/commitdiff
Add a new warning -Wmissing-variable-declarations, to warn about variables
authorEli Friedman <eli.friedman@gmail.com>
Tue, 23 Oct 2012 20:19:32 +0000 (20:19 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Tue, 23 Oct 2012 20:19:32 +0000 (20:19 +0000)
defined without a previous declaration.  This is similar to
-Wmissing-prototypes, but for variables instead of functions.

Patch by Ed Schouten.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166498 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/Sema.cpp
lib/Sema/SemaDecl.cpp
test/Sema/warn-missing-variable-declarations.c [new file with mode: 0644]
test/Sema/warn-missing-variable-declarations.cpp [new file with mode: 0644]

index efa974839acd615fd090fd9ae936f0fbf862e101..56cb2060421c32537e7b93300490759c06a288b2 100644 (file)
@@ -3139,6 +3139,9 @@ def note_sentinel_here : Note<
 def warn_missing_prototype : Warning<
   "no previous prototype for function %0">,
   InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
+def warn_missing_variable_declarations : Warning<
+  "no previous extern declaration for non-static variable %0">,
+  InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
 def err_redefinition : Error<"redefinition of %0">;
 def err_definition_of_implicitly_declared_member : Error<
   "definition of implicitly declared %select{default constructor|copy "
index eef5a2694a5ef921c910c55eaaf7735c80634a68..c7d378f1ac0c41e24819c0fd527e3c442d2da4c1 100644 (file)
@@ -665,6 +665,8 @@ void Sema::ActOnEndOfTranslationUnit() {
                                    diag::err_tentative_def_incomplete_type))
       VD->setInvalidDecl();
 
+    CheckCompleteVariableDeclaration(VD);
+
     // Notify the consumer that we've completed a tentative definition.
     if (!VD->isInvalidDecl())
       Consumer.CompleteTentativeDefinition(VD);
index 162c50b7fec9f063b4d55a900a810017937cbab4..19442b98c1a8fd498fe59b8a5ed2db5b77270e5e 100644 (file)
@@ -7148,6 +7148,17 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
     }
   }
 
+  if (var->isThisDeclarationADefinition() &&
+      var->getLinkage() == ExternalLinkage) {
+    // Find a previous declaration that's not a definition.
+    VarDecl *prev = var->getPreviousDecl();
+    while (prev && prev->isThisDeclarationADefinition())
+      prev = prev->getPreviousDecl();
+
+    if (!prev)
+      Diag(var->getLocation(), diag::warn_missing_variable_declarations) << var;
+  }
+
   // All the following checks are C++ only.
   if (!getLangOpts().CPlusPlus) return;
 
diff --git a/test/Sema/warn-missing-variable-declarations.c b/test/Sema/warn-missing-variable-declarations.c
new file mode 100644 (file)
index 0000000..cf911c2
--- /dev/null
@@ -0,0 +1,36 @@
+// RUN: %clang -Wmissing-variable-declarations -fsyntax-only -Xclang -verify %s
+
+int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}
+
+int vbad2;
+int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}
+
+struct {
+  int mgood1;
+} vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}}
+
+int vbad4;
+int vbad4 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad4'}}
+extern int vbad4;
+
+extern int vgood1;
+int vgood1;
+int vgood1 = 10;
+// RUN: %clang -Wmissing-variable-declarations -fsyntax-only -Xclang -verify %s
+
+int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}
+
+int vbad2;
+int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}
+
+struct {
+  int mgood1;
+} vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}}
+
+int vbad4;
+int vbad4 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad4'}}
+extern int vbad4;
+
+extern int vgood1;
+int vgood1;
+int vgood1 = 10;
diff --git a/test/Sema/warn-missing-variable-declarations.cpp b/test/Sema/warn-missing-variable-declarations.cpp
new file mode 100644 (file)
index 0000000..77c4c01
--- /dev/null
@@ -0,0 +1,39 @@
+// RUN: %clang -Wmissing-variable-declarations -fsyntax-only -Xclang -verify %s
+
+// Variable declarations that should trigger a warning.
+int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}
+int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}
+
+// Variable declarations that should not trigger a warning.
+static int vgood1;
+extern int vgood2;
+int vgood2;
+static struct {
+  int mgood1;
+} vgood3;
+
+// Functions should never trigger a warning.
+void fgood1(void);
+void fgood2(void) {
+  int lgood1;
+  static int lgood2;
+}
+static void fgood3(void) {
+  int lgood3;
+  static int lgood4;
+}
+
+// Structures, namespaces and classes should be unaffected.
+struct sgood1 {
+  int mgood2;
+};
+struct {
+  int mgood3;
+} sgood2;
+class CGood1 {
+  static int MGood1;
+};
+int CGood1::MGood1;
+namespace {
+  int mgood4;
+}