[clang-tools-extra] [NFC] Fixes proposed by code sanitizer. (PR #134138)
Zahira Ammarguellat via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 3 12:12:17 PDT 2025
https://github.com/zahiraam updated https://github.com/llvm/llvm-project/pull/134138
>From 608f5827cedbbc65441cefab80fbcdba7a053933 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Wed, 2 Apr 2025 11:52:13 -0700
Subject: [PATCH 1/3] [NFC] Fixes proposed by code sanitizer.
---
.../bugprone/NarrowingConversionsCheck.cpp | 2 +-
.../misc/ConstCorrectnessCheck.cpp.1 | 272 ++++++++++++++++++
clang-tools-extra/clangd/ConfigCompile.cpp | 2 +-
clang-tools-extra/clangd/Headers.cpp | 2 +-
4 files changed, 275 insertions(+), 3 deletions(-)
create mode 100644 clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp.1
diff --git a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp
index bafcd402ca851..7650d9e8a592f 100644
--- a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp
@@ -260,7 +260,7 @@ static IntegerRange createFromType(const ASTContext &Context,
llvm::APSInt LowerValue(PrecisionBits + 2, /*isUnsigned*/ false);
LowerValue.setBit(PrecisionBits);
LowerValue.setSignBit();
- return {LowerValue, UpperValue};
+ return {std::move(LowerValue), UpperValue};
}
assert(T.isInteger() && "Unexpected builtin type");
uint64_t TypeSize = Context.getTypeSize(&T);
diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp.1 b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp.1
new file mode 100644
index 0000000000000..cecac7628e66c
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp.1
@@ -0,0 +1,272 @@
+//===--- ConstCorrectnessCheck.cpp - clang-tidy -----------------*- C++ -*-===//
+//
+// 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 "ConstCorrectnessCheck.h"
+#include "../utils/FixItHintUtils.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include <cassert>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::misc {
+
+namespace {
+// FIXME: This matcher exists in some other code-review as well.
+// It should probably move to ASTMatchers.
+AST_MATCHER(VarDecl, isLocal) { return Node.isLocalVarDecl(); }
+AST_MATCHER_P(DeclStmt, containsAnyDeclaration,
+ ast_matchers::internal::Matcher<Decl>, InnerMatcher) {
+ return ast_matchers::internal::matchesFirstInPointerRange(
+ InnerMatcher, Node.decl_begin(), Node.decl_end(), Finder,
+ Builder) != Node.decl_end();
+}
+AST_MATCHER(ReferenceType, isSpelledAsLValue) {
+ return Node.isSpelledAsLValue();
+}
+AST_MATCHER(Type, isDependentType) { return Node.isDependentType(); }
+} // namespace
+
+ConstCorrectnessCheck::ConstCorrectnessCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ AnalyzePointers(Options.get("AnalyzePointers", true)),
+ AnalyzeReferences(Options.get("AnalyzeReferences", true)),
+ AnalyzeValues(Options.get("AnalyzeValues", true)),
+
+ WarnPointersAsPointers(Options.get("WarnPointersAsPointers", true)),
+ WarnPointersAsValues(Options.get("WarnPointersAsValues", false)),
+
+ TransformPointersAsPointers(
+ Options.get("TransformPointersAsPointers", true)),
+ TransformPointersAsValues(
+ Options.get("TransformPointersAsValues", false)),
+ TransformReferences(Options.get("TransformReferences", true)),
+ TransformValues(Options.get("TransformValues", true)),
+
+ AllowedTypes(
+ utils::options::parseStringList(Options.get("AllowedTypes", ""))) {
+ if (AnalyzeValues == false && AnalyzeReferences == false &&
+ AnalyzePointers == false)
+ this->configurationDiag(
+ "The check 'misc-const-correctness' will not "
+ "perform any analysis because 'AnalyzeValues', "
+ "'AnalyzeReferences' and 'AnalyzePointers' are false.");
+}
+
+void ConstCorrectnessCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "AnalyzePointers", AnalyzePointers);
+ Options.store(Opts, "AnalyzeReferences", AnalyzeReferences);
+ Options.store(Opts, "AnalyzeValues", AnalyzeValues);
+
+ Options.store(Opts, "WarnPointersAsPointers", WarnPointersAsPointers);
+ Options.store(Opts, "WarnPointersAsValues", WarnPointersAsValues);
+
+ Options.store(Opts, "TransformPointersAsPointers",
+ TransformPointersAsPointers);
+ Options.store(Opts, "TransformPointersAsValues", TransformPointersAsValues);
+ Options.store(Opts, "TransformReferences", TransformReferences);
+ Options.store(Opts, "TransformValues", TransformValues);
+
+ Options.store(Opts, "AllowedTypes",
+ utils::options::serializeStringList(AllowedTypes));
+}
+
+void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) {
+ const auto ConstType =
+ hasType(qualType(isConstQualified(),
+ // pointee check will check the constness of pointer
+ unless(pointerType())));
+
+ const auto ConstReference = hasType(references(isConstQualified()));
+ const auto RValueReference = hasType(
+ referenceType(anyOf(rValueReferenceType(), unless(isSpelledAsLValue()))));
+
+ const auto TemplateType = anyOf(
+ hasType(hasCanonicalType(templateTypeParmType())),
+ hasType(substTemplateTypeParmType()), hasType(isDependentType()),
+ // References to template types, their substitutions or typedefs to
+ // template types need to be considered as well.
+ hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType())))),
+ hasType(referenceType(pointee(substTemplateTypeParmType()))));
+
+ const auto AllowedType = hasType(qualType(anyOf(
+ hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))),
+ references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))),
+ pointerType(pointee(hasDeclaration(
+ namedDecl(matchers::matchesAnyListedName(AllowedTypes))))))));
+
+ const auto AutoTemplateType = varDecl(
+ anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType()))),
+ hasType(pointerType(pointee(autoType())))));
+
+ const auto FunctionPointerRef =
+ hasType(hasCanonicalType(referenceType(pointee(functionType()))));
+
+ // Match local variables which could be 'const' if not modified later.
+ // Example: `int i = 10` would match `int i`.
+ const auto LocalValDecl = varDecl(
+ isLocal(), hasInitializer(anything()),
+ unless(anyOf(ConstType, ConstReference, TemplateType,
+ hasInitializer(isInstantiationDependent()), AutoTemplateType,
+ RValueReference, FunctionPointerRef,
+ hasType(cxxRecordDecl(isLambda())), isImplicit(),
+ AllowedType)));
+
+ // Match the function scope for which the analysis of all local variables
+ // shall be run.
+ const auto FunctionScope =
+ functionDecl(
+ hasBody(stmt(forEachDescendant(
+ declStmt(containsAnyDeclaration(
+ LocalValDecl.bind("local-value")),
+ unless(has(decompositionDecl())))
+ .bind("decl-stmt")))
+ .bind("scope")))
+ .bind("function-decl");
+
+ Finder->addMatcher(FunctionScope, this);
+}
+
+/// Classify for a variable in what the Const-Check is interested.
+enum class VariableCategory { Value, Reference, Pointer };
+
+void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *LocalScope = Result.Nodes.getNodeAs<Stmt>("scope");
+ const auto *Variable = Result.Nodes.getNodeAs<VarDecl>("local-value");
+ const auto *Function = Result.Nodes.getNodeAs<FunctionDecl>("function-decl");
+ const auto *VarDeclStmt = Result.Nodes.getNodeAs<DeclStmt>("decl-stmt");
+ // It can not be guaranteed that the variable is declared isolated,
+ // therefore a transformation might effect the other variables as well and
+ // be incorrect.
+ const bool CanBeFixIt = VarDeclStmt != nullptr && VarDeclStmt->isSingleDecl();
+
+ /// If the variable was declared in a template it might be analyzed multiple
+ /// times. Only one of those instantiations shall emit a warning. NOTE: This
+ /// shall only deduplicate warnings for variables that are not instantiation
+ /// dependent. Variables like 'int x = 42;' in a template that can become
+ /// const emit multiple warnings otherwise.
+ bool IsNormalVariableInTemplate = Function->isTemplateInstantiation();
+ if (IsNormalVariableInTemplate &&
+ TemplateDiagnosticsCache.contains(Variable->getBeginLoc()))
+ return;
+
+ VariableCategory VC = VariableCategory::Value;
+ const QualType VT = Variable->getType();
+ if (VT->isReferenceType()) {
+ VC = VariableCategory::Reference;
+ } else if (VT->isPointerType()) {
+ VC = VariableCategory::Pointer;
+ } else if (const auto *ArrayT = dyn_cast<ArrayType>(VT)) {
+ if (ArrayT->getElementType()->isPointerType())
+ VC = VariableCategory::Pointer;
+ }
+
+ auto CheckValue = [&]() {
+ // The scope is only registered if the analysis shall be run.
+ registerScope(LocalScope, Result.Context);
+
+ // Offload const-analysis to utility function.
+ if (ScopesCache[LocalScope]->isMutated(Variable))
+ return;
+
+ auto &Diag = diag(Variable->getBeginLoc(),
+ "variable %0 of type %1 can be declared 'const'")
+ << Variable << VT;
+ if (IsNormalVariableInTemplate)
+ TemplateDiagnosticsCache.insert(Variable->getBeginLoc());
+ if (!CanBeFixIt)
+ return;
+ using namespace utils::fixit;
+ if (VC == VariableCategory::Value && TransformValues) {
+ Diag << addQualifierToVarDecl(*Variable, *Result.Context,
+ Qualifiers::Const, QualifierTarget::Value,
+ QualifierPolicy::Right);
+ // FIXME: Add '{}' for default initialization if no user-defined default
+ // constructor exists and there is no initializer.
+ return;
+ }
+
+ if (VC == VariableCategory::Reference && TransformReferences) {
+ Diag << addQualifierToVarDecl(*Variable, *Result.Context,
+ Qualifiers::Const, QualifierTarget::Value,
+ QualifierPolicy::Right);
+ return;
+ }
+
+ if (VC == VariableCategory::Pointer && TransformPointersAsValues) {
+ Diag << addQualifierToVarDecl(*Variable, *Result.Context,
+ Qualifiers::Const, QualifierTarget::Value,
+ QualifierPolicy::Right);
+ return;
+ }
+ };
+
+ auto CheckPointee = [&]() {
+ assert(VC == VariableCategory::Pointer);
+ registerScope(LocalScope, Result.Context);
+ if (ScopesCache[LocalScope]->isPointeeMutated(Variable))
+ return;
+ auto &Diag =
+ diag(Variable->getBeginLoc(),
+ "pointee of variable %0 of type %1 can be declared 'const'")
+ << Variable << VT;
+ if (IsNormalVariableInTemplate)
+ TemplateDiagnosticsCache.insert(Variable->getBeginLoc());
+ if (!CanBeFixIt)
+ return;
+ using namespace utils::fixit;
+ if (TransformPointersAsPointers) {
+ Diag << addQualifierToVarDecl(*Variable, *Result.Context,
+ Qualifiers::Const, QualifierTarget::Pointee,
+ QualifierPolicy::Right);
+ }
+ };
+
+ // Each variable can only be in one category: Value, Pointer, Reference.
+ // Analysis can be controlled for every category.
+ if (VC == VariableCategory::Value && AnalyzeValues) {
+ CheckValue();
+ return;
+ }
+ if (VC == VariableCategory::Reference && AnalyzeReferences) {
+ if (VT->getPointeeType()->isPointerType() && !WarnPointersAsValues)
+ return;
+ CheckValue();
+ return;
+ }
+ if (VC == VariableCategory::Pointer && AnalyzePointers) {
+ if (WarnPointersAsValues && !VT.isConstQualified())
+ CheckValue();
+ if (WarnPointersAsPointers) {
+ if (const auto *PT = dyn_cast<PointerType>(VT)) {
+ if (!PT->getPointeeType().isConstQualified())
+ CheckPointee();
+ }
+ if (const auto *AT = dyn_cast<ArrayType>(VT)) {
+ if (!AT->getElementType().isConstQualified()) {
+ assert(AT->getElementType()->isPointerType());
+ CheckPointee();
+ }
+ }
+ }
+ return;
+ }
+}
+
+void ConstCorrectnessCheck::registerScope(const Stmt *LocalScope,
+ ASTContext *Context) {
+ auto &Analyzer = ScopesCache[LocalScope];
+ if (!Analyzer)
+ Analyzer = std::make_unique<ExprMutationAnalyzer>(*LocalScope, *Context);
+}
+
+} // namespace clang::tidy::misc
diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp
index 3d7f792aa136b..13c2405e76df7 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -535,7 +535,7 @@ struct FragmentCompiler {
}
if (Filters->empty())
return std::nullopt;
- auto Filter = [Filters](llvm::StringRef Path) {
+ auto Filter = [Filters = std::move(Filters)](llvm::StringRef Path) {
for (auto &Regex : *Filters)
if (Regex.match(Path))
return true;
diff --git a/clang-tools-extra/clangd/Headers.cpp b/clang-tools-extra/clangd/Headers.cpp
index 0ffd9ee4d2751..0d43ada87d359 100644
--- a/clang-tools-extra/clangd/Headers.cpp
+++ b/clang-tools-extra/clangd/Headers.cpp
@@ -305,7 +305,7 @@ IncludeInserter::calculateIncludePath(const HeaderFile &InsertedHeader,
if (llvm::sys::path::is_absolute(Suggested))
return std::nullopt;
bool IsAngled = false;
- for (auto Filter : AngledHeaders) {
+ for (auto &Filter : AngledHeaders) {
if (Filter(Suggested)) {
IsAngled = true;
break;
>From 5f453ebb1910985e7bab561df0aa41b56509c810 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Wed, 2 Apr 2025 11:54:29 -0700
Subject: [PATCH 2/3] Removed added file.
---
.../misc/ConstCorrectnessCheck.cpp.1 | 272 ------------------
1 file changed, 272 deletions(-)
delete mode 100644 clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp.1
diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp.1 b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp.1
deleted file mode 100644
index cecac7628e66c..0000000000000
--- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp.1
+++ /dev/null
@@ -1,272 +0,0 @@
-//===--- ConstCorrectnessCheck.cpp - clang-tidy -----------------*- C++ -*-===//
-//
-// 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 "ConstCorrectnessCheck.h"
-#include "../utils/FixItHintUtils.h"
-#include "../utils/Matchers.h"
-#include "../utils/OptionsUtils.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include <cassert>
-
-using namespace clang::ast_matchers;
-
-namespace clang::tidy::misc {
-
-namespace {
-// FIXME: This matcher exists in some other code-review as well.
-// It should probably move to ASTMatchers.
-AST_MATCHER(VarDecl, isLocal) { return Node.isLocalVarDecl(); }
-AST_MATCHER_P(DeclStmt, containsAnyDeclaration,
- ast_matchers::internal::Matcher<Decl>, InnerMatcher) {
- return ast_matchers::internal::matchesFirstInPointerRange(
- InnerMatcher, Node.decl_begin(), Node.decl_end(), Finder,
- Builder) != Node.decl_end();
-}
-AST_MATCHER(ReferenceType, isSpelledAsLValue) {
- return Node.isSpelledAsLValue();
-}
-AST_MATCHER(Type, isDependentType) { return Node.isDependentType(); }
-} // namespace
-
-ConstCorrectnessCheck::ConstCorrectnessCheck(StringRef Name,
- ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context),
- AnalyzePointers(Options.get("AnalyzePointers", true)),
- AnalyzeReferences(Options.get("AnalyzeReferences", true)),
- AnalyzeValues(Options.get("AnalyzeValues", true)),
-
- WarnPointersAsPointers(Options.get("WarnPointersAsPointers", true)),
- WarnPointersAsValues(Options.get("WarnPointersAsValues", false)),
-
- TransformPointersAsPointers(
- Options.get("TransformPointersAsPointers", true)),
- TransformPointersAsValues(
- Options.get("TransformPointersAsValues", false)),
- TransformReferences(Options.get("TransformReferences", true)),
- TransformValues(Options.get("TransformValues", true)),
-
- AllowedTypes(
- utils::options::parseStringList(Options.get("AllowedTypes", ""))) {
- if (AnalyzeValues == false && AnalyzeReferences == false &&
- AnalyzePointers == false)
- this->configurationDiag(
- "The check 'misc-const-correctness' will not "
- "perform any analysis because 'AnalyzeValues', "
- "'AnalyzeReferences' and 'AnalyzePointers' are false.");
-}
-
-void ConstCorrectnessCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
- Options.store(Opts, "AnalyzePointers", AnalyzePointers);
- Options.store(Opts, "AnalyzeReferences", AnalyzeReferences);
- Options.store(Opts, "AnalyzeValues", AnalyzeValues);
-
- Options.store(Opts, "WarnPointersAsPointers", WarnPointersAsPointers);
- Options.store(Opts, "WarnPointersAsValues", WarnPointersAsValues);
-
- Options.store(Opts, "TransformPointersAsPointers",
- TransformPointersAsPointers);
- Options.store(Opts, "TransformPointersAsValues", TransformPointersAsValues);
- Options.store(Opts, "TransformReferences", TransformReferences);
- Options.store(Opts, "TransformValues", TransformValues);
-
- Options.store(Opts, "AllowedTypes",
- utils::options::serializeStringList(AllowedTypes));
-}
-
-void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) {
- const auto ConstType =
- hasType(qualType(isConstQualified(),
- // pointee check will check the constness of pointer
- unless(pointerType())));
-
- const auto ConstReference = hasType(references(isConstQualified()));
- const auto RValueReference = hasType(
- referenceType(anyOf(rValueReferenceType(), unless(isSpelledAsLValue()))));
-
- const auto TemplateType = anyOf(
- hasType(hasCanonicalType(templateTypeParmType())),
- hasType(substTemplateTypeParmType()), hasType(isDependentType()),
- // References to template types, their substitutions or typedefs to
- // template types need to be considered as well.
- hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType())))),
- hasType(referenceType(pointee(substTemplateTypeParmType()))));
-
- const auto AllowedType = hasType(qualType(anyOf(
- hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))),
- references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))),
- pointerType(pointee(hasDeclaration(
- namedDecl(matchers::matchesAnyListedName(AllowedTypes))))))));
-
- const auto AutoTemplateType = varDecl(
- anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType()))),
- hasType(pointerType(pointee(autoType())))));
-
- const auto FunctionPointerRef =
- hasType(hasCanonicalType(referenceType(pointee(functionType()))));
-
- // Match local variables which could be 'const' if not modified later.
- // Example: `int i = 10` would match `int i`.
- const auto LocalValDecl = varDecl(
- isLocal(), hasInitializer(anything()),
- unless(anyOf(ConstType, ConstReference, TemplateType,
- hasInitializer(isInstantiationDependent()), AutoTemplateType,
- RValueReference, FunctionPointerRef,
- hasType(cxxRecordDecl(isLambda())), isImplicit(),
- AllowedType)));
-
- // Match the function scope for which the analysis of all local variables
- // shall be run.
- const auto FunctionScope =
- functionDecl(
- hasBody(stmt(forEachDescendant(
- declStmt(containsAnyDeclaration(
- LocalValDecl.bind("local-value")),
- unless(has(decompositionDecl())))
- .bind("decl-stmt")))
- .bind("scope")))
- .bind("function-decl");
-
- Finder->addMatcher(FunctionScope, this);
-}
-
-/// Classify for a variable in what the Const-Check is interested.
-enum class VariableCategory { Value, Reference, Pointer };
-
-void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) {
- const auto *LocalScope = Result.Nodes.getNodeAs<Stmt>("scope");
- const auto *Variable = Result.Nodes.getNodeAs<VarDecl>("local-value");
- const auto *Function = Result.Nodes.getNodeAs<FunctionDecl>("function-decl");
- const auto *VarDeclStmt = Result.Nodes.getNodeAs<DeclStmt>("decl-stmt");
- // It can not be guaranteed that the variable is declared isolated,
- // therefore a transformation might effect the other variables as well and
- // be incorrect.
- const bool CanBeFixIt = VarDeclStmt != nullptr && VarDeclStmt->isSingleDecl();
-
- /// If the variable was declared in a template it might be analyzed multiple
- /// times. Only one of those instantiations shall emit a warning. NOTE: This
- /// shall only deduplicate warnings for variables that are not instantiation
- /// dependent. Variables like 'int x = 42;' in a template that can become
- /// const emit multiple warnings otherwise.
- bool IsNormalVariableInTemplate = Function->isTemplateInstantiation();
- if (IsNormalVariableInTemplate &&
- TemplateDiagnosticsCache.contains(Variable->getBeginLoc()))
- return;
-
- VariableCategory VC = VariableCategory::Value;
- const QualType VT = Variable->getType();
- if (VT->isReferenceType()) {
- VC = VariableCategory::Reference;
- } else if (VT->isPointerType()) {
- VC = VariableCategory::Pointer;
- } else if (const auto *ArrayT = dyn_cast<ArrayType>(VT)) {
- if (ArrayT->getElementType()->isPointerType())
- VC = VariableCategory::Pointer;
- }
-
- auto CheckValue = [&]() {
- // The scope is only registered if the analysis shall be run.
- registerScope(LocalScope, Result.Context);
-
- // Offload const-analysis to utility function.
- if (ScopesCache[LocalScope]->isMutated(Variable))
- return;
-
- auto &Diag = diag(Variable->getBeginLoc(),
- "variable %0 of type %1 can be declared 'const'")
- << Variable << VT;
- if (IsNormalVariableInTemplate)
- TemplateDiagnosticsCache.insert(Variable->getBeginLoc());
- if (!CanBeFixIt)
- return;
- using namespace utils::fixit;
- if (VC == VariableCategory::Value && TransformValues) {
- Diag << addQualifierToVarDecl(*Variable, *Result.Context,
- Qualifiers::Const, QualifierTarget::Value,
- QualifierPolicy::Right);
- // FIXME: Add '{}' for default initialization if no user-defined default
- // constructor exists and there is no initializer.
- return;
- }
-
- if (VC == VariableCategory::Reference && TransformReferences) {
- Diag << addQualifierToVarDecl(*Variable, *Result.Context,
- Qualifiers::Const, QualifierTarget::Value,
- QualifierPolicy::Right);
- return;
- }
-
- if (VC == VariableCategory::Pointer && TransformPointersAsValues) {
- Diag << addQualifierToVarDecl(*Variable, *Result.Context,
- Qualifiers::Const, QualifierTarget::Value,
- QualifierPolicy::Right);
- return;
- }
- };
-
- auto CheckPointee = [&]() {
- assert(VC == VariableCategory::Pointer);
- registerScope(LocalScope, Result.Context);
- if (ScopesCache[LocalScope]->isPointeeMutated(Variable))
- return;
- auto &Diag =
- diag(Variable->getBeginLoc(),
- "pointee of variable %0 of type %1 can be declared 'const'")
- << Variable << VT;
- if (IsNormalVariableInTemplate)
- TemplateDiagnosticsCache.insert(Variable->getBeginLoc());
- if (!CanBeFixIt)
- return;
- using namespace utils::fixit;
- if (TransformPointersAsPointers) {
- Diag << addQualifierToVarDecl(*Variable, *Result.Context,
- Qualifiers::Const, QualifierTarget::Pointee,
- QualifierPolicy::Right);
- }
- };
-
- // Each variable can only be in one category: Value, Pointer, Reference.
- // Analysis can be controlled for every category.
- if (VC == VariableCategory::Value && AnalyzeValues) {
- CheckValue();
- return;
- }
- if (VC == VariableCategory::Reference && AnalyzeReferences) {
- if (VT->getPointeeType()->isPointerType() && !WarnPointersAsValues)
- return;
- CheckValue();
- return;
- }
- if (VC == VariableCategory::Pointer && AnalyzePointers) {
- if (WarnPointersAsValues && !VT.isConstQualified())
- CheckValue();
- if (WarnPointersAsPointers) {
- if (const auto *PT = dyn_cast<PointerType>(VT)) {
- if (!PT->getPointeeType().isConstQualified())
- CheckPointee();
- }
- if (const auto *AT = dyn_cast<ArrayType>(VT)) {
- if (!AT->getElementType().isConstQualified()) {
- assert(AT->getElementType()->isPointerType());
- CheckPointee();
- }
- }
- }
- return;
- }
-}
-
-void ConstCorrectnessCheck::registerScope(const Stmt *LocalScope,
- ASTContext *Context) {
- auto &Analyzer = ScopesCache[LocalScope];
- if (!Analyzer)
- Analyzer = std::make_unique<ExprMutationAnalyzer>(*LocalScope, *Context);
-}
-
-} // namespace clang::tidy::misc
>From c9bfb4495dbf26d5c207a2e8f5261add3bff34ae Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Thu, 3 Apr 2025 12:11:08 -0700
Subject: [PATCH 3/3] Added the & at line 315 of Headers.cpp.
---
clang-tools-extra/clangd/Headers.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/clangd/Headers.cpp b/clang-tools-extra/clangd/Headers.cpp
index 0d43ada87d359..87fd261b906e6 100644
--- a/clang-tools-extra/clangd/Headers.cpp
+++ b/clang-tools-extra/clangd/Headers.cpp
@@ -312,7 +312,7 @@ IncludeInserter::calculateIncludePath(const HeaderFile &InsertedHeader,
}
}
bool IsQuoted = false;
- for (auto Filter : QuotedHeaders) {
+ for (auto &Filter : QuotedHeaders) {
if (Filter(Suggested)) {
IsQuoted = true;
break;
More information about the cfe-commits
mailing list