[clang] f717050 - Silence a duplicate diagnostic about K&R C function definitions

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 6 07:08:35 PDT 2022


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;
+}


        


More information about the cfe-commits mailing list