https://github.com/steffenlarsen created 
https://github.com/llvm/llvm-project/pull/183287

This commit intends to clean up the use of global strings in clang by enforcing 
immutability. As far as possible, the global and static variables of either 
type 'const char *' or 'StringRef' (and arrays thereof) are either declared 
'constexpr' or 'const'. This should help ensure that these variables are not 
used as global state at runtime and reduce the overall global state surface of 
clang.

>From 92eda02c885aba0804489ac8ada128e6d2ae3b65 Mon Sep 17 00:00:00 2001
From: Steffen Holst Larsen <[email protected]>
Date: Wed, 25 Feb 2026 05:34:50 -0600
Subject: [PATCH] [Clang][NFCI] Enforce immutability of global strings

This commit intends to clean up the use of global strings in clang by
enforcing immutability. As far as possible, the global and static
variables of either type 'const char *' or 'StringRef' (and arrays
thereof) are either declared 'constexpr' or 'const'. This should help
ensure that these variables are not used as global state at runtime and
reduce the overall global state surface of clang.

Signed-off-by: Steffen Holst Larsen <[email protected]>
---
 clang/include/clang/Basic/PlistSupport.h      |  2 +-
 clang/include/clang/Format/Format.h           |  6 +-
 clang/include/clang/Tooling/AllTUsExecution.h |  2 +-
 .../clang/Tooling/StandaloneExecution.h       |  2 +-
 clang/lib/AST/Mangle.cpp                      |  2 +-
 clang/lib/AST/NSAPI.cpp                       | 85 +++++++++----------
 clang/lib/Analysis/IssueHash.cpp              |  4 +-
 clang/lib/CodeGen/CGNonTrivialStruct.cpp      |  2 +-
 clang/lib/Driver/Driver.cpp                   |  4 +-
 clang/lib/Driver/ToolChains/Clang.cpp         |  4 +-
 clang/lib/Format/Format.cpp                   |  6 +-
 clang/lib/InstallAPI/DirectoryScanner.cpp     |  8 +-
 clang/lib/Sema/SemaCodeComplete.cpp           |  4 +-
 .../ObjectFilePCHContainerReader.cpp          |  2 +-
 .../Serialization/PCHContainerOperations.cpp  |  2 +-
 .../Checkers/DereferenceChecker.cpp           |  2 +-
 .../StaticAnalyzer/Checkers/ErrnoModeling.cpp |  2 +-
 .../Checkers/GCDAntipatternChecker.cpp        |  2 +-
 .../Checkers/OSObjectCStyleCast.cpp           |  4 +-
 .../Checkers/ObjCAutoreleaseWriteChecker.cpp  | 10 +--
 .../RunLoopAutoreleaseLeakChecker.cpp         | 10 +--
 .../StaticAnalyzer/Checkers/StreamChecker.cpp |  6 +-
 clang/lib/Tooling/AllTUsExecution.cpp         |  2 -
 clang/lib/Tooling/StandaloneExecution.cpp     |  2 -
 clang/unittests/Tooling/ExecutionTest.cpp     |  4 +-
 25 files changed, 82 insertions(+), 97 deletions(-)

