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
