mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-19 11:35:51 -04:00
Suggestions to fix -Wmissing-{prototypes,variable-declarations}
Summary: I've found that most often the proper way to fix this warning is to add `static`, because if the code otherwise compiles and links, the function or variable is apparently not needed outside of the TU. We can't provide a fix-it hint for variable declarations, because multiple VarDecls can share the same type, and if we put static in front of that, we affect all declared variables, some of which might have previous declarations. We also provide no fix-it hint for the rare case of an `extern` function definition, because that would require removing `extern` and I have no idea how to get the source location of the storage class specifier from a FunctionDecl. I believe this information is only available earlier in the AST construction from DeclSpec::getStorageClassSpecLoc(), but we don't have that here. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D59402 llvm-svn: 363749
This commit is contained in:
parent
f9c6e565de
commit
df195d8aed
@ -4681,6 +4681,9 @@ def warn_strict_prototypes : Warning<
|
|||||||
def warn_missing_variable_declarations : Warning<
|
def warn_missing_variable_declarations : Warning<
|
||||||
"no previous extern declaration for non-static variable %0">,
|
"no previous extern declaration for non-static variable %0">,
|
||||||
InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
|
InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
|
||||||
|
def note_static_for_internal_linkage : Note<
|
||||||
|
"declare 'static' if the %select{variable|function}0 is not intended to be "
|
||||||
|
"used outside of this translation unit">;
|
||||||
def err_static_data_member_reinitialization :
|
def err_static_data_member_reinitialization :
|
||||||
Error<"static data member %0 already has an initializer">;
|
Error<"static data member %0 already has an initializer">;
|
||||||
def err_redefinition : Error<"redefinition of %0">;
|
def err_redefinition : Error<"redefinition of %0">;
|
||||||
|
@ -11899,8 +11899,11 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
|
|||||||
while (prev && prev->isThisDeclarationADefinition())
|
while (prev && prev->isThisDeclarationADefinition())
|
||||||
prev = prev->getPreviousDecl();
|
prev = prev->getPreviousDecl();
|
||||||
|
|
||||||
if (!prev)
|
if (!prev) {
|
||||||
Diag(var->getLocation(), diag::warn_missing_variable_declarations) << var;
|
Diag(var->getLocation(), diag::warn_missing_variable_declarations) << var;
|
||||||
|
Diag(var->getTypeSpecStartLoc(), diag::note_static_for_internal_linkage)
|
||||||
|
<< /* variable */ 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache the result of checking for constant initialization.
|
// Cache the result of checking for constant initialization.
|
||||||
@ -13364,6 +13367,13 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
|
|||||||
? FixItHint::CreateInsertion(FTL.getRParenLoc(), "void")
|
? FixItHint::CreateInsertion(FTL.getRParenLoc(), "void")
|
||||||
: FixItHint{});
|
: FixItHint{});
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Diag(FD->getTypeSpecStartLoc(), diag::note_static_for_internal_linkage)
|
||||||
|
<< /* function */ 1
|
||||||
|
<< (FD->getStorageClass() == SC_None
|
||||||
|
? FixItHint::CreateInsertion(FD->getTypeSpecStartLoc(),
|
||||||
|
"static ")
|
||||||
|
: FixItHint{});
|
||||||
}
|
}
|
||||||
|
|
||||||
// GNU warning -Wstrict-prototypes
|
// GNU warning -Wstrict-prototypes
|
||||||
|
@ -9,11 +9,17 @@ int f(int x) { return x; } // expected-warning{{no previous prototype for functi
|
|||||||
static int g(int x) { return x; }
|
static int g(int x) { return x; }
|
||||||
|
|
||||||
int h(int x) { return x; } // expected-warning{{no previous prototype for function 'h'}}
|
int h(int x) { return x; } // expected-warning{{no previous prototype for function 'h'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
|
||||||
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
|
||||||
|
|
||||||
static int g2();
|
static int g2();
|
||||||
|
|
||||||
int g2(int x) { return x; }
|
int g2(int x) { return x; }
|
||||||
|
|
||||||
|
extern int g3(int x) { return x; } // expected-warning{{no previous prototype for function 'g3'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
|
||||||
|
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:{{.*}}-[[@LINE-2]]:{{.*}}}:"{{.*}}"
|
||||||
|
|
||||||
void test(void);
|
void test(void);
|
||||||
|
|
||||||
int h3(); // expected-note{{this declaration is not a prototype; add parameter declarations to make it one}}
|
int h3(); // expected-note{{this declaration is not a prototype; add parameter declarations to make it one}}
|
||||||
@ -28,6 +34,7 @@ void test(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int h2(int x) { return x; } // expected-warning{{no previous prototype for function 'h2'}}
|
int h2(int x) { return x; } // expected-warning{{no previous prototype for function 'h2'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
|
||||||
int h3(int x) { return x; } // expected-warning{{no previous prototype for function 'h3'}}
|
int h3(int x) { return x; } // expected-warning{{no previous prototype for function 'h3'}}
|
||||||
int h4(int x) { return x; }
|
int h4(int x) { return x; }
|
||||||
|
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
// RUN: %clang_cc1 -Wmissing-variable-declarations -fsyntax-only -verify %s
|
// RUN: %clang_cc1 -Wmissing-variable-declarations -fsyntax-only -verify %s
|
||||||
|
|
||||||
int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}
|
int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
|
|
||||||
int vbad2;
|
int vbad2;
|
||||||
int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}
|
int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
|
|
||||||
struct {
|
struct { // expected-note{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
int mgood1;
|
int mgood1;
|
||||||
} vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}}
|
} vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}}
|
||||||
|
|
||||||
int vbad4;
|
int vbad4;
|
||||||
int vbad4 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad4'}}
|
int vbad4 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad4'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
extern int vbad4;
|
extern int vbad4;
|
||||||
|
|
||||||
extern int vgood1;
|
extern int vgood1;
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-prototypes -std=c++11 %s
|
// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-prototypes -std=c++11 %s
|
||||||
|
// RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
void f() { } // expected-warning {{no previous prototype for function 'f'}}
|
void f() { } // expected-warning {{no previous prototype for function 'f'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
|
||||||
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
|
||||||
|
|
||||||
namespace NS {
|
namespace NS {
|
||||||
void f() { } // expected-warning {{no previous prototype for function 'f'}}
|
void f() { } // expected-warning {{no previous prototype for function 'f'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -32,3 +36,7 @@ class I {
|
|||||||
|
|
||||||
// Don't warn on explicitly deleted functions.
|
// Don't warn on explicitly deleted functions.
|
||||||
void j() = delete;
|
void j() = delete;
|
||||||
|
|
||||||
|
extern void k() {} // expected-warning {{no previous prototype for function 'k'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
|
||||||
|
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:{{.*}}-[[@LINE-2]]:{{.*}}}:"{{.*}}"
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
// RUN: %clang -Wmissing-variable-declarations -fsyntax-only -Xclang -verify -std=c++17 %s
|
// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-variable-declarations -std=c++17 %s
|
||||||
|
|
||||||
// Variable declarations that should trigger a warning.
|
// Variable declarations that should trigger a warning.
|
||||||
int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}
|
int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
|
|
||||||
int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}
|
int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
|
|
||||||
namespace x {
|
namespace x {
|
||||||
int vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}}
|
int vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variable declarations that should not trigger a warning.
|
// Variable declarations that should not trigger a warning.
|
||||||
@ -58,7 +62,9 @@ const int const_var = 0;
|
|||||||
constexpr int constexpr_var = 0;
|
constexpr int constexpr_var = 0;
|
||||||
inline constexpr int inline_constexpr_var = 0;
|
inline constexpr int inline_constexpr_var = 0;
|
||||||
extern const int extern_const_var = 0; // expected-warning {{no previous extern declaration}}
|
extern const int extern_const_var = 0; // expected-warning {{no previous extern declaration}}
|
||||||
|
// expected-note@-1{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
extern constexpr int extern_constexpr_var = 0; // expected-warning {{no previous extern declaration}}
|
extern constexpr int extern_constexpr_var = 0; // expected-warning {{no previous extern declaration}}
|
||||||
|
// expected-note@-1{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
|
|
||||||
template<typename> int var_template = 0;
|
template<typename> int var_template = 0;
|
||||||
template<typename> constexpr int const_var_template = 0;
|
template<typename> constexpr int const_var_template = 0;
|
||||||
@ -69,7 +75,9 @@ int use_var_template() { return var_template<int[2]>; }
|
|||||||
template int var_template<int[3]>;
|
template int var_template<int[3]>;
|
||||||
extern template int var_template<int[4]>;
|
extern template int var_template<int[4]>;
|
||||||
template<> int var_template<int[5]>; // expected-warning {{no previous extern declaration}}
|
template<> int var_template<int[5]>; // expected-warning {{no previous extern declaration}}
|
||||||
|
// expected-note@-1{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
|
|
||||||
// FIXME: We give this specialization internal linkage rather than inheriting
|
// FIXME: We give this specialization internal linkage rather than inheriting
|
||||||
// the linkage from the template! We should not warn here.
|
// the linkage from the template! We should not warn here.
|
||||||
template<> int static_var_template<int[5]>; // expected-warning {{no previous extern declaration}}
|
template<> int static_var_template<int[5]>; // expected-warning {{no previous extern declaration}}
|
||||||
|
// expected-note@-1{{declare 'static' if the variable is not intended to be used outside of this translation unit}}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-prototypes %s
|
// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-prototypes %s
|
||||||
|
|
||||||
void f() { } // expected-warning {{no previous prototype for function 'f'}}
|
void f() { } // expected-warning {{no previous prototype for function 'f'}}
|
||||||
|
// expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
|
||||||
|
|
||||||
// Don't warn about kernel functions.
|
// Don't warn about kernel functions.
|
||||||
kernel void g() { }
|
kernel void g() { }
|
||||||
|
Loading…
Reference in New Issue
Block a user