llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tools-extra Author: Prabhu Rajasekaran (Prabhuk) <details> <summary>Changes</summary> Static variables in constexpr functions create a warning in Clang and is currently an error in GCC. Add a clang tidy check to catch such cases to prevent these cases slipping through in libcxx code. --- Full diff: https://github.com/llvm/llvm-project/pull/175814.diff 7 Files Affected: - (modified) clang-tools-extra/clang-tidy/misc/CMakeLists.txt (+1) - (modified) clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp (+3) - (added) clang-tools-extra/clang-tidy/misc/StaticInConstexprCheck.cpp (+39) - (added) clang-tools-extra/clang-tidy/misc/StaticInConstexprCheck.h (+33) - (added) clang-tools-extra/docs/clang-tidy/checks/misc/static-in-constexpr.rst (+6) - (added) clang-tools-extra/test/clang-tidy/checkers/misc/static-in-constexpr.cpp (+40) - (modified) libcxx/.clang-tidy (+1) ``````````diff diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt index e34b0cf687be3..bb11f5c5836e1 100644 --- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt @@ -38,6 +38,7 @@ add_clang_library(clangTidyMiscModule STATIC PredictableRandCheck.cpp RedundantExpressionCheck.cpp StaticAssertCheck.cpp + StaticInConstexprCheck.cpp ThrowByValueCatchByReferenceCheck.cpp UnconventionalAssignOperatorCheck.cpp UniqueptrResetReleaseCheck.cpp diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp index f8550b30b9789..3918c70f4fb9a 100644 --- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp @@ -27,6 +27,7 @@ #include "PredictableRandCheck.h" #include "RedundantExpressionCheck.h" #include "StaticAssertCheck.h" +#include "StaticInConstexprCheck.h" #include "ThrowByValueCatchByReferenceCheck.h" #include "UnconventionalAssignOperatorCheck.h" #include "UniqueptrResetReleaseCheck.h" @@ -76,6 +77,8 @@ class MiscModule : public ClangTidyModule { CheckFactories.registerCheck<RedundantExpressionCheck>( "misc-redundant-expression"); CheckFactories.registerCheck<StaticAssertCheck>("misc-static-assert"); + CheckFactories.registerCheck<StaticInConstexprCheck>( + "misc-static-in-constexpr"); CheckFactories.registerCheck<ThrowByValueCatchByReferenceCheck>( "misc-throw-by-value-catch-by-reference"); CheckFactories.registerCheck<UnconventionalAssignOperatorCheck>( diff --git a/clang-tools-extra/clang-tidy/misc/StaticInConstexprCheck.cpp b/clang-tools-extra/clang-tidy/misc/StaticInConstexprCheck.cpp new file mode 100644 index 0000000000000..5427f7e80cd33 --- /dev/null +++ b/clang-tools-extra/clang-tidy/misc/StaticInConstexprCheck.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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 "StaticInConstexprCheck.h" +#include "clang/AST/Decl.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::misc { + +void StaticInConstexprCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(varDecl(isStaticLocal()).bind("var"), this); +} + +void StaticInConstexprCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var"); + const DeclContext *DC = Var->getDeclContext(); + + while (DC && !DC->isFunctionOrMethod()) + DC = DC->getParent(); + + const auto *FD = dyn_cast_or_null<FunctionDecl>(DC); + if (!FD) + return; + + if (FD->isConstexpr()) { + diag(Var->getLocation(), + "variable of static or thread storage duration inside constexpr " + "function"); + } +} + +} // namespace clang::tidy::misc \ No newline at end of file diff --git a/clang-tools-extra/clang-tidy/misc/StaticInConstexprCheck.h b/clang-tools-extra/clang-tidy/misc/StaticInConstexprCheck.h new file mode 100644 index 0000000000000..862255c9eeb1d --- /dev/null +++ b/clang-tools-extra/clang-tidy/misc/StaticInConstexprCheck.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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_MISC_STATICINCONSTEXPRCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_STATICINCONSTEXPRCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::misc { + +/// Checks for static variables declared inside constexpr functions. +/// +/// For the user-facing documentation see: +/// https://clang.llvm.org/extra/clang-tidy/checks/misc/static-in-constexpr.html +class StaticInConstexprCheck : public ClangTidyCheck { +public: + StaticInConstexprCheck(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::misc + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_STATICINCONSTEXPRCHECK_H diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/static-in-constexpr.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/static-in-constexpr.rst new file mode 100644 index 0000000000000..4aeaa4e661866 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/static-in-constexpr.rst @@ -0,0 +1,6 @@ +.. title:: clang-tidy - misc-static-in-constexpr + +misc-static-in-constexpr +======================== + +FIXME: Describe what patterns does the check detect and why. Give examples. diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/static-in-constexpr.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/static-in-constexpr.cpp new file mode 100644 index 0000000000000..6e4e5f458f8b3 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/static-in-constexpr.cpp @@ -0,0 +1,40 @@ +// RUN: %check_clang_tidy -std=c++23 %s misc-static-in-constexpr %t + +void normal_func() { + static int x = 0; + thread_local int y = 0; +} + +constexpr void constexpr_func() { + static int x = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: variable of static or thread storage duration inside constexpr function [misc-static-in-constexpr] + + thread_local int y = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: variable of static or thread storage duration inside constexpr function [misc-static-in-constexpr] +} + +consteval void consteval_func() { + static int x = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: variable of static or thread storage duration inside constexpr function [misc-static-in-constexpr] +} + +constexpr void constexpr_with_lambda() { + auto l = []() { + static int x = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: variable of static or thread storage duration inside constexpr function [misc-static-in-constexpr] + }; +} + +constexpr void constexpr_with_constexpr_lambda() { + auto l = []() constexpr { + static int x = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: variable of static or thread storage duration inside constexpr function [misc-static-in-constexpr] + }; +} + +struct S { + static constexpr void static_member_func() { + static int x = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: variable of static or thread storage duration inside constexpr function [misc-static-in-constexpr] + } +}; \ No newline at end of file diff --git a/libcxx/.clang-tidy b/libcxx/.clang-tidy index ebbfab0379265..685773e4095cd 100644 --- a/libcxx/.clang-tidy +++ b/libcxx/.clang-tidy @@ -13,6 +13,7 @@ Checks: > misc-definitions-in-headers, misc-misplaced-const, misc-non-copyable-objects, + misc-static-in-constexpr, misc-uniqueptr-reset-release, modernize-loop-convert, `````````` </details> https://github.com/llvm/llvm-project/pull/175814 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
