Author: Aaron Ballman Date: 2022-10-06T10:08:23-04:00 New Revision: f7170500cf10ea9d685eb655c76a7c393fb18708
URL: https://github.com/llvm/llvm-project/commit/f7170500cf10ea9d685eb655c76a7c393fb18708 DIFF: https://github.com/llvm/llvm-project/commit/f7170500cf10ea9d685eb655c76a7c393fb18708.diff LOG: 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 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaDecl.cpp clang/test/Sema/warn-deprecated-non-prototype.c Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 1652c90337f6e..a1aea7e2753d8 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -231,6 +231,10 @@ Improvements to Clang's diagnostics be selected. - Add a fix-it hint for the ``-Wdefaulted-function-deleted`` warning to 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 ------------------------------------------------- diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 8e7a989219da6..60b8d1c3c59c7 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14657,6 +14657,21 @@ void Sema::ActOnFinishInlineFunctionDef(FunctionDecl *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 ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, const FunctionDecl *&PossiblePrototype) { @@ -14703,16 +14718,9 @@ ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, if (!FD->isExternallyVisible()) return false; - 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()->isFunctionNoProtoType(); - } + // If we were able to find a potential prototype, don't warn. + if (FindPossiblePrototype(FD, PossiblePrototype)) + return false; 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 // need to diagnose it as changing behavior in C2x because we now know // whether the function accepts arguments or not. This only handles the diff --git a/clang/test/Sema/warn-deprecated-non-prototype.c b/clang/test/Sema/warn-deprecated-non-prototype.c index 351745e49069f..47994934baed6 100644 --- a/clang/test/Sema/warn-deprecated-non-prototype.c +++ b/clang/test/Sema/warn-deprecated-non-prototype.c @@ -105,3 +105,14 @@ void calls(void) { func(1, 2); // OK 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; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits