https://github.com/isuckatcs updated 
https://github.com/llvm/llvm-project/pull/161023

>From 51cf252c590d15c7be2ea5a25e7e86ea5e6772c8 Mon Sep 17 00:00:00 2001
From: isuckatcs <[email protected]>
Date: Sat, 27 Sep 2025 22:32:15 +0200
Subject: [PATCH 1/2] [clang-tidy] Portability Avoid Unprototyped Functions
 Check

---
 .../AvoidUnprototypedFunctionsCheck.cpp       | 58 +++++++++++++++
 .../AvoidUnprototypedFunctionsCheck.h         | 33 +++++++++
 .../clang-tidy/portability/CMakeLists.txt     |  1 +
 .../portability/PortabilityTidyModule.cpp     |  3 +
 clang-tools-extra/docs/ReleaseNotes.rst       |  5 ++
 .../docs/clang-tidy/checks/list.rst           |  1 +
 .../avoid-unprototyped-functions.rst          | 73 +++++++++++++++++++
 .../avoid-unprototyped-functions.c            | 32 ++++++++
 8 files changed, 206 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/portability/AvoidUnprototypedFunctionsCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/portability/AvoidUnprototypedFunctionsCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-unprototyped-functions.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/portability/avoid-unprototyped-functions.c

diff --git 
a/clang-tools-extra/clang-tidy/portability/AvoidUnprototypedFunctionsCheck.cpp 
b/clang-tools-extra/clang-tidy/portability/AvoidUnprototypedFunctionsCheck.cpp
new file mode 100644
index 0000000000000..032986471e3e1
--- /dev/null
+++ 
b/clang-tools-extra/clang-tidy/portability/AvoidUnprototypedFunctionsCheck.cpp
@@ -0,0 +1,58 @@
+//===--- AvoidUnprototypedFunctionsCheck.cpp - clang-tidy 
-----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "AvoidUnprototypedFunctionsCheck.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+void AvoidUnprototypedFunctionsCheck::registerMatchers(MatchFinder *Finder) {
+  auto FunctionTypeMatcher =
+      forEachDescendant(functionType(unless(functionProtoType())));
+  
Finder->addMatcher(declaratorDecl(FunctionTypeMatcher).bind("declaratorDecl"),
+                     this);
+  Finder->addMatcher(typedefDecl(FunctionTypeMatcher).bind("typedefDecl"),
+                     this);
+}
+
+void AvoidUnprototypedFunctionsCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  if (const auto *MatchedTypedefDecl =
+          Result.Nodes.getNodeAs<TypedefDecl>("typedefDecl")) {
+    diag(MatchedTypedefDecl->getLocation(),
+         "avoid unprototyped functions in typedef; explicitly add a 'void' "
+         "parameter if the function takes no arguments");
+    return;
+  }
+
+  const auto *MatchedDeclaratorDecl =
+      Result.Nodes.getNodeAs<Decl>("declaratorDecl");
+  if (!MatchedDeclaratorDecl) {
+    return;
+  }
+
+  if (const auto *MatchedFunctionDecl =
+          llvm::dyn_cast<FunctionDecl>(MatchedDeclaratorDecl)) {
+    if (MatchedFunctionDecl->isMain() ||
+        MatchedFunctionDecl->hasWrittenPrototype())
+      return;
+
+    diag(MatchedFunctionDecl->getLocation(),
+         "avoid unprototyped function declarations; explicitly spell out a "
+         "single 'void' parameter if the function takes no argument");
+    return;
+  }
+
+  diag(MatchedDeclaratorDecl->getLocation(),
+       "avoid unprototyped functions in type specifiers; explicitly add a "
+       "'void' parameter if the function takes no arguments");
+}
+
+} // namespace clang::tidy::portability
diff --git 
a/clang-tools-extra/clang-tidy/portability/AvoidUnprototypedFunctionsCheck.h 
b/clang-tools-extra/clang-tidy/portability/AvoidUnprototypedFunctionsCheck.h
new file mode 100644
index 0000000000000..fb89dc6526a24
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/portability/AvoidUnprototypedFunctionsCheck.h
@@ -0,0 +1,33 @@
+//===--- AvoidUnprototypedFunctionsCheck.h - clang-tidy ---------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDUNPROTOTYPEDFUNCTIONSCHECK_H
+#define 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDUNPROTOTYPEDFUNCTIONSCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::portability {
+
+/// Checks if unprototyped function types are used in the source code.
+///
+/// For the user-facing documentation see:
+/// 
http://clang.llvm.org/extra/clang-tidy/checks/portability/avoid-unprototyped-functions.html
+class AvoidUnprototypedFunctionsCheck : public ClangTidyCheck {
+public:
+  AvoidUnprototypedFunctionsCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+    return !LangOpts.CPlusPlus;
+  }
+};
+
+} // namespace clang::tidy::portability
+
+#endif // 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDUNPROTOTYPEDFUNCTIONSCHECK_H
diff --git a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
index 73d74a550afc0..7140469ca1515 100644
--- a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
@@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS
 
 add_clang_library(clangTidyPortabilityModule STATIC
   AvoidPragmaOnceCheck.cpp
+  AvoidUnprototypedFunctionsCheck.cpp
   PortabilityTidyModule.cpp
   RestrictSystemIncludesCheck.cpp
   SIMDIntrinsicsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp 
b/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
index e73e95455d3a5..ee0c64712bacd 100644
--- a/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
@@ -10,6 +10,7 @@
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
 #include "AvoidPragmaOnceCheck.h"
+#include "AvoidUnprototypedFunctionsCheck.h"
 #include "RestrictSystemIncludesCheck.h"
 #include "SIMDIntrinsicsCheck.h"
 #include "StdAllocatorConstCheck.h"
@@ -23,6 +24,8 @@ class PortabilityModule : public ClangTidyModule {
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
     CheckFactories.registerCheck<AvoidPragmaOnceCheck>(
         "portability-avoid-pragma-once");
+    CheckFactories.registerCheck<AvoidUnprototypedFunctionsCheck>(
+        "portability-avoid-unprototyped-functions");
     CheckFactories.registerCheck<RestrictSystemIncludesCheck>(
         "portability-restrict-system-includes");
     CheckFactories.registerCheck<SIMDIntrinsicsCheck>(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 9257dc6b98ba2..9997bb0ac60a7 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -208,6 +208,11 @@ New checks
 
   Detect redundant parentheses.
 
+- New :doc:`portability-avoid-unprototyped-functions
+  <clang-tidy/checks/portability/avoid-unprototyped-functions>` check.
+
+  Checks if unprototyped function types are used in the source code.
+
 New check aliases
 ^^^^^^^^^^^^^^^^^
 
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst 
b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index f94696d4ef9c7..57c4321877e9d 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -362,6 +362,7 @@ Clang-Tidy Checks
    :doc:`performance-unnecessary-copy-initialization 
<performance/unnecessary-copy-initialization>`, "Yes"
    :doc:`performance-unnecessary-value-param 
<performance/unnecessary-value-param>`, "Yes"
    :doc:`portability-avoid-pragma-once <portability/avoid-pragma-once>`,
+   :doc:`portability-avoid-unprototyped-functions 
<portability/avoid-unprototyped-functions>`,
    :doc:`portability-restrict-system-includes 
<portability/restrict-system-includes>`, "Yes"
    :doc:`portability-simd-intrinsics <portability/simd-intrinsics>`,
    :doc:`portability-std-allocator-const <portability/std-allocator-const>`,
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-unprototyped-functions.rst
 
b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-unprototyped-functions.rst
new file mode 100644
index 0000000000000..3d7ed212b61d9
--- /dev/null
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-unprototyped-functions.rst
@@ -0,0 +1,73 @@
+.. title:: clang-tidy - portability-avoid-unprototyped-functions
+
+portability-avoid-unprototyped-functions
+========================================
+
+Checks if unprototyped function types are used in the source code.
+
+For example:
+
+.. code-block:: c
+
+  void foo();         // Bad: unprototyped function declaration
+  void foo(void);     // Good: a function declaration that takes no parameters
+
+  void (*ptr)();      // Bad: pointer to an unprototyped function
+  void (*ptr)(void);  // Good: pointer to a function that takes no parameters
+
+Before C23 ``void foo()`` means a function that takes any number of 
parameters, so the following snippet is valid.
+
+.. code-block:: c
+
+  // -std=c17
+  void foo();
+
+  int main() {
+    foo(1, 2, 3);
+
+    return 0;
+  }
+
+Starting from C23 however, ``void foo()`` means a function that takes no 
parameters, so the same snippet is invalid.
+
+.. code-block:: c
+
+  // -std=c23
+  void foo();
+
+  int main() {
+    foo(1, 2, 3);
+  //    ^ error: too many arguments to function call, expected 0, have 3
+
+    return 0;
+  }
+
+Similarly a pointer to an unprototyped function binds to any function before 
C23, so the following snippet is considered valid.
+
+.. code-block:: c
+
+  // -std=c17
+  void foo(int x, int y);
+
+  int main() {
+    void (*ptr)() = &foo;
+
+    return 0;
+  }
+
+From C23 however, the smae pointer will only bind to functions that take no 
parameters.
+
+.. code-block:: c
+
+  // -std=c23
+  void foo(int x, int y);
+
+  int main() {
+    void (*ptr)() = &foo;
+    //    ^ error: incompatible function pointer types initializing 'void 
(*)(void)' with an expression of type 'void (*)(int, int)'
+
+    return 0;
+  }
+
+Some codebases might explicitly take advantage of the pre-C23 behavior, but 
these codebases should also be aware that
+their solution might not be fully portable between compilers.
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-unprototyped-functions.c
 
b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-unprototyped-functions.c
new file mode 100644
index 0000000000000..0efc029f5c63f
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-unprototyped-functions.c
@@ -0,0 +1,32 @@
+// RUN: %check_clang_tidy %s portability-avoid-unprototyped-functions %t
+struct S {
+  int (*UnprototypedFunctionPtrField)();
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid unprototyped functions in 
type specifiers; explicitly add a 'void' parameter if the function takes no 
arguments
+};
+
+void unprototypedFunction();
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid unprototyped function 
declarations; explicitly spell out a single 'void' parameter if the function 
takes no argument
+
+void unprototypedParamter(int (*UnprototypedFunctionPtrParameter)());
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: avoid unprototyped functions in 
type specifiers; explicitly add a 'void' parameter if the function takes no 
arguments
+
+void unprototypedVariable() {
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid unprototyped function 
declarations; explicitly spell out a single 'void' parameter if the function 
takes no argument
+
+  int (*UnprototypedFunctionPtrVariable)();
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid unprototyped functions in 
type specifiers; explicitly add a 'void' parameter if the function takes no 
arguments
+}
+
+typedef int (*UnprototypedFunctionPtrArray[13])();
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid unprototyped functions in 
typedef; explicitly add a 'void' parameter if the function takes no arguments
+
+void unprototypedTypeAliasParameter(UnprototypedFunctionPtrArray);
+
+#define ANYARG
+
+void unprototypedMacroParameter(ANYARG);
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid unprototyped function 
declarations; explicitly spell out a single 'void' parameter if the function 
takes no argument
+
+void functionWithNoArguments(void);
+
+int main();

>From 776f4eda17fd14977eeb793c392f080f199bee43 Mon Sep 17 00:00:00 2001
From: isuckatcs <[email protected]>
Date: Sun, 28 Sep 2025 14:40:54 +0200
Subject: [PATCH 2/2] [clang-tidy] Add `clang-diagnostic-*` checks that enable
 clang warnings

Prior to this change to enable additional clang diagnostics, one had to
specify extra arguments on either the command line, or in the config
file.

This meant invocations like `clang-tidy ... -- -Wall`, or `clang-tidy
--extra-arg=-Wall ...` as well as config files like the one below.

```
\# .clang-tidy
Checks: ...
ExtraArgs: ["-Wall"]
```

This patch merges this functionality with the commonly used checks
interface, so the invocation for enabling the `-Wall` flag will look
like `clang-tidy --checks="...,clang-diagnostic-all" ...`.
---
 clang-tools-extra/clang-tidy/ClangTidy.cpp | 51 ++++++++++++++++++----
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp 
b/clang-tools-extra/clang-tidy/ClangTidy.cpp
index 7e18f3806a143..1afb3aadfdb1e 100644
--- a/clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -20,6 +20,7 @@
 #include "ClangTidyModuleRegistry.h"
 #include "ClangTidyProfiling.h"
 #include "ExpandModularHeadersPPCallbacks.h"
+#include "GlobList.h"
 #include "clang-tidy-config.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
@@ -563,6 +564,16 @@ runClangTidy(clang::tidy::ClangTidyContext &Context,
   ClangTool Tool(Compilations, InputFiles,
                  std::make_shared<PCHContainerOperations>(), BaseFS);
 
+  Context.setEnableProfiling(EnableCheckProfile);
+  Context.setProfileStoragePrefix(StoreCheckProfile);
+
+  ClangTidyDiagnosticConsumer DiagConsumer(Context, nullptr, true, 
ApplyAnyFix);
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(DiagnosticIDs::create(), *DiagOpts, &DiagConsumer,
+                       /*ShouldOwnClient=*/false);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
+  Tool.setDiagnosticConsumer(&DiagConsumer);
+
   // Add extra arguments passed by the clang-tidy command-line.
   ArgumentsAdjuster PerFileExtraArgumentsInserter =
       [&Context](const CommandLineArguments &Args, StringRef Filename) {
@@ -581,17 +592,39 @@ runClangTidy(clang::tidy::ClangTidyContext &Context,
         return AdjustedArgs;
       };
 
+  // Add extra arguments passed by clang-diagnostic-* checks.
+  ArgumentsAdjuster ClangDiagnosticArgumentsInserter =
+      [&Context, &DE](const CommandLineArguments &Args, StringRef Filename) {
+        ClangTidyOptions Opts = Context.getOptionsForFile(Filename);
+        if (!Opts.Checks)
+          return Args;
+
+        CommandLineArguments AdjustedArgs = Args;
+        llvm::StringRef AdjustedChecks = *Opts.Checks;
+
+        // By default the list starts with 'clang-diagnostic-*' and
+        // 'clang-analyzer-*', but these are not user specified, so we remove
+        // them.
+        AdjustedChecks.consume_front("clang-diagnostic-*,clang-analyzer-*");
+        if (AdjustedChecks.starts_with(','))
+          AdjustedChecks = AdjustedChecks.drop_front(1);
+
+        CachedGlobList Filter(AdjustedChecks);
+        for (StringRef Flag : DE.getDiagnosticIDs()->getDiagnosticFlags()) {
+          if (Flag.starts_with("-Wno"))
+            continue;
+
+          if (Filter.contains(
+                  (Twine("clang-diagnostic-") + Flag.drop_front(2)).str()))
+            AdjustedArgs.insert(AdjustedArgs.end(), "-Wstrict-prototypes");
+        }
+
+        return AdjustedArgs;
+      };
+
   Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter);
+  Tool.appendArgumentsAdjuster(ClangDiagnosticArgumentsInserter);
   Tool.appendArgumentsAdjuster(getStripPluginsAdjuster());
-  Context.setEnableProfiling(EnableCheckProfile);
-  Context.setProfileStoragePrefix(StoreCheckProfile);
-
-  ClangTidyDiagnosticConsumer DiagConsumer(Context, nullptr, true, 
ApplyAnyFix);
-  auto DiagOpts = std::make_unique<DiagnosticOptions>();
-  DiagnosticsEngine DE(DiagnosticIDs::create(), *DiagOpts, &DiagConsumer,
-                       /*ShouldOwnClient=*/false);
-  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
-  Tool.setDiagnosticConsumer(&DiagConsumer);
 
   class ActionFactory : public FrontendActionFactory {
   public:

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to