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
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 "
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);
}
}
+ 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;
--- /dev/null
+// 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;
--- /dev/null
+// 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;
+}