[clang] [clang-tools-extra] [clang][dataflow][WIP] Add bugprone-dataflow-dead-code check (PR #139068)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 8 05:04:53 PDT 2025
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- clang-tools-extra/clang-tidy/bugprone/DataflowDeadCodeCheck.cpp clang-tools-extra/clang-tidy/bugprone/DataflowDeadCodeCheck.h clang-tools-extra/test/clang-tidy/checkers/bugprone/dataflow-dead-code.cpp clang/include/clang/Analysis/FlowSensitive/Models/DeadCodeModel.h clang/lib/Analysis/FlowSensitive/Models/DeadCodeModel.cpp clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp clang-tools-extra/clangd/TidyProvider.cpp
``````````
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/clang-tools-extra/clang-tidy/bugprone/DataflowDeadCodeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DataflowDeadCodeCheck.cpp
index c999be784..2fe1519fa 100644
--- a/clang-tools-extra/clang-tidy/bugprone/DataflowDeadCodeCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/DataflowDeadCodeCheck.cpp
@@ -16,8 +16,8 @@
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
-#include "clang/Analysis/FlowSensitive/NoopAnalysis.h"
#include "clang/Analysis/FlowSensitive/Models/DeadCodeModel.h"
+#include "clang/Analysis/FlowSensitive/NoopAnalysis.h"
#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/Any.h"
@@ -30,8 +30,8 @@
namespace clang::tidy::bugprone {
using ast_matchers::MatchFinder;
-using dataflow::DeadCodeModel;
using dataflow::DeadCodeDiagnoser;
+using dataflow::DeadCodeModel;
using dataflow::NoopAnalysis;
using Diagnoser = DeadCodeDiagnoser;
@@ -44,8 +44,7 @@ struct ExpandedResult {
using ResultType = Diagnoser::ResultType;
-static std::optional<ResultType>
-analyzeFunction(const FunctionDecl &FuncDecl) {
+static std::optional<ResultType> analyzeFunction(const FunctionDecl &FuncDecl) {
using dataflow::AdornedCFG;
using dataflow::DataflowAnalysisState;
using llvm::Expected;
@@ -68,9 +67,11 @@ analyzeFunction(const FunctionDecl &FuncDecl) {
Diagnoser Diagnoser;
ResultType Diagnostics;
-
- if (llvm::Error E = dataflow::diagnoseFunction<DeadCodeModel, Diagnoser::DiagnosticEntry>(
- FuncDecl, ASTCtx, Diagnoser).moveInto(Diagnostics)) {
+
+ if (llvm::Error E =
+ dataflow::diagnoseFunction<DeadCodeModel, Diagnoser::DiagnosticEntry>(
+ FuncDecl, ASTCtx, Diagnoser)
+ .moveInto(Diagnostics)) {
llvm::dbgs() << "Dataflow analysis failed: " << llvm::toString(std::move(E))
<< ".\n";
return std::nullopt;
@@ -82,18 +83,18 @@ analyzeFunction(const FunctionDecl &FuncDecl) {
void DataflowDeadCodeCheck::registerMatchers(MatchFinder *Finder) {
using namespace ast_matchers;
Finder->addMatcher(
- decl(anyOf(functionDecl(unless(isExpansionInSystemHeader()),
- // FIXME: Remove the filter below when lambdas are
- // well supported by the check.
- unless(hasDeclContext(cxxRecordDecl(isLambda())))),
- cxxConstructorDecl(
- unless(hasDeclContext(cxxRecordDecl(isLambda()))))))
+ decl(
+ anyOf(functionDecl(unless(isExpansionInSystemHeader()),
+ // FIXME: Remove the filter below when lambdas are
+ // well supported by the check.
+ unless(hasDeclContext(cxxRecordDecl(isLambda())))),
+ cxxConstructorDecl(
+ unless(hasDeclContext(cxxRecordDecl(isLambda()))))))
.bind(FuncID),
this);
}
-void DataflowDeadCodeCheck::check(
- const MatchFinder::MatchResult &Result) {
+void DataflowDeadCodeCheck::check(const MatchFinder::MatchResult &Result) {
if (Result.SourceManager->getDiagnostics().hasUncompilableErrorOccurred())
return;
@@ -111,8 +112,7 @@ void DataflowDeadCodeCheck::check(
break;
case Diagnoser::DiagnosticType::AlwaysFalse:
- diag(Loc,
- "dead code - branching condition is always false");
+ diag(Loc, "dead code - branching condition is always false");
break;
}
}
diff --git a/clang-tools-extra/clangd/TidyProvider.cpp b/clang-tools-extra/clangd/TidyProvider.cpp
index e7c34ab97..bd35dc5ab 100644
--- a/clang-tools-extra/clangd/TidyProvider.cpp
+++ b/clang-tools-extra/clangd/TidyProvider.cpp
@@ -222,8 +222,7 @@ TidyProvider disableUnusableChecks(llvm::ArrayRef<std::string> ExtraBadChecks) {
"-hicpp-invalid-access-moved",
// Check uses dataflow analysis, which might hang/crash unexpectedly on
// incomplete code.
- "-bugprone-dataflow-dead-code",
- "-bugprone-unchecked-optional-access");
+ "-bugprone-dataflow-dead-code", "-bugprone-unchecked-optional-access");
size_t Size = BadChecks.size();
for (const std::string &Str : ExtraBadChecks) {
diff --git a/clang/include/clang/Analysis/FlowSensitive/Models/DeadCodeModel.h b/clang/include/clang/Analysis/FlowSensitive/Models/DeadCodeModel.h
index 7a914bafc..a44ce3c7a 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Models/DeadCodeModel.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Models/DeadCodeModel.h
@@ -31,32 +31,33 @@ namespace clang::dataflow {
class DeadCodeModel : public DataflowAnalysis<DeadCodeModel, NoopLattice> {
public:
explicit DeadCodeModel(ASTContext &Context)
- : DataflowAnalysis<DeadCodeModel, NoopLattice>(Context) {}
+ : DataflowAnalysis<DeadCodeModel, NoopLattice>(Context) {}
static NoopLattice initialElement() { return {}; }
void transfer(const CFGElement &E, NoopLattice &State, Environment &Env) {}
- void transferBranch(bool Branch, const Stmt *S, NoopLattice &State, Environment &Env);
+ void transferBranch(bool Branch, const Stmt *S, NoopLattice &State,
+ Environment &Env);
};
class DeadCodeDiagnoser {
public:
-
/// Returns source locations for pointers that were checked when known to be
// null, and checked after already dereferenced, respectively.
enum class DiagnosticType { AlwaysTrue, AlwaysFalse };
struct DiagnosticEntry {
- SourceLocation Location;
- DiagnosticType Type;
+ SourceLocation Location;
+ DiagnosticType Type;
};
using ResultType = llvm::SmallVector<DiagnosticEntry>;
+
private:
CFGMatchSwitch<const Environment, ResultType> DiagnoseMatchSwitch;
public:
-DeadCodeDiagnoser();
+ DeadCodeDiagnoser();
ResultType operator()(const CFGElement &Elt, ASTContext &Ctx,
const TransferStateForDiagnostics<NoopLattice> &State);
diff --git a/clang/lib/Analysis/FlowSensitive/Models/DeadCodeModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/DeadCodeModel.cpp
index 841e2764b..530a9cc0b 100644
--- a/clang/lib/Analysis/FlowSensitive/Models/DeadCodeModel.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Models/DeadCodeModel.cpp
@@ -31,13 +31,13 @@ using Diagnoser = DeadCodeDiagnoser;
constexpr char kCond[] = "condition";
auto conditionMatcher() {
-return expr(allOf(hasType(booleanType()),
- unless(cxxBoolLiteral())))
- .bind(kCond);
+ return expr(allOf(hasType(booleanType()), unless(cxxBoolLiteral())))
+ .bind(kCond);
}
-DeadCodeDiagnoser::ResultType diagnoseAnyDeadCondition(const Expr *S,
- const MatchFinder::MatchResult &Result, const Environment &Env) {
+DeadCodeDiagnoser::ResultType
+diagnoseAnyDeadCondition(const Expr *S, const MatchFinder::MatchResult &Result,
+ const Environment &Env) {
const auto *Cond = Result.Nodes.getNodeAs<Expr>(kCond);
assert(Cond != nullptr);
@@ -52,35 +52,34 @@ DeadCodeDiagnoser::ResultType diagnoseAnyDeadCondition(const Expr *S,
if (BoolValue *CondValue = cast_or_null<BoolValue>(Env.getValue(*Cond))) {
if (Env.proves(CondValue->formula())) {
- return {{ Cond->getBeginLoc(), Diagnoser::DiagnosticType::AlwaysTrue }};
+ return {{Cond->getBeginLoc(), Diagnoser::DiagnosticType::AlwaysTrue}};
}
if (Env.proves(Env.arena().makeNot(CondValue->formula()))) {
- return {{ Cond->getBeginLoc(), Diagnoser::DiagnosticType::AlwaysFalse }};
+ return {{Cond->getBeginLoc(), Diagnoser::DiagnosticType::AlwaysFalse}};
}
}
return {};
}
-
DeadCodeDiagnoser::ResultType catchall(const Stmt *S,
- const MatchFinder::MatchResult &Result, const Environment &Env) {
+ const MatchFinder::MatchResult &Result,
+ const Environment &Env) {
S->dump();
return {};
}
-
auto buildDiagnoseMatchSwitch() {
return CFGMatchSwitchBuilder<const Environment, Diagnoser::ResultType>()
- .CaseOfCFGStmt<Expr>(conditionMatcher(), diagnoseAnyDeadCondition)
- .Build();
+ .CaseOfCFGStmt<Expr>(conditionMatcher(), diagnoseAnyDeadCondition)
+ .Build();
}
} // namespace
void DeadCodeModel::transferBranch(bool Branch, const Stmt *S,
- NoopLattice &State, Environment &Env) {
+ NoopLattice &State, Environment &Env) {
if (!S || !isa<Expr>(S))
return;
@@ -93,12 +92,12 @@ void DeadCodeModel::transferBranch(bool Branch, const Stmt *S,
}
DeadCodeDiagnoser::DeadCodeDiagnoser()
-: DiagnoseMatchSwitch(buildDiagnoseMatchSwitch()) {}
+ : DiagnoseMatchSwitch(buildDiagnoseMatchSwitch()) {}
DeadCodeDiagnoser::ResultType DeadCodeDiagnoser::operator()(
- const CFGElement &Elt, ASTContext &Ctx,
- const TransferStateForDiagnostics<NoopLattice> &State) {
-return DiagnoseMatchSwitch(Elt, Ctx, State.Env);
+ const CFGElement &Elt, ASTContext &Ctx,
+ const TransferStateForDiagnostics<NoopLattice> &State) {
+ return DiagnoseMatchSwitch(Elt, Ctx, State.Env);
}
} // namespace clang::dataflow
\ No newline at end of file
``````````
</details>
https://github.com/llvm/llvm-project/pull/139068
More information about the cfe-commits
mailing list