Skip to content

Commit a97b851

Browse files
committed
add StaticConstexprString option
1 parent 7832be9 commit a97b851

File tree

5 files changed

+90
-9
lines changed

5 files changed

+90
-9
lines changed

clang-tools-extra/clang-tidy/modernize/UseConstexprCheck.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -911,18 +911,43 @@ void UseConstexprCheck::onEndOfTranslationUnit() {
911911
Diag << FixItHint::CreateInsertion(FDecl->getInnerLocStart(),
912912
FunctionReplacement);
913913
}
914-
const std::string VariableReplacement = ConstexprString + " ";
914+
915+
const std::string VariableReplacementWithStatic = StaticConstexprString + " ";
916+
const auto VariableReplacement =
917+
[&FunctionReplacement, this, &VariableReplacementWithStatic](
918+
const VarDecl *Var, const FunctionDecl *FuncCtx,
919+
const bool IsAddingConstexprToFuncCtx) -> const std::string & {
920+
if (!FuncCtx)
921+
return FunctionReplacement;
922+
923+
if (!getLangOpts().CPlusPlus23)
924+
return FunctionReplacement;
925+
926+
// We'll prefer the function to be constexpr over the function not being
927+
// constexpr just for the var to be static constexpr instead of just
928+
// constexpr.
929+
if (IsAddingConstexprToFuncCtx)
930+
return FunctionReplacement;
931+
932+
if (Var->isStaticLocal())
933+
return FunctionReplacement;
934+
935+
return VariableReplacementWithStatic;
936+
};
937+
915938
for (const auto &[Var, FuncCtx] : VariableMapping) {
939+
const auto IsAddingConstexprToFuncCtx = Functions.contains(FuncCtx);
916940
if (FuncCtx && getLangOpts().CPlusPlus23 && Var->isStaticLocal() &&
917-
Functions.contains(FuncCtx))
941+
IsAddingConstexprToFuncCtx)
918942
continue;
919943
const SourceRange R =
920944
SourceRange(Var->getInnerLocStart(), Var->getLocation());
921945
auto Diag =
922946
diag(Var->getLocation(), "variable %0 can be declared 'constexpr'")
923947
<< Var << R
924-
<< FixItHint::CreateInsertion(Var->getInnerLocStart(),
925-
VariableReplacement);
948+
<< FixItHint::CreateInsertion(
949+
Var->getInnerLocStart(),
950+
VariableReplacement(Var, FuncCtx, IsAddingConstexprToFuncCtx));
926951
// Since either of the locs can be in a macro, use `makeFileCharRange` to be
927952
// sure that we have a consistent `CharSourceRange`, located entirely in the
928953
// source file.
@@ -947,11 +972,14 @@ UseConstexprCheck::UseConstexprCheck(StringRef Name, ClangTidyContext *Context)
947972
ConservativeLiteralType(Options.get("ConservativeLiteralType", true)),
948973
AddConstexprToMethodOfClassWithoutConstexprConstructor(Options.get(
949974
"AddConstexprToMethodOfClassWithoutConstexprConstructor", false)),
950-
ConstexprString(Options.get("ConstexprString", "constexpr")) {}
975+
ConstexprString(Options.get("ConstexprString", "constexpr")),
976+
StaticConstexprString(
977+
Options.get("StaticConstexprString", "static " + ConstexprString)) {}
951978
void UseConstexprCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
952979
Options.store(Opts, "ConservativeLiteralType", ConservativeLiteralType);
953980
Options.store(Opts, "AddConstexprToMethodOfClassWithoutConstexprConstructor",
954981
AddConstexprToMethodOfClassWithoutConstexprConstructor);
955982
Options.store(Opts, "ConstexprString", ConstexprString);
983+
Options.store(Opts, "StaticConstexprString", StaticConstexprString);
956984
}
957985
} // namespace clang::tidy::modernize

