Disable -Wmissing-prototypes for internal linkage functions that aren't explicitly marked "static"

Some functions can end up non-externally visible despite not being
declared "static" or in an unnamed namespace in C++ - such as by having
parameters that are of non-external types.

Such functions aren't mistakenly intended to be defining some function
that needs a declaration. They could be maybe more legible (except for
the operator new example) with an explicit static, but that's a
stylistic thing outside what should be addressed by a warning.

This reapplies 275c56226d - once we figure
out what to do about the change in behavior for -Wnon-c-typedef-for-linkage
(this reverts the revert commit 85ee1d3ca1)

Differential Revision: https://reviews.llvm.org/D121328
This commit is contained in:
David Blaikie 2022-03-09 21:13:31 +00:00
parent a5032b2633
commit 34b9b1ea48
3 changed files with 24 additions and 0 deletions

View File

@ -14233,6 +14233,11 @@ ShouldWarnAboutMissingPrototype(const FunctionDecl *FD,
if (FD->isDeleted())
return false;
// Don't warn on implicitly local functions (such as having local-typed
// parameters).
if (!FD->isExternallyVisible())
return false;
for (const FunctionDecl *Prev = FD->getPreviousDecl();
Prev; Prev = Prev->getPreviousDecl()) {
// Ignore any declarations that occur in function or method

View File

@ -183,3 +183,9 @@ namespace BuiltinName {
void memcpy(); // expected-note {{due to this member}}
} A; // expected-note {{given name 'A' for linkage purposes by this typedef}}
}
namespace inline_defined_static_member {
typedef struct { // expected-warning {{anonymous non-C-compatible type}}
static void f() { // expected-note {{due to this member}}
}
} A; // expected-note {{given name 'A' for linkage purposes by this typedef}}
}

View File

@ -44,3 +44,16 @@ 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]]:{{.*}}}:"{{.*}}"
namespace {
struct anon { };
}
// No warning because this has internal linkage despite not being declared
// explicitly 'static', owing to the internal linkage parameter.
void l(anon) {
}
void *operator new(decltype(sizeof(3)) size, const anon &) throw() {
return nullptr;
}