https://github.com/PlutoDog95 created 
https://github.com/llvm/llvm-project/pull/196593

This patch suppresses `-Wunneeded-internal-declaration` for referenced 
`constexpr` functions used during constant evaluation.

`constexpr` variables already receive similar handling in 
`ShouldRemoveFromUnused()` because they may participate in constant expression 
evaluation without being odr-used. Referenced `constexpr` functions currently 
lack equivalent handling, which can produce false positives in cases such as 
dependent return type evaluation.

Add analogous handling for referenced `constexpr` functions and include a 
regression test.

Fixes #196564 


>From a488e1500568f16ad796e1b331c402f6d0dd7190 Mon Sep 17 00:00:00 2001
From: Vineet Agarwal <[email protected]>
Date: Thu, 7 May 2026 19:29:58 +0530
Subject: [PATCH 1/2] [analyzer] Suppress EnumCastOutOfRange diagnostics in
 system headers

Suppress EnumCastOutOfRange warnings emitted from system headers.

The checker already receives locations correctly classified as system
headers by SourceManager, but it did not suppress diagnostics for them.
This caused warnings to be emitted from libraries included through
-isystem, such as Boost.Regex.

Add a system-header guard in reportWarning() and add a regression test.

Signed-off-by: Vineet Agarwal <[email protected]>
---
 .../Checkers/EnumCastOutOfRangeChecker.cpp           | 10 +++++++---
 clang/test/Analysis/Inputs/enum-system-header.h      |  8 ++++++++
 .../enum-cast-out-of-range-system-header.cpp         | 12 ++++++++++++
 3 files changed, 27 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Analysis/Inputs/enum-system-header.h
 create mode 100644 clang/test/Analysis/enum-cast-out-of-range-system-header.cpp

diff --git a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
index 76a1470aaac44..32a73a1d5c44f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
@@ -85,8 +85,13 @@ void EnumCastOutOfRangeChecker::reportWarning(CheckerContext 
&C,
                                               const CastExpr *CE,
                                               const EnumDecl *E) const {
   assert(E && "valid EnumDecl* is expected");
-  if (const ExplodedNode *N = C.generateNonFatalErrorNode()) {
-    std::string ValueStr = "", NameStr = "the enum";
+    auto &SM = C.getSourceManager();
+
+    if (SM.isInSystemHeader(CE->getExprLoc()))
+      return;
+
+    if (const ExplodedNode *N = C.generateNonFatalErrorNode()) {
+      std::string ValueStr = "", NameStr = "the enum";
 
     // Try to add details to the message:
     const auto ConcreteValue =
@@ -101,7 +106,6 @@ void 
EnumCastOutOfRangeChecker::reportWarning(CheckerContext &C,
     std::string Msg = formatv("The value{0} provided to the cast expression is 
"
                               "not in the valid range of values for {1}",
                               ValueStr, NameStr);
-
     auto BR = std::make_unique<PathSensitiveBugReport>(EnumValueCastOutOfRange,
                                                        Msg, N);
     bugreporter::trackExpressionValue(N, CE->getSubExpr(), *BR);
diff --git a/clang/test/Analysis/Inputs/enum-system-header.h 
b/clang/test/Analysis/Inputs/enum-system-header.h
new file mode 100644
index 0000000000000..53c6bdac24093
--- /dev/null
+++ b/clang/test/Analysis/Inputs/enum-system-header.h
@@ -0,0 +1,8 @@
+enum MyEnum {
+  A = 1,
+  B = 2
+};
+
+static inline MyEnum bad_cast(int x) {
+  return (MyEnum)x;
+}
diff --git a/clang/test/Analysis/enum-cast-out-of-range-system-header.cpp 
b/clang/test/Analysis/enum-cast-out-of-range-system-header.cpp
new file mode 100644
index 0000000000000..073cde677bcd1
--- /dev/null
+++ b/clang/test/Analysis/enum-cast-out-of-range-system-header.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:   -analyzer-checker=core,optin.core.EnumCastOutOfRange \
+// RUN:   -isystem %S/Inputs \
+// RUN:   -verify %s
+
+#include "enum-system-header.h"
+
+void test() {
+  bad_cast(100);
+}
+
+// expected-no-diagnostics

>From 22dddcd7360ab0ad47a3b8342fb863479d345a9c Mon Sep 17 00:00:00 2001
From: Vineet Agarwal <[email protected]>
Date: Fri, 8 May 2026 22:56:40 +0530
Subject: [PATCH 2/2] [clang] Suppress -Wunneeded-internal-declaration for
 referenced constexpr functions

Referenced constexpr functions used during constant evaluation may not
be odr-used and therefore do not require emission, but they are still
semantically necessary.

Suppress -Wunneeded-internal-declaration for referenced constexpr
functions, analogous to the existing handling for variables usable in
constant expressions.

Add a regression test for constexpr function usage in a dependent return
type.
---
 clang/lib/Sema/Sema.cpp                       |  5 ++++
 .../warn-unused-constexpr-function.cpp        | 24 +++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 clang/test/SemaCXX/warn-unused-constexpr-function.cpp

diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 8a68f2f19bf3d..9c8a84668454a 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -891,6 +891,11 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const 
DeclaratorDecl *D) {
     return true;
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // If a constexpr function is referenced for constant evaluation,
+    // don't warn even if it is not odr-used.
+    if (FD->isReferenced() && FD->isConstexpr())
+      return true;
+
     // If this is a function template and none of its specializations is used,
     // we should warn.
     if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate())
diff --git a/clang/test/SemaCXX/warn-unused-constexpr-function.cpp 
b/clang/test/SemaCXX/warn-unused-constexpr-function.cpp
new file mode 100644
index 0000000000000..329cfe954c1a6
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unused-constexpr-function.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++14 -Wunused-function -fsyntax-only %s
+
+static constexpr bool returnInt(int) { return true; }
+
+template <bool B>
+struct select;
+
+template <>
+struct select<true> {
+  using type = int;
+};
+
+template <>
+struct select<false> {
+  using type = float;
+};
+
+template <typename T>
+typename select<returnInt(T{})>::type make() {
+  return T{};
+}
+
+int makeInt() { return make<int>(); }
+float makeFloat() { return make<float>(); }

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

Reply via email to