clang-tools-extra/clang-tidy/modernize/UseConstexprCheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class UseConstexprCheck : public ClangTidyCheck {
3535
const bool ConservativeLiteralType;
3636
const bool AddConstexprToMethodOfClassWithoutConstexprConstructor;
3737
const std::string ConstexprString;
38+
const std::string StaticConstexprString;
3839
llvm::SmallPtrSet<const FunctionDecl *, 32> Functions;
3940
llvm::DenseMap<const VarDecl *, const FunctionDecl *> VariableMapping;
4041
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %check_clang_tidy -std=c++11 %s modernize-use-constexpr %t -- -- -fno-delayed-template-parsing
2+
// RUN: %check_clang_tidy -std=c++14 %s modernize-use-constexpr %t -- -- -fno-delayed-template-parsing
3+
// RUN: %check_clang_tidy -std=c++17 %s modernize-use-constexpr %t -- -- -fno-delayed-template-parsing
4+
// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constexpr %t -- -- -fno-delayed-template-parsing
5+
// RUN: %check_clang_tidy -std=c++23-or-later -check-suffix=23 %s modernize-use-constexpr %t -- -- -fno-delayed-template-parsing
6+
7+
8+
#define FUNC(N) void func##N()
9+
FUNC(0) {
10+
static int f1 = 1;
11+
static const int f2 = 2;
12+
// CHECK-MESSAGES-23: :[[@LINE-1]]:22: warning: variable 'f2' can be declared 'constexpr' [modernize-use-constexpr]
13+
// CHECK-FIXES-23: constexpr static int f2 = 2;
14+
const int f3 = 3;
15+
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: variable 'f3' can be declared 'constexpr' [modernize-use-constexpr]
16+
// CHECK-FIXES: constexpr int f3 = 3;
17+
// CHECK-MESSAGES-23: :[[@LINE-3]]:15: warning: variable 'f3' can be declared 'constexpr' [modernize-use-constexpr]
18+
// CHECK-FIXES-23: static constexpr int f3 = 3;
19+
}
20+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %check_clang_tidy -std=c++11 %s modernize-use-constexpr %t -- -config="{CheckOptions: {modernize-use-constexpr.ConstexprString: 'CXPR'}}"
2+
// RUN: %check_clang_tidy -std=c++14 %s modernize-use-constexpr %t -- -config="{CheckOptions: {modernize-use-constexpr.ConstexprString: 'CXPR'}}"
3+
// RUN: %check_clang_tidy -std=c++17 %s modernize-use-constexpr %t -- -config="{CheckOptions: {modernize-use-constexpr.ConstexprString: 'CXPR'}}"
4+
// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constexpr %t -- -config="{CheckOptions: {modernize-use-constexpr.ConstexprString: 'CXPR'}}"
5+
// RUN: %check_clang_tidy -std=c++23-or-later -check-suffix=23 %s modernize-use-constexpr %t -- -config="{CheckOptions: {modernize-use-constexpr.ConstexprString: 'CXPR'}}"
6+
// RUN: %check_clang_tidy -std=c++23-or-later -check-suffix=23-STATIC %s modernize-use-constexpr %t -- -config="{CheckOptions: {modernize-use-constexpr.ConstexprString: 'CXPR', modernize-use-constexpr.StaticConstexprString: 'STATIC_CXPR'}}"
7+
8+
static int f1() { return 0; }
9+
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: function 'f1' can be declared 'constexpr' [modernize-use-constexpr]
10+
// CHECK-FIXES: CXPR static int f1() { return 0; }
11+
// CHECK-MESSAGES-23: :[[@LINE-3]]:12: warning: function 'f1' can be declared 'constexpr' [modernize-use-constexpr]
12+
// CHECK-FIXES-23: CXPR static int f1() { return 0; }
13+
// CHECK-MESSAGES-23-STATIC: :[[@LINE-5]]:12: warning: function 'f1' can be declared 'constexpr' [modernize-use-constexpr]
14+
// CHECK-FIXES-23-STATIC: CXPR static int f1() { return 0; }
15+
16+
#define FUNC(N) void func##N()
17+
FUNC(0) {
18+
static int f1 = 1;
19+
static const int f2 = 2;
20+
// CHECK-MESSAGES-23: :[[@LINE-1]]:22: warning: variable 'f2' can be declared 'constexpr' [modernize-use-constexpr]
21+
// CHECK-FIXES-23: CXPR static int f2 = 2;
22+
// CHECK-MESSAGES-23-STATIC: :[[@LINE-3]]:22: warning: variable 'f2' can be declared 'constexpr' [modernize-use-constexpr]
23+
// CHECK-FIXES-23-STATIC: CXPR static int f2 = 2;
24+
const int f3 = 3;
25+
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: variable 'f3' can be declared 'constexpr' [modernize-use-constexpr]
26+
// CHECK-FIXES: CXPR int f3 = 3;
27+
// CHECK-MESSAGES-23: :[[@LINE-3]]:15: warning: variable 'f3' can be declared 'constexpr' [modernize-use-constexpr]
28+
// CHECK-FIXES-23: static CXPR int f3 = 3;
29+
// CHECK-MESSAGES-23-STATIC: :[[@LINE-5]]:15: warning: variable 'f3' can be declared 'constexpr' [modernize-use-constexpr]
30+
// CHECK-FIXES-23-STATIC: STATIC_CXPR int f3 = 3;
31+
}
32+

clang-tools-extra/test/clang-tidy/checkers/modernize/use-constexpr.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,11 +453,11 @@ namespace variable {
453453
static const int d1 = 3;
454454

455455
static auto e1 = TemplatedVar1<int> + TemplatedVar1<unsigned int>;
456-
}
457456

458-
const auto check = [](const int & ref) { };
459-
// CHECK-MESSAGES-17: :[[@LINE-1]]:16: warning: variable 'check' can be declared 'constexpr' [modernize-use-constexpr]
460-
// CHECK-FIXES-17: constexpr auto check = [](const int & ref) { };
457+
const auto check = [](const int & ref) { };
458+
// CHECK-MESSAGES-17: :[[@LINE-1]]:24: warning: variable 'check' can be declared 'constexpr' [modernize-use-constexpr]
459+
// CHECK-FIXES-17: constexpr auto check = [](const int & ref) { };
460+
}
461461
} // namespace literal_type
462462

463463
namespace struct_type {

0 commit comments

Comments
 (0)