Skip to content

Commit f717050

Browse files
committed
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
1 parent 364003e commit f717050

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ Improvements to Clang's diagnostics
231231
be selected.
232232
- Add a fix-it hint for the ``-Wdefaulted-function-deleted`` warning to
233233
explicitly delete the function.
234+
- Fixed an accidental duplicate diagnostic involving the declaration of a
235+
function definition without a prototype which is preceded by a static
236+
declaration of the function with a prototype. Fixes
237+
`Issue 58181 <https://github.com/llvm/llvm-project/issues/58181>`_.
234238

235239
Non-comprehensive list of changes in this release
236240
-------------------------------------------------

clang/lib/Sema/SemaDecl.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14657,6 +14657,21 @@ void Sema::ActOnFinishInlineFunctionDef(FunctionDecl *D) {
1465714657
Consumer.HandleInlineFunctionDefinition(D);
1465814658
}
1465914659

14660+
static bool FindPossiblePrototype(const FunctionDecl *FD,
14661+
const FunctionDecl *&PossiblePrototype) {
14662+
for (const FunctionDecl *Prev = FD->getPreviousDecl(); Prev;
14663+
Prev = Prev->getPreviousDecl()) {
14664+
// Ignore any declarations that occur in function or method
14665+
// scope, because they aren't visible from the header.
14666+
if (Prev->getLexicalDeclContext()->isFunctionOrMethod())
14667+
continue;
14668+
14669+
PossiblePrototype = Prev;
14670+
return Prev->getType()->isFunctionProtoType();
14671+
}
14672+
return false;
14673+
}
14674+
1466014675
static bool
1466114676
ShouldWarnAboutMissingPrototype(const FunctionDecl *FD,
1466214677
const FunctionDecl *&PossiblePrototype) {
@@ -14703,16 +14718,9 @@ ShouldWarnAboutMissingPrototype(const FunctionDecl *FD,
1470314718
if (!FD->isExternallyVisible())
1470414719
return false;
1470514720

14706-
for (const FunctionDecl *Prev = FD->getPreviousDecl();
14707-
Prev; Prev = Prev->getPreviousDecl()) {
14708-
// Ignore any declarations that occur in function or method
14709-
// scope, because they aren't visible from the header.
14710-
if (Prev->getLexicalDeclContext()->isFunctionOrMethod())
14711-
continue;
14712-
14713-
PossiblePrototype = Prev;
14714-
return Prev->getType()->isFunctionNoProtoType();
14715-
}
14721+
// If we were able to find a potential prototype, don't warn.
14722+
if (FindPossiblePrototype(FD, PossiblePrototype))
14723+
return false;
1471614724

1471714725
return true;
1471814726
}
@@ -15280,6 +15288,12 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
1528015288
}
1528115289
}
1528215290

15291+
// We might not have found a prototype because we didn't wish to warn on
15292+
// the lack of a missing prototype. Try again without the checks for
15293+
// whether we want to warn on the missing prototype.
15294+
if (!PossiblePrototype)
15295+
(void)FindPossiblePrototype(FD, PossiblePrototype);
15296+
1528315297
// If the function being defined does not have a prototype, then we may
1528415298
// need to diagnose it as changing behavior in C2x because we now know
1528515299
// whether the function accepts arguments or not. This only handles the

clang/test/Sema/warn-deprecated-non-prototype.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,14 @@ void calls(void) {
105105
func(1, 2); // OK
106106
func(1, 2, 3); // both-warning {{too many arguments in call to 'func'}}
107107
}
108+
109+
// Issue 58181 -- we would issue the warning about the function without a
110+
// prototype twice when the function was declared static in the following
111+
// example.
112+
static int GH58181(int x, int y);
113+
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}}
114+
int x;
115+
int y;
116+
{
117+
return x + y;
118+
}

0 commit comments

Comments
 (0)