forked from OSchip/llvm-project
Silence a duplicate diagnostic about K&R C function definitions
We would issue the same diagnostic twice in the case that the K&R C function definition is preceded by a static declaration of the function with a prototype. Fixes #58181
This commit is contained in:
parent
364003e2da
commit
f7170500cf
|
@ -231,6 +231,10 @@ Improvements to Clang's diagnostics
|
||||||
be selected.
|
be selected.
|
||||||
- Add a fix-it hint for the ``-Wdefaulted-function-deleted`` warning to
|
- Add a fix-it hint for the ``-Wdefaulted-function-deleted`` warning to
|
||||||
explicitly delete the function.
|
explicitly delete the function.
|
||||||
|
- Fixed an accidental duplicate diagnostic involving the declaration of a
|
||||||
|
function definition without a prototype which is preceded by a static
|
||||||
|
declaration of the function with a prototype. Fixes
|
||||||
|
`Issue 58181 <https://github.com/llvm/llvm-project/issues/58181>`_.
|
||||||
|
|
||||||
Non-comprehensive list of changes in this release
|
Non-comprehensive list of changes in this release
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
|
|
@ -14657,6 +14657,21 @@ void Sema::ActOnFinishInlineFunctionDef(FunctionDecl *D) {
|
||||||
Consumer.HandleInlineFunctionDefinition(D);
|
Consumer.HandleInlineFunctionDefinition(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool FindPossiblePrototype(const FunctionDecl *FD,
|
||||||
|
const FunctionDecl *&PossiblePrototype) {
|
||||||
|
for (const FunctionDecl *Prev = FD->getPreviousDecl(); Prev;
|
||||||
|
Prev = Prev->getPreviousDecl()) {
|
||||||
|
// Ignore any declarations that occur in function or method
|
||||||
|
// scope, because they aren't visible from the header.
|
||||||
|
if (Prev->getLexicalDeclContext()->isFunctionOrMethod())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PossiblePrototype = Prev;
|
||||||
|
return Prev->getType()->isFunctionProtoType();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ShouldWarnAboutMissingPrototype(const FunctionDecl *FD,
|
ShouldWarnAboutMissingPrototype(const FunctionDecl *FD,
|
||||||
const FunctionDecl *&PossiblePrototype) {
|
const FunctionDecl *&PossiblePrototype) {
|
||||||
|
@ -14703,16 +14718,9 @@ ShouldWarnAboutMissingPrototype(const FunctionDecl *FD,
|
||||||
if (!FD->isExternallyVisible())
|
if (!FD->isExternallyVisible())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (const FunctionDecl *Prev = FD->getPreviousDecl();
|
// If we were able to find a potential prototype, don't warn.
|
||||||
Prev; Prev = Prev->getPreviousDecl()) {
|
if (FindPossiblePrototype(FD, PossiblePrototype))
|
||||||
// Ignore any declarations that occur in function or method
|
return false;
|
||||||
// scope, because they aren't visible from the header.
|
|
||||||
if (Prev->getLexicalDeclContext()->isFunctionOrMethod())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PossiblePrototype = Prev;
|
|
||||||
return Prev->getType()->isFunctionNoProtoType();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -15280,6 +15288,12 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We might not have found a prototype because we didn't wish to warn on
|
||||||
|
// the lack of a missing prototype. Try again without the checks for
|
||||||
|
// whether we want to warn on the missing prototype.
|
||||||
|
if (!PossiblePrototype)
|
||||||
|
(void)FindPossiblePrototype(FD, PossiblePrototype);
|
||||||
|
|
||||||
// If the function being defined does not have a prototype, then we may
|
// If the function being defined does not have a prototype, then we may
|
||||||
// need to diagnose it as changing behavior in C2x because we now know
|
// need to diagnose it as changing behavior in C2x because we now know
|
||||||
// whether the function accepts arguments or not. This only handles the
|
// whether the function accepts arguments or not. This only handles the
|
||||||
|
|
|
@ -105,3 +105,14 @@ void calls(void) {
|
||||||
func(1, 2); // OK
|
func(1, 2); // OK
|
||||||
func(1, 2, 3); // both-warning {{too many arguments in call to 'func'}}
|
func(1, 2, 3); // both-warning {{too many arguments in call to 'func'}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 58181 -- we would issue the warning about the function without a
|
||||||
|
// prototype twice when the function was declared static in the following
|
||||||
|
// example.
|
||||||
|
static int GH58181(int x, int y);
|
||||||
|
static int GH58181(x, y) // both-warning {{a function definition without a prototype is deprecated in all versions of C and is not supported in C2x}}
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
{
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue