forked from OSchip/llvm-project
Implement -Wmissing-prototypes. Fixes PR3911.
llvm-svn: 68110
This commit is contained in:
parent
9277379fc0
commit
f1b876d5de
|
@ -670,6 +670,9 @@ public:
|
||||||
/// external, C linkage.
|
/// external, C linkage.
|
||||||
bool isExternC(ASTContext &Context) const;
|
bool isExternC(ASTContext &Context) const;
|
||||||
|
|
||||||
|
/// \brief Determines whether this is a global function.
|
||||||
|
bool isGlobal() const;
|
||||||
|
|
||||||
/// getPreviousDeclaration - Return the previous declaration of this
|
/// getPreviousDeclaration - Return the previous declaration of this
|
||||||
/// function.
|
/// function.
|
||||||
const FunctionDecl *getPreviousDeclaration() const {
|
const FunctionDecl *getPreviousDeclaration() const {
|
||||||
|
|
|
@ -712,6 +712,7 @@ def warn_deprecated : Warning<"%0 is deprecated">;
|
||||||
def warn_unavailable : Warning<"%0 is unavailable">;
|
def warn_unavailable : Warning<"%0 is unavailable">;
|
||||||
def note_unavailable_here : Note<
|
def note_unavailable_here : Note<
|
||||||
"function has been explicitly marked %select{unavailable|deleted}0 here">;
|
"function has been explicitly marked %select{unavailable|deleted}0 here">;
|
||||||
|
def warn_missing_prototype : Warning<"no previous prototype for function %0">;
|
||||||
def err_redefinition : Error<"redefinition of %0">;
|
def err_redefinition : Error<"redefinition of %0">;
|
||||||
def err_static_non_static : Error<
|
def err_static_non_static : Error<
|
||||||
"static declaration of %0 follows non-static declaration">;
|
"static declaration of %0 follows non-static declaration">;
|
||||||
|
|
|
@ -276,12 +276,14 @@ OPTION("-Winline", Winline, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wint-to-pointer-cast", Wint_to_pointer_cast, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
OPTION("-Wint-to-pointer-cast", Wint_to_pointer_cast, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wl,", Wl_COMMA, CommaJoined, INVALID, INVALID, "li", 0)
|
OPTION("-Wl,", Wl_COMMA, CommaJoined, INVALID, INVALID, "li", 0)
|
||||||
OPTION("-Wmissing-braces", Wmissing_braces, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
OPTION("-Wmissing-braces", Wmissing_braces, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
||||||
|
OPTION("-Wmissing-prototypes", Wmissing_prototypes, Flag, clang_W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wmost", Wmost, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
OPTION("-Wmost", Wmost, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wnested-externs", Wnested_externs, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
OPTION("-Wnested-externs", Wnested_externs, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wno-format-nonliteral", Wno_format_nonliteral, Flag, clang_W_Group, INVALID, "", 0)
|
OPTION("-Wno-format-nonliteral", Wno_format_nonliteral, Flag, clang_W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wno-format-y2k", Wno_format_y2k, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
OPTION("-Wno-format-y2k", Wno_format_y2k, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wno-four-char-constants", Wno_four_char_constants, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
OPTION("-Wno-four-char-constants", Wno_four_char_constants, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wno-missing-field-initializers", Wno_missing_field_initializers, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
OPTION("-Wno-missing-field-initializers", Wno_missing_field_initializers, Flag, clang_ignored_W_Group, INVALID, "", 0)
|
||||||
|
OPTION("-Wno-missing-prototypes", Wno_missing_prototypes, Flag, clang_W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wno-nonportable-cfstrings", Wno_nonportable_cfstrings, Joined, W_Group, INVALID, "", 0)
|
OPTION("-Wno-nonportable-cfstrings", Wno_nonportable_cfstrings, Joined, W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wno-pointer-sign", Wno_pointer_sign, Flag, clang_W_Group, INVALID, "", 0)
|
OPTION("-Wno-pointer-sign", Wno_pointer_sign, Flag, clang_W_Group, INVALID, "", 0)
|
||||||
OPTION("-Wno-strict-selector-match", Wno_strict_selector_match, Flag, clang_W_Group, INVALID, "", 0)
|
OPTION("-Wno-strict-selector-match", Wno_strict_selector_match, Flag, clang_W_Group, INVALID, "", 0)
|
||||||
|
|
|
@ -341,6 +341,26 @@ bool FunctionDecl::isExternC(ASTContext &Context) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FunctionDecl::isGlobal() const {
|
||||||
|
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this))
|
||||||
|
return Method->isStatic();
|
||||||
|
|
||||||
|
if (getStorageClass() == Static)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (const DeclContext *DC = getDeclContext();
|
||||||
|
DC->isNamespace();
|
||||||
|
DC = DC->getParent()) {
|
||||||
|
if (const NamespaceDecl *Namespace = cast<NamespaceDecl>(DC)) {
|
||||||
|
if (!Namespace->getDeclName())
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Returns a value indicating whether this function
|
/// \brief Returns a value indicating whether this function
|
||||||
/// corresponds to a builtin function.
|
/// corresponds to a builtin function.
|
||||||
///
|
///
|
||||||
|
|
|
@ -2741,6 +2741,28 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
|
||||||
diag::err_func_def_incomplete_result))
|
diag::err_func_def_incomplete_result))
|
||||||
FD->setInvalidDecl();
|
FD->setInvalidDecl();
|
||||||
|
|
||||||
|
// GNU warning -Wmissing-prototypes:
|
||||||
|
// Warn if a global function is defined without a previous
|
||||||
|
// prototype declaration. This warning is issued even if the
|
||||||
|
// definition itself provides a prototype. The aim is to detect
|
||||||
|
// global functions that fail to be declared in header files.
|
||||||
|
if (!FD->isInvalidDecl() && FD->isGlobal() && !isa<CXXMethodDecl>(FD)) {
|
||||||
|
bool MissingPrototype = true;
|
||||||
|
for (const FunctionDecl *Prev = FD->getPreviousDeclaration();
|
||||||
|
Prev; Prev = Prev->getPreviousDeclaration()) {
|
||||||
|
// Ignore any declarations that occur in function or method
|
||||||
|
// scope, because they aren't visible from the header.
|
||||||
|
if (Prev->getDeclContext()->isFunctionOrMethod())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MissingPrototype = !Prev->getType()->isFunctionProtoType();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MissingPrototype)
|
||||||
|
Diag(FD->getLocation(), diag::warn_missing_prototype) << FD;
|
||||||
|
}
|
||||||
|
|
||||||
PushDeclContext(FnBodyScope, FD);
|
PushDeclContext(FnBodyScope, FD);
|
||||||
|
|
||||||
// Check the validity of our function parameters
|
// Check the validity of our function parameters
|
||||||
|
|
|
@ -140,6 +140,9 @@ static const diag::kind PointerSignDiags[] = {
|
||||||
diag::ext_typecheck_convert_incompatible_pointer_sign
|
diag::ext_typecheck_convert_incompatible_pointer_sign
|
||||||
};
|
};
|
||||||
static const diag::kind DeprecatedDeclarations[] = { diag::warn_deprecated };
|
static const diag::kind DeprecatedDeclarations[] = { diag::warn_deprecated };
|
||||||
|
static const diag::kind MissingPrototypesDiags[] = {
|
||||||
|
diag::warn_missing_prototype
|
||||||
|
};
|
||||||
|
|
||||||
// Hmm ... this option is currently actually completely ignored.
|
// Hmm ... this option is currently actually completely ignored.
|
||||||
//static const diag::kind StrictSelectorMatchDiags[] = { };
|
//static const diag::kind StrictSelectorMatchDiags[] = { };
|
||||||
|
@ -149,6 +152,7 @@ static const WarningOption OptionTable[] = {
|
||||||
{ "float-equal", DIAGS(FloatEqualDiags) },
|
{ "float-equal", DIAGS(FloatEqualDiags) },
|
||||||
{ "format-nonliteral", DIAGS(FormatNonLiteralDiags) },
|
{ "format-nonliteral", DIAGS(FormatNonLiteralDiags) },
|
||||||
{ "implicit-function-declaration", DIAGS(ImplicitFunctionDeclarationDiags) },
|
{ "implicit-function-declaration", DIAGS(ImplicitFunctionDeclarationDiags) },
|
||||||
|
{ "missing-prototypes", DIAGS(MissingPrototypesDiags) },
|
||||||
{ "pointer-sign", DIAGS(PointerSignDiags) },
|
{ "pointer-sign", DIAGS(PointerSignDiags) },
|
||||||
{ "readonly-setter-attrs", DIAGS(ReadOnlySetterAttrsDiags) },
|
{ "readonly-setter-attrs", DIAGS(ReadOnlySetterAttrsDiags) },
|
||||||
{ "undef", DIAGS(UndefDiags) },
|
{ "undef", DIAGS(UndefDiags) },
|
||||||
|
@ -179,6 +183,7 @@ bool ProcessWarningOptions(Diagnostic &Diags) {
|
||||||
Diags.setDiagnosticMapping(diag::err_pp_file_not_found, diag::MAP_FATAL);
|
Diags.setDiagnosticMapping(diag::err_pp_file_not_found, diag::MAP_FATAL);
|
||||||
Diags.setDiagnosticMapping(diag::err_template_recursion_depth_exceeded,
|
Diags.setDiagnosticMapping(diag::err_template_recursion_depth_exceeded,
|
||||||
diag::MAP_FATAL);
|
diag::MAP_FATAL);
|
||||||
|
Diags.setDiagnosticMapping(diag::warn_missing_prototype, diag::MAP_IGNORE);
|
||||||
Diags.setSuppressSystemWarnings(!OptWarnInSystemHeaders);
|
Diags.setSuppressSystemWarnings(!OptWarnInSystemHeaders);
|
||||||
|
|
||||||
for (OptionsList::iterator it = Options.begin(), e = Options.end();
|
for (OptionsList::iterator it = Options.begin(), e = Options.end();
|
||||||
|
|
Loading…
Reference in New Issue