diff --git a/clang/include/clang/Basic/PlistSupport.h 
b/clang/include/clang/Basic/PlistSupport.h
index 1814130f1d2cb..2e248c5066e17 100644
--- a/clang/include/clang/Basic/PlistSupport.h
+++ b/clang/include/clang/Basic/PlistSupport.h
@@ -57,7 +57,7 @@ inline raw_ostream &Indent(raw_ostream &o, const unsigned 
indent) {
 }
 
 inline raw_ostream &EmitPlistHeader(raw_ostream &o) {
-  static const char *PlistHeader =
+  constexpr char PlistHeader[] =
       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
       "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
       "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\";>\n"
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 2028c963ac306..8dba796126f18 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -6174,16 +6174,16 @@ LangOptions getFormattingLangOpts(const FormatStyle 
&Style = getLLVMStyle());
 /// Description to be used for help text for a ``llvm::cl`` option for
 /// specifying format style. The description is closely related to the 
operation
 /// of ``getStyle()``.
-extern const char *StyleOptionHelpDescription;
+extern const char *const StyleOptionHelpDescription;
 
 /// The suggested format style to use by default. This allows tools using
 /// ``getStyle`` to have a consistent default style.
 /// Different builds can modify the value to the preferred styles.
-extern const char *DefaultFormatStyle;
+extern const char *const DefaultFormatStyle;
 
 /// The suggested predefined style to use as the fallback style in 
``getStyle``.
 /// Different builds can modify the value to the preferred styles.
-extern const char *DefaultFallbackStyle;
+extern const char *const DefaultFallbackStyle;
 
 /// Construct a FormatStyle based on ``StyleName``.
 ///
diff --git a/clang/include/clang/Tooling/AllTUsExecution.h 
b/clang/include/clang/Tooling/AllTUsExecution.h
index 03cfc9c67f5c5..d1faeca54ed1f 100644
--- a/clang/include/clang/Tooling/AllTUsExecution.h
+++ b/clang/include/clang/Tooling/AllTUsExecution.h
@@ -25,7 +25,7 @@ namespace tooling {
 /// database.
 class AllTUsToolExecutor : public ToolExecutor {
 public:
-  static const char *ExecutorName;
+  static constexpr char ExecutorName[] = "AllTUsToolExecutor";
 
   /// Init with \p CompilationDatabase.
   /// This uses \p ThreadCount threads to exececute the actions on all files in
diff --git a/clang/include/clang/Tooling/StandaloneExecution.h 
b/clang/include/clang/Tooling/StandaloneExecution.h
index cdbe65a95b9d2..eb669bb063c38 100644
--- a/clang/include/clang/Tooling/StandaloneExecution.h
+++ b/clang/include/clang/Tooling/StandaloneExecution.h
@@ -30,7 +30,7 @@ namespace tooling {
 ///   - `getClangStripDependencyFileAdjuster()`
 class StandaloneToolExecutor : public ToolExecutor {
 public:
-  static const char *ExecutorName;
+  static constexpr char ExecutorName[] = "StandaloneToolExecutor";
 
   /// Init with \p CompilationDatabase and the paths of all files to be
   /// proccessed.
diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp
index 780b2c585c810..8291624b76822 100644
--- a/clang/lib/AST/Mangle.cpp
+++ b/clang/lib/AST/Mangle.cpp
@@ -152,7 +152,7 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl 
*D) {
   return shouldMangleCXXName(D);
 }
 
-static llvm::StringRef g_lldb_func_call_label_prefix = "$__lldb_func:";
+constexpr llvm::StringRef g_lldb_func_call_label_prefix = "$__lldb_func:";
 
 /// Given an LLDB function call label, this function prints the label
 /// into \c Out, together with the structor type of \c GD (if the
diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp
index 17f5ee5dee3d1..f0973a716e19b 100644
--- a/clang/lib/AST/NSAPI.cpp
+++ b/clang/lib/AST/NSAPI.cpp
@@ -21,18 +21,11 @@ NSAPI::NSAPI(ASTContext &ctx)
     NSUTF8StringEncodingId(nullptr) {}
 
 IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
-  static const char *ClassName[NumClassIds] = {
-    "NSObject",
-    "NSString",
-    "NSArray",
-    "NSMutableArray",
-    "NSDictionary",
-    "NSMutableDictionary",
-    "NSNumber",
-    "NSMutableSet",
-    "NSMutableOrderedSet",
-    "NSValue"
-  };
+  constexpr const char *const ClassName[NumClassIds] = {
+      "NSObject",       "NSString",     "NSArray",
+      "NSMutableArray", "NSDictionary", "NSMutableDictionary",
+      "NSNumber",       "NSMutableSet", "NSMutableOrderedSet",
+      "NSValue"};
 
   if (!ClassIds[K])
     return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
@@ -284,43 +277,41 @@ std::optional<NSAPI::NSSetMethodKind> 
NSAPI::getNSSetMethodKind(Selector Sel) {
 
 Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
                                            bool Instance) const {
-  static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
-    "numberWithChar",
-    "numberWithUnsignedChar",
-    "numberWithShort",
-    "numberWithUnsignedShort",
-    "numberWithInt",
-    "numberWithUnsignedInt",
-    "numberWithLong",
-    "numberWithUnsignedLong",
-    "numberWithLongLong",
-    "numberWithUnsignedLongLong",
-    "numberWithFloat",
-    "numberWithDouble",
-    "numberWithBool",
-    "numberWithInteger",
-    "numberWithUnsignedInteger"
-  };
-  static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
-    "initWithChar",
-    "initWithUnsignedChar",
-    "initWithShort",
-    "initWithUnsignedShort",
-    "initWithInt",
-    "initWithUnsignedInt",
-    "initWithLong",
-    "initWithUnsignedLong",
-    "initWithLongLong",
-    "initWithUnsignedLongLong",
-    "initWithFloat",
-    "initWithDouble",
-    "initWithBool",
-    "initWithInteger",
-    "initWithUnsignedInteger"
-  };
+  constexpr const char *const ClassSelectorName[NumNSNumberLiteralMethods] = {
+      "numberWithChar",
+      "numberWithUnsignedChar",
+      "numberWithShort",
+      "numberWithUnsignedShort",
+      "numberWithInt",
+      "numberWithUnsignedInt",
+      "numberWithLong",
+      "numberWithUnsignedLong",
+      "numberWithLongLong",
+      "numberWithUnsignedLongLong",
+      "numberWithFloat",
+      "numberWithDouble",
+      "numberWithBool",
+      "numberWithInteger",
+      "numberWithUnsignedInteger"};
+  constexpr const char *const InstanceSelectorName[NumNSNumberLiteralMethods] =
+      {"initWithChar",
+       "initWithUnsignedChar",
+       "initWithShort",
+       "initWithUnsignedShort",
+       "initWithInt",
+       "initWithUnsignedInt",
+       "initWithLong",
+       "initWithUnsignedLong",
+       "initWithLongLong",
+       "initWithUnsignedLongLong",
+       "initWithFloat",
+       "initWithDouble",
+       "initWithBool",
+       "initWithInteger",
+       "initWithUnsignedInteger"};
 
   Selector *Sels;
-  const char **Names;
+  const char *const *Names;
   if (Instance) {
     Sels = NSNumberInstanceSelectors;
     Names = InstanceSelectorName;
diff --git a/clang/lib/Analysis/IssueHash.cpp b/clang/lib/Analysis/IssueHash.cpp
index e4b73d37a63f3..47fe930cd1de4 100644
--- a/clang/lib/Analysis/IssueHash.cpp
+++ b/clang/lib/Analysis/IssueHash.cpp
@@ -132,7 +132,7 @@ static StringRef 
GetNthLineOfFile(std::optional<llvm::MemoryBufferRef> Buffer,
 
 static std::string NormalizeLine(const SourceManager &SM, const FullSourceLoc 
&L,
                                  const LangOptions &LangOpts) {
-  static StringRef Whitespaces = " \t\n";
+  constexpr StringRef Whitespaces = " \t\n";
 
   StringRef Str = GetNthLineOfFile(SM.getBufferOrNone(L.getFileID(), L),
                                    L.getExpansionLineNumber());
@@ -183,7 +183,7 @@ std::string clang::getIssueString(const FullSourceLoc 
&IssueLoc,
                                   StringRef WarningMessage,
                                   const Decl *IssueDecl,
                                   const LangOptions &LangOpts) {
-  static StringRef Delimiter = "$";
+  constexpr StringRef Delimiter = "$";
 
   return (llvm::Twine(CheckerName) + Delimiter +
           GetEnclosingDeclContextSignature(IssueDecl) + Delimiter +
diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp 
b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
index 0a383c8f919d9..4e171691029eb 100644
--- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp
+++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -32,7 +32,7 @@ static uint64_t getFieldSize(const FieldDecl *FD, QualType FT,
 
 namespace {
 enum { DstIdx = 0, SrcIdx = 1 };
-const char *ValNameStr[2] = {"dst", "src"};
+constexpr char *const ValNameStr[2] = {"dst", "src"};
 
 template <class Derived> struct StructVisitor {
   StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index c52610f1cae7b..fcf6b05a4411b 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -219,7 +219,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef 
TargetTriple,
 }
 
 void Driver::setDriverMode(StringRef Value) {
-  static StringRef OptName =
+  static const StringRef OptName =
       getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
   if (auto M = llvm::StringSwitch<std::optional<DriverMode>>(Value)
                    .Case("gcc", GCCMode)
@@ -7220,7 +7220,7 @@ bool clang::driver::willEmitRemarks(const ArgList &Args) {
 
 llvm::StringRef clang::driver::getDriverMode(StringRef ProgName,
                                              ArrayRef<const char *> Args) {
-  static StringRef OptName =
+  static const StringRef OptName =
       
getDriverOptTable().getOption(options::OPT_driver_mode).getPrefixedName();
   llvm::StringRef Opt;
   for (StringRef Arg : Args) {
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 6dbb51a26868d..be9cb19149da7 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6518,8 +6518,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
     CmdArgs.push_back("-relocatable-pch");
 
   if (const Arg *A = Args.getLastArg(options::OPT_fcf_runtime_abi_EQ)) {
-    static const char *kCFABIs[] = {
-      "standalone", "objc", "swift", "swift-5.0", "swift-4.2", "swift-4.1",
+    constexpr char *const kCFABIs[] = {
+        "standalone", "objc", "swift", "swift-5.0", "swift-4.2", "swift-4.1",
     };
 
     if (!llvm::is_contained(kCFABIs, StringRef(A->getValue())))
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 2f67ec86b101a..6a069778fa5e6 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -4338,7 +4338,7 @@ LangOptions getFormattingLangOpts(const FormatStyle 
&Style) {
   return LangOpts;
 }
 
-const char *StyleOptionHelpDescription =
+const char *const StyleOptionHelpDescription =
     "Set coding style. <string> can be:\n"
     "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"
     "   Mozilla, WebKit.\n"
@@ -4449,9 +4449,9 @@ FormatStyle::LanguageKind guessLanguage(StringRef 
FileName, StringRef Code) {
 }
 
 // Update StyleOptionHelpDescription above when changing this.
-const char *DefaultFormatStyle = "file";
+const char *const DefaultFormatStyle = "file";
 
-const char *DefaultFallbackStyle = "LLVM";
+const char *const DefaultFallbackStyle = "LLVM";
 
 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
 loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
diff --git a/clang/lib/InstallAPI/DirectoryScanner.cpp 
b/clang/lib/InstallAPI/DirectoryScanner.cpp
index f8f708fda4ca4..bdf375bbdbda4 100644
--- a/clang/lib/InstallAPI/DirectoryScanner.cpp
+++ b/clang/lib/InstallAPI/DirectoryScanner.cpp
@@ -275,9 +275,9 @@ llvm::Error DirectoryScanner::scanForFrameworks(StringRef 
Directory) {
 
   // Expect a certain directory structure and naming convention to find
   // frameworks.
-  static const char *SubDirectories[] = {"System/Library/Frameworks/",
-                                         "System/Library/PrivateFrameworks/",
-                                         "System/Library/SubFrameworks"};
+  constexpr const char *const SubDirectories[] = {
+      "System/Library/Frameworks/", "System/Library/PrivateFrameworks/",
+      "System/Library/SubFrameworks"};
 
   // Check if the directory is already a framework.
   if (isFramework(Directory)) {
@@ -288,7 +288,7 @@ llvm::Error DirectoryScanner::scanForFrameworks(StringRef 
Directory) {
   }
 
   // Check known sub-directory locations.
-  for (const auto *SubDir : SubDirectories) {
+  for (const auto *const SubDir : SubDirectories) {
     SmallString<PATH_MAX> Path(Directory);
     sys::path::append(Path, SubDir);
 
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index 98d78d2a461f1..5c1031cbf69fa 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -10471,8 +10471,8 @@ void 
SemaCodeCompletion::CodeCompleteAvailabilityPlatformName() {
                         CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
-  static const char *Platforms[] = {"macOS", "iOS", "watchOS", "tvOS"};
-  for (const char *Platform : llvm::ArrayRef(Platforms)) {
+  constexpr const char *const Platforms[] = {"macOS", "iOS", "watchOS", 
"tvOS"};
+  for (const char *const Platform : llvm::ArrayRef(Platforms)) {
     Results.AddResult(CodeCompletionResult(Platform));
     Results.AddResult(CodeCompletionResult(Results.getAllocator().CopyString(
         Twine(Platform) + "ApplicationExtension")));
diff --git a/clang/lib/Serialization/ObjectFilePCHContainerReader.cpp 
b/clang/lib/Serialization/ObjectFilePCHContainerReader.cpp
index 59fc46960dc60..08634bf9fe15e 100644
--- a/clang/lib/Serialization/ObjectFilePCHContainerReader.cpp
+++ b/clang/lib/Serialization/ObjectFilePCHContainerReader.cpp
@@ -13,7 +13,7 @@
 using namespace clang;
 
 ArrayRef<StringRef> ObjectFilePCHContainerReader::getFormats() const {
-  static StringRef Formats[] = {"obj", "raw"};
+  static const StringRef Formats[] = {"obj", "raw"};
   return Formats;
 }
 
diff --git a/clang/lib/Serialization/PCHContainerOperations.cpp 
b/clang/lib/Serialization/PCHContainerOperations.cpp
index 4aedb7debcff2..881f59ba4ab0e 100644
--- a/clang/lib/Serialization/PCHContainerOperations.cpp
+++ b/clang/lib/Serialization/PCHContainerOperations.cpp
@@ -56,7 +56,7 @@ std::unique_ptr<ASTConsumer> 
RawPCHContainerWriter::CreatePCHContainerGenerator(
 }
 
 ArrayRef<llvm::StringRef> RawPCHContainerReader::getFormats() const {
-  static StringRef Raw("raw");
+  static const StringRef Raw("raw");
   return ArrayRef(Raw);
 }
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
index be61eceeb62e7..51b2fa8299c33 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -399,7 +399,7 @@ namespace llvm {
 template <> struct format_provider<ValueDescStr> {
   static void format(const ValueDescStr &V, raw_ostream &Stream,
                      StringRef Style) {
-    static const char *ValueStr[2][3] = {
+    constexpr const char *const ValueStr[2][3] = {
         {"zero", "nonzero integer value", "probably nonzero integer value"},
         {"null pointer", "non-null pointer", "probably non-null pointer"},
     };
diff --git a/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
index 46c7a6cd9a4dc..108f215944b94 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp
@@ -36,7 +36,7 @@ namespace {
 
 // Name of the "errno" variable.
 // FIXME: Is there a system where it is not called "errno" but is a variable?
-const char *ErrnoVarName = "errno";
+constexpr char ErrnoVarName[] = "errno";
 
 // Names of functions that return a location of the "errno" value.
 // FIXME: Are there other similar function names?
diff --git a/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp
index 5637941a58f02..b719613e8ddcc 100644
--- a/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp
@@ -43,7 +43,7 @@ using namespace ast_matchers;
 namespace {
 
 // ID of a node at which the diagnostic would be emitted.
-const char *WarnAtNode = "waitcall";
+constexpr char WarnAtNode[] = "waitcall";
 
 class GCDAntipatternChecker : public Checker<check::ASTCodeBody> {
 public:
diff --git a/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp 
b/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp
index 46690dd886b2b..c12f0d070dfc3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp
@@ -24,8 +24,8 @@ using namespace ento;
 using namespace ast_matchers;
 
 namespace {
-static constexpr const char *const WarnAtNode = "WarnAtNode";
-static constexpr const char *const WarnRecordDecl = "WarnRecordDecl";
+constexpr char WarnAtNode[] = "WarnAtNode";
+constexpr char WarnRecordDecl[] = "WarnRecordDecl";
 
 class OSObjectCStyleCastChecker : public Checker<check::ASTCodeBody> {
 public:
diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp
index e7fd14d4558b2..c595bb0deafc0 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp
@@ -41,11 +41,11 @@ using namespace ast_matchers;
 
 namespace {
 
-const char *ProblematicWriteBind = "problematicwrite";
-const char *CapturedBind = "capturedbind";
-const char *ParamBind = "parambind";
-const char *IsMethodBind = "ismethodbind";
-const char *IsARPBind = "isautoreleasepoolbind";
+constexpr char ProblematicWriteBind[] = "problematicwrite";
+constexpr char CapturedBind[] = "capturedbind";
+constexpr char ParamBind[] = "parambind";
+constexpr char IsMethodBind[] = "ismethodbind";
+constexpr char IsARPBind[] = "isautoreleasepoolbind";
 
 class ObjCAutoreleaseWriteChecker : public Checker<check::ASTCodeBody> {
 public:
diff --git 
a/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp
index 2cf6c6ff47f1d..66565fa579707 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp
@@ -40,11 +40,11 @@ using namespace ast_matchers;
 
 namespace {
 
-const char * RunLoopBind = "NSRunLoopM";
-const char * RunLoopRunBind = "RunLoopRunM";
-const char * OtherMsgBind = "OtherMessageSentM";
-const char * AutoreleasePoolBind = "AutoreleasePoolM";
-const char * OtherStmtAutoreleasePoolBind = "OtherAutoreleasePoolM";
+constexpr char RunLoopBind[] = "NSRunLoopM";
+constexpr char RunLoopRunBind[] = "RunLoopRunM";
+constexpr char OtherMsgBind[] = "OtherMessageSentM";
+constexpr char AutoreleasePoolBind[] = "AutoreleasePoolM";
+constexpr char OtherStmtAutoreleasePoolBind[] = "OtherAutoreleasePoolM";
 
 class RunLoopAutoreleaseLeakChecker : public Checker<check::ASTCodeBody> {
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 6481b76e69171..feada75dd1b1a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -198,8 +198,8 @@ using FnCheck = std::function<void(const StreamChecker *, 
const FnDescription *,
 using ArgNoTy = unsigned int;
 static const ArgNoTy ArgNone = std::numeric_limits<ArgNoTy>::max();
 
-const char *FeofNote = "Assuming stream reaches end-of-file here";
-const char *FerrorNote = "Assuming this stream operation fails";
+constexpr char FeofNote[] = "Assuming stream reaches end-of-file here";
+constexpr char FerrorNote[] = "Assuming this stream operation fails";
 
 struct FnDescription {
   FnCheck PreFn;
@@ -1923,7 +1923,7 @@ ProgramStateRef StreamChecker::ensureStreamOpened(SVal 
StreamVal,
 
 ProgramStateRef StreamChecker::ensureNoFilePositionIndeterminate(
     SVal StreamVal, CheckerContext &C, ProgramStateRef State) const {
-  static const char *BugMessage =
+  constexpr char BugMessage[] =
       "File position of the stream might be 'indeterminate' "
       "after a failed operation. "
       "Can cause undefined behavior.";
diff --git a/clang/lib/Tooling/AllTUsExecution.cpp 
b/clang/lib/Tooling/AllTUsExecution.cpp
index 9cad8680447be..69291bbbc9fa8 100644
--- a/clang/lib/Tooling/AllTUsExecution.cpp
+++ b/clang/lib/Tooling/AllTUsExecution.cpp
@@ -16,8 +16,6 @@
 namespace clang {
 namespace tooling {
 
-const char *AllTUsToolExecutor::ExecutorName = "AllTUsToolExecutor";
-
 namespace {
 llvm::Error make_string_error(const llvm::Twine &Message) {
   return llvm::make_error<llvm::StringError>(Message,
diff --git a/clang/lib/Tooling/StandaloneExecution.cpp 
b/clang/lib/Tooling/StandaloneExecution.cpp
index 09094c3c23f34..706ee3f3d8d28 100644
--- a/clang/lib/Tooling/StandaloneExecution.cpp
+++ b/clang/lib/Tooling/StandaloneExecution.cpp
@@ -17,8 +17,6 @@ static llvm::Error make_string_error(const llvm::Twine 
&Message) {
                                              llvm::inconvertibleErrorCode());
 }
 
-const char *StandaloneToolExecutor::ExecutorName = "StandaloneToolExecutor";
-
 static ArgumentsAdjuster getDefaultArgumentsAdjusters() {
   return combineAdjusters(
       getClangStripOutputAdjuster(),
diff --git a/clang/unittests/Tooling/ExecutionTest.cpp 
b/clang/unittests/Tooling/ExecutionTest.cpp
index c81049308f706..284965a66cb64 100644
--- a/clang/unittests/Tooling/ExecutionTest.cpp
+++ b/clang/unittests/Tooling/ExecutionTest.cpp
@@ -87,7 +87,7 @@ class ReportResultActionFactory : public 
FrontendActionFactory {
 
 class TestToolExecutor : public ToolExecutor {
 public:
-  static const char *ExecutorName;
+  static constexpr char ExecutorName[] = "test-executor";
 
   TestToolExecutor(CommonOptionsParser Options)
       : OptionsParser(std::move(Options)) {}
@@ -118,8 +118,6 @@ class TestToolExecutor : public ToolExecutor {
   std::map<std::string, std::string> VFS;
 };
 
-const char *TestToolExecutor::ExecutorName = "test-executor";
-
 class TestToolExecutorPlugin : public ToolExecutorPlugin {
 public:
   llvm::Expected<std::unique_ptr<ToolExecutor>>

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

Reply via email to