-
Notifications
You must be signed in to change notification settings - Fork 12.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][analysis] refactor the unevaluated api #117474
base: main
Are you sure you want to change the base?
Conversation
It is unclear for `ExprMutationAnalyzer::isUnevaluated` to accept 2 Stmt. Redesign the API to accept only 1 Stmt and the API will only check whether stmt is substmt of an unevaluated stmt.
@llvm/pr-subscribers-clang-tools-extra @llvm/pr-subscribers-clang-analysis Author: Congcong Cai (HerrCai0907) ChangesIt is unclear for Full diff: https://github.com/llvm/llvm-project/pull/117474.diff 3 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
index e329588290cd4b..2b2d80ea9346bd 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -303,7 +303,7 @@ void InfiniteLoopCheck::check(const MatchFinder::MatchResult &Result) {
}
}
- if (ExprMutationAnalyzer::isUnevaluated(LoopStmt, *LoopStmt, *Result.Context))
+ if (ExprMutationAnalyzer::isUnevaluated(LoopStmt, *Result.Context))
return;
if (isAtLeastOneCondVarChanged(Func, LoopStmt, Cond, Result.Context))
diff --git a/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
index c7a5b016c949d0..7442f4aad531b7 100644
--- a/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
+++ b/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
@@ -47,8 +47,6 @@ class ExprMutationAnalyzer {
const Stmt *findPointeeMutation(const Expr *Exp);
const Stmt *findPointeeMutation(const Decl *Dec);
- static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
- ASTContext &Context);
private:
using MutationFinder = const Stmt *(Analyzer::*)(const Expr *);
@@ -58,8 +56,6 @@ class ExprMutationAnalyzer {
Memoized::ResultMap &MemoizedResults);
const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
- bool isUnevaluated(const Expr *Exp);
-
const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
const Stmt *
@@ -83,6 +79,10 @@ class ExprMutationAnalyzer {
ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
: Memorized(), A(Stm, Context, Memorized) {}
+ /// check whether stmt is unevaluated. mutation analyzer will ignore the
+ /// content in unevaluated stmt.
+ static bool isUnevaluated(const Stmt *Stm, ASTContext &Context);
+
bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
const Stmt *findMutation(const Expr *Exp) { return A.findMutation(Exp); }
@@ -101,11 +101,6 @@ class ExprMutationAnalyzer {
return A.findPointeeMutation(Dec);
}
- static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
- ASTContext &Context) {
- return Analyzer::isUnevaluated(Smt, Stm, Context);
- }
-
private:
Memoized Memorized;
Analyzer A;
diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
index a94b22e051d0e1..be0e8aa5743dd9 100644
--- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -236,7 +236,7 @@ const Stmt *ExprMutationAnalyzer::Analyzer::findMutationMemoized(
if (!Inserted)
return Memoized->second;
- if (isUnevaluated(Exp))
+ if (ExprMutationAnalyzer::isUnevaluated(Exp, Context))
return nullptr;
for (const auto &Finder : Finders) {
@@ -268,41 +268,29 @@ ExprMutationAnalyzer::Analyzer::tryEachDeclRef(const Decl *Dec,
return nullptr;
}
-bool ExprMutationAnalyzer::Analyzer::isUnevaluated(const Stmt *Exp,
- const Stmt &Stm,
- ASTContext &Context) {
- return selectFirst<Stmt>(
- NodeID<Expr>::value,
- match(
- findFirst(
- stmt(canResolveToExpr(Exp),
- anyOf(
- // `Exp` is part of the underlying expression of
- // decltype/typeof if it has an ancestor of
- // typeLoc.
- hasAncestor(typeLoc(unless(
- hasAncestor(unaryExprOrTypeTraitExpr())))),
- hasAncestor(expr(anyOf(
- // `UnaryExprOrTypeTraitExpr` is unevaluated
- // unless it's sizeof on VLA.
- unaryExprOrTypeTraitExpr(unless(sizeOfExpr(
- hasArgumentOfType(variableArrayType())))),
- // `CXXTypeidExpr` is unevaluated unless it's
- // applied to an expression of glvalue of
- // polymorphic class type.
- cxxTypeidExpr(
- unless(isPotentiallyEvaluated())),
- // The controlling expression of
- // `GenericSelectionExpr` is unevaluated.
- genericSelectionExpr(hasControllingExpr(
- hasDescendant(equalsNode(Exp)))),
- cxxNoexceptExpr())))))
- .bind(NodeID<Expr>::value)),
- Stm, Context)) != nullptr;
-}
-
-bool ExprMutationAnalyzer::Analyzer::isUnevaluated(const Expr *Exp) {
- return isUnevaluated(Exp, Stm, Context);
+bool ExprMutationAnalyzer::isUnevaluated(const Stmt *Stm, ASTContext &Context) {
+ return !match(stmt(anyOf(
+ // `Exp` is part of the underlying expression of
+ // decltype/typeof if it has an ancestor of
+ // typeLoc.
+ hasAncestor(typeLoc(
+ unless(hasAncestor(unaryExprOrTypeTraitExpr())))),
+ hasAncestor(expr(anyOf(
+ // `UnaryExprOrTypeTraitExpr` is unevaluated
+ // unless it's sizeof on VLA.
+ unaryExprOrTypeTraitExpr(unless(sizeOfExpr(
+ hasArgumentOfType(variableArrayType())))),
+ // `CXXTypeidExpr` is unevaluated unless it's
+ // applied to an expression of glvalue of
+ // polymorphic class type.
+ cxxTypeidExpr(unless(isPotentiallyEvaluated())),
+ // The controlling expression of
+ // `GenericSelectionExpr` is unevaluated.
+ genericSelectionExpr(
+ hasControllingExpr(hasDescendant(equalsNode(Stm)))),
+ cxxNoexceptExpr()))))),
+ *Stm, Context)
+ .empty();
}
const Stmt *
|
@llvm/pr-subscribers-clang Author: Congcong Cai (HerrCai0907) ChangesIt is unclear for Full diff: https://github.com/llvm/llvm-project/pull/117474.diff 3 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
index e329588290cd4b..2b2d80ea9346bd 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -303,7 +303,7 @@ void InfiniteLoopCheck::check(const MatchFinder::MatchResult &Result) {
}
}
- if (ExprMutationAnalyzer::isUnevaluated(LoopStmt, *LoopStmt, *Result.Context))
+ if (ExprMutationAnalyzer::isUnevaluated(LoopStmt, *Result.Context))
return;
if (isAtLeastOneCondVarChanged(Func, LoopStmt, Cond, Result.Context))
diff --git a/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
index c7a5b016c949d0..7442f4aad531b7 100644
--- a/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
+++ b/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
@@ -47,8 +47,6 @@ class ExprMutationAnalyzer {
const Stmt *findPointeeMutation(const Expr *Exp);
const Stmt *findPointeeMutation(const Decl *Dec);
- static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
- ASTContext &Context);
private:
using MutationFinder = const Stmt *(Analyzer::*)(const Expr *);
@@ -58,8 +56,6 @@ class ExprMutationAnalyzer {
Memoized::ResultMap &MemoizedResults);
const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
- bool isUnevaluated(const Expr *Exp);
-
const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
const Stmt *
@@ -83,6 +79,10 @@ class ExprMutationAnalyzer {
ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
: Memorized(), A(Stm, Context, Memorized) {}
+ /// check whether stmt is unevaluated. mutation analyzer will ignore the
+ /// content in unevaluated stmt.
+ static bool isUnevaluated(const Stmt *Stm, ASTContext &Context);
+
bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
const Stmt *findMutation(const Expr *Exp) { return A.findMutation(Exp); }
@@ -101,11 +101,6 @@ class ExprMutationAnalyzer {
return A.findPointeeMutation(Dec);
}
- static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
- ASTContext &Context) {
- return Analyzer::isUnevaluated(Smt, Stm, Context);
- }
-
private:
Memoized Memorized;
Analyzer A;
diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
index a94b22e051d0e1..be0e8aa5743dd9 100644
--- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -236,7 +236,7 @@ const Stmt *ExprMutationAnalyzer::Analyzer::findMutationMemoized(
if (!Inserted)
return Memoized->second;
- if (isUnevaluated(Exp))
+ if (ExprMutationAnalyzer::isUnevaluated(Exp, Context))
return nullptr;
for (const auto &Finder : Finders) {
@@ -268,41 +268,29 @@ ExprMutationAnalyzer::Analyzer::tryEachDeclRef(const Decl *Dec,
return nullptr;
}
-bool ExprMutationAnalyzer::Analyzer::isUnevaluated(const Stmt *Exp,
- const Stmt &Stm,
- ASTContext &Context) {
- return selectFirst<Stmt>(
- NodeID<Expr>::value,
- match(
- findFirst(
- stmt(canResolveToExpr(Exp),
- anyOf(
- // `Exp` is part of the underlying expression of
- // decltype/typeof if it has an ancestor of
- // typeLoc.
- hasAncestor(typeLoc(unless(
- hasAncestor(unaryExprOrTypeTraitExpr())))),
- hasAncestor(expr(anyOf(
- // `UnaryExprOrTypeTraitExpr` is unevaluated
- // unless it's sizeof on VLA.
- unaryExprOrTypeTraitExpr(unless(sizeOfExpr(
- hasArgumentOfType(variableArrayType())))),
- // `CXXTypeidExpr` is unevaluated unless it's
- // applied to an expression of glvalue of
- // polymorphic class type.
- cxxTypeidExpr(
- unless(isPotentiallyEvaluated())),
- // The controlling expression of
- // `GenericSelectionExpr` is unevaluated.
- genericSelectionExpr(hasControllingExpr(
- hasDescendant(equalsNode(Exp)))),
- cxxNoexceptExpr())))))
- .bind(NodeID<Expr>::value)),
- Stm, Context)) != nullptr;
-}
-
-bool ExprMutationAnalyzer::Analyzer::isUnevaluated(const Expr *Exp) {
- return isUnevaluated(Exp, Stm, Context);
+bool ExprMutationAnalyzer::isUnevaluated(const Stmt *Stm, ASTContext &Context) {
+ return !match(stmt(anyOf(
+ // `Exp` is part of the underlying expression of
+ // decltype/typeof if it has an ancestor of
+ // typeLoc.
+ hasAncestor(typeLoc(
+ unless(hasAncestor(unaryExprOrTypeTraitExpr())))),
+ hasAncestor(expr(anyOf(
+ // `UnaryExprOrTypeTraitExpr` is unevaluated
+ // unless it's sizeof on VLA.
+ unaryExprOrTypeTraitExpr(unless(sizeOfExpr(
+ hasArgumentOfType(variableArrayType())))),
+ // `CXXTypeidExpr` is unevaluated unless it's
+ // applied to an expression of glvalue of
+ // polymorphic class type.
+ cxxTypeidExpr(unless(isPotentiallyEvaluated())),
+ // The controlling expression of
+ // `GenericSelectionExpr` is unevaluated.
+ genericSelectionExpr(
+ hasControllingExpr(hasDescendant(equalsNode(Stm)))),
+ cxxNoexceptExpr()))))),
+ *Stm, Context)
+ .empty();
}
const Stmt *
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
It is hard to understand for
ExprMutationAnalyzer::isUnevaluated
to accept 2 Stmt as parameters.This patch wants to redesign the API to accept only 1 Stmt. Now it will only check whether stmt is a sub-stmt of an unevaluated stmt.