<br><br><div class="gmail_quote">On Tue, Oct 23, 2012 at 10:19 PM, Eli Friedman <span dir="ltr"><<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: efriedma<br>
Date: Tue Oct 23 15:19:32 2012<br>
New Revision: 166498<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=166498&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=166498&view=rev</a><br>
Log:<br>
Add a new warning -Wmissing-variable-declarations, to warn about variables<br>
defined without a previous declaration.  This is similar to<br>
-Wmissing-prototypes, but for variables instead of functions.<br>
<br>
Patch by Ed Schouten.<br>
<br>
<br>
Added:<br>
    cfe/trunk/test/Sema/warn-missing-variable-declarations.c<br>
    cfe/trunk/test/Sema/warn-missing-variable-declarations.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/Sema/Sema.cpp<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=166498&r1=166497&r2=166498&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=166498&r1=166497&r2=166498&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Oct 23 15:19:32 2012<br>
@@ -3139,6 +3139,9 @@<br>
 def warn_missing_prototype : Warning<<br>
   "no previous prototype for function %0">,<br>
   InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;<br>
+def warn_missing_variable_declarations : Warning<<br>
+  "no previous extern declaration for non-static variable %0">,<br>
+  InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;<br>
 def err_redefinition : Error<"redefinition of %0">;<br>
 def err_definition_of_implicitly_declared_member : Error<<br>
   "definition of implicitly declared %select{default constructor|copy "<br>
<br>
Modified: cfe/trunk/lib/Sema/Sema.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=166498&r1=166497&r2=166498&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=166498&r1=166497&r2=166498&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/Sema.cpp (original)<br>
+++ cfe/trunk/lib/Sema/Sema.cpp Tue Oct 23 15:19:32 2012<br>
@@ -665,6 +665,8 @@<br>
                                    diag::err_tentative_def_incomplete_type))<br>
       VD->setInvalidDecl();<br>
<br>
+    CheckCompleteVariableDeclaration(VD);<br>
+<br>
     // Notify the consumer that we've completed a tentative definition.<br>
     if (!VD->isInvalidDecl())<br>
       Consumer.CompleteTentativeDefinition(VD);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=166498&r1=166497&r2=166498&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=166498&r1=166497&r2=166498&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Oct 23 15:19:32 2012<br>
@@ -7148,6 +7148,17 @@<br>
     }<br>
   }<br>
<br>
+  if (var->isThisDeclarationADefinition() &&<br>
+      var->getLinkage() == ExternalLinkage) {<br>
+    // Find a previous declaration that's not a definition.<br>
+    VarDecl *prev = var->getPreviousDecl();<br>
+    while (prev && prev->isThisDeclarationADefinition())<br>
+      prev = prev->getPreviousDecl();<br>
+<br>
+    if (!prev)<br>
+      Diag(var->getLocation(), diag::warn_missing_variable_declarations) << var;<br>
+  }<br>
+<br>
   // All the following checks are C++ only.<br>
   if (!getLangOpts().CPlusPlus) return;<br>
<br>
<br>
Added: cfe/trunk/test/Sema/warn-missing-variable-declarations.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-missing-variable-declarations.c?rev=166498&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-missing-variable-declarations.c?rev=166498&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Sema/warn-missing-variable-declarations.c (added)<br>
+++ cfe/trunk/test/Sema/warn-missing-variable-declarations.c Tue Oct 23 15:19:32 2012<br>
@@ -0,0 +1,36 @@<br>
+// RUN: %clang -Wmissing-variable-declarations -fsyntax-only -Xclang -verify %s<br>
+<br>
+int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}<br>
+<br>
+int vbad2;<br>
+int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}<br>
+<br>
+struct {<br>
+  int mgood1;<br>
+} vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}}<br>
+<br>
+int vbad4;<br>
+int vbad4 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad4'}}<br>
+extern int vbad4;<br>
+<br>
+extern int vgood1;<br>
+int vgood1;<br>
+int vgood1 = 10;<br>
+// RUN: %clang -Wmissing-variable-declarations -fsyntax-only -Xclang -verify %s<br>
+<br>
+int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}<br>
+<br>
+int vbad2;<br>
+int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}<br>
+<br>
+struct {<br>
+  int mgood1;<br>
+} vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}}<br>
+<br>
+int vbad4;<br>
+int vbad4 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad4'}}<br>
+extern int vbad4;<br>
+<br>
+extern int vgood1;<br>
+int vgood1;<br>
+int vgood1 = 10;<br>
<br></blockquote><div>Did I miss something or is this test case "doubled" ?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Added: cfe/trunk/test/Sema/warn-missing-variable-declarations.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-missing-variable-declarations.cpp?rev=166498&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-missing-variable-declarations.cpp?rev=166498&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Sema/warn-missing-variable-declarations.cpp (added)<br>
+++ cfe/trunk/test/Sema/warn-missing-variable-declarations.cpp Tue Oct 23 15:19:32 2012<br>
@@ -0,0 +1,39 @@<br>
+// RUN: %clang -Wmissing-variable-declarations -fsyntax-only -Xclang -verify %s<br>
+<br>
+// Variable declarations that should trigger a warning.<br>
+int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}<br>
+int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}<br>
+<br>
+// Variable declarations that should not trigger a warning.<br>
+static int vgood1;<br>
+extern int vgood2;<br>
+int vgood2;<br>
+static struct {<br>
+  int mgood1;<br>
+} vgood3;<br>
+<br>
+// Functions should never trigger a warning.<br>
+void fgood1(void);<br>
+void fgood2(void) {<br>
+  int lgood1;<br>
+  static int lgood2;<br>
+}<br>
+static void fgood3(void) {<br>
+  int lgood3;<br>
+  static int lgood4;<br>
+}<br>
+<br>
+// Structures, namespaces and classes should be unaffected.<br>
+struct sgood1 {<br>
+  int mgood2;<br>
+};<br>
+struct {<br>
+  int mgood3;<br>
+} sgood2;<br>
+class CGood1 {<br>
+  static int MGood1;<br>
+};<br>
+int CGood1::MGood1;<br>
+namespace {<br>
+  int mgood4;<br>
+}<br>
<br><br></blockquote><div><br>How does this interact with "static" variables (at file scope) ?<br><br>Also, there is no test in "named" namespaces, should not this be covered too ?<br><br>-- Matthieu<br>
</div><br></div>