llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Vineet Agarwal (PlutoDog95)

<details>
<summary>Changes</summary>

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 


---
Full diff: https://github.com/llvm/llvm-project/pull/196593.diff


5 Files Affected:

- (modified) clang/lib/Sema/Sema.cpp (+5) 
- (modified) clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp 
(+7-3) 
- (added) clang/test/Analysis/Inputs/enum-system-header.h (+8) 
- (added) clang/test/Analysis/enum-cast-out-of-range-system-header.cpp (+12) 
- (added) clang/test/SemaCXX/warn-unused-constexpr-function.cpp (+24) 


``````````diff
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/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
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>(); }

``````````

</details>


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

Reply via email to