Skip to content

Commit b41b8ea

Browse files
committed
[clang][analysis] refactor the unevaluated api
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.
1 parent 68a48ec commit b41b8ea

File tree

3 files changed

+29
-46
lines changed

3 files changed

+29
-46
lines changed

clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ void InfiniteLoopCheck::check(const MatchFinder::MatchResult &Result) {
303303
}
304304
}
305305

306-
if (ExprMutationAnalyzer::isUnevaluated(LoopStmt, *LoopStmt, *Result.Context))
306+
if (ExprMutationAnalyzer::isUnevaluated(LoopStmt, *Result.Context))
307307
return;
308308

309309
if (isAtLeastOneCondVarChanged(Func, LoopStmt, Cond, Result.Context))

clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ class ExprMutationAnalyzer {
4747

4848
const Stmt *findPointeeMutation(const Expr *Exp);
4949
const Stmt *findPointeeMutation(const Decl *Dec);
50-
static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
51-
ASTContext &Context);
5250

5351
private:
5452
using MutationFinder = const Stmt *(Analyzer::*)(const Expr *);
@@ -58,8 +56,6 @@ class ExprMutationAnalyzer {
5856
Memoized::ResultMap &MemoizedResults);
5957
const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
6058

61-
bool isUnevaluated(const Expr *Exp);
62-
6359
const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
6460
const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
6561
const Stmt *
@@ -83,6 +79,10 @@ class ExprMutationAnalyzer {
8379
ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
8480
: Memorized(), A(Stm, Context, Memorized) {}
8581

82+
/// check whether stmt is unevaluated. mutation analyzer will ignore the
83+
/// content in unevaluated stmt.
84+
static bool isUnevaluated(const Stmt *Stm, ASTContext &Context);
85+
8686
bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
8787
bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
8888
const Stmt *findMutation(const Expr *Exp) { return A.findMutation(Exp); }
@@ -101,11 +101,6 @@ class ExprMutationAnalyzer {
101101
return A.findPointeeMutation(Dec);
102102
}
103103

104-
static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
105-
ASTContext &Context) {
106-
return Analyzer::isUnevaluated(Smt, Stm, Context);
107-
}
108-
109104
private:
110105
Memoized Memorized;
111106
Analyzer A;

clang/lib/Analysis/ExprMutationAnalyzer.cpp

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ const Stmt *ExprMutationAnalyzer::Analyzer::findMutationMemoized(
236236
if (!Inserted)
237237
return Memoized->second;
238238

239-
if (isUnevaluated(Exp))
239+
if (ExprMutationAnalyzer::isUnevaluated(Exp, Context))
240240
return nullptr;
241241

242242
for (const auto &Finder : Finders) {
@@ -268,41 +268,29 @@ ExprMutationAnalyzer::Analyzer::tryEachDeclRef(const Decl *Dec,
268268
return nullptr;
269269
}
270270

271-
bool ExprMutationAnalyzer::Analyzer::isUnevaluated(const Stmt *Exp,
272-
const Stmt &Stm,
273-
ASTContext &Context) {
274-
return selectFirst<Stmt>(
275-
NodeID<Expr>::value,
276-
match(
277-
findFirst(
278-
stmt(canResolveToExpr(Exp),
279-
anyOf(
280-
// `Exp` is part of the underlying expression of
281-
// decltype/typeof if it has an ancestor of
282-
// typeLoc.
283-
hasAncestor(typeLoc(unless(
284-
hasAncestor(unaryExprOrTypeTraitExpr())))),
285-
hasAncestor(expr(anyOf(
286-
// `UnaryExprOrTypeTraitExpr` is unevaluated
287-
// unless it's sizeof on VLA.
288-
unaryExprOrTypeTraitExpr(unless(sizeOfExpr(
289-
hasArgumentOfType(variableArrayType())))),
290-
// `CXXTypeidExpr` is unevaluated unless it's
291-
// applied to an expression of glvalue of
292-
// polymorphic class type.
293-
cxxTypeidExpr(
294-
unless(isPotentiallyEvaluated())),
295-
// The controlling expression of
296-
// `GenericSelectionExpr` is unevaluated.
297-
genericSelectionExpr(hasControllingExpr(
298-
hasDescendant(equalsNode(Exp)))),
299-
cxxNoexceptExpr())))))
300-
.bind(NodeID<Expr>::value)),
301-
Stm, Context)) != nullptr;
302-
}
303-
304-
bool ExprMutationAnalyzer::Analyzer::isUnevaluated(const Expr *Exp) {
305-
return isUnevaluated(Exp, Stm, Context);
271+
bool ExprMutationAnalyzer::isUnevaluated(const Stmt *Stm, ASTContext &Context) {
272+
return !match(stmt(anyOf(
273+
// `Exp` is part of the underlying expression of
274+
// decltype/typeof if it has an ancestor of
275+
// typeLoc.
276+
hasAncestor(typeLoc(
277+
unless(hasAncestor(unaryExprOrTypeTraitExpr())))),
278+
hasAncestor(expr(anyOf(
279+
// `UnaryExprOrTypeTraitExpr` is unevaluated
280+
// unless it's sizeof on VLA.
281+
unaryExprOrTypeTraitExpr(unless(sizeOfExpr(
282+
hasArgumentOfType(variableArrayType())))),
283+
// `CXXTypeidExpr` is unevaluated unless it's
284+
// applied to an expression of glvalue of
285+
// polymorphic class type.
286+
cxxTypeidExpr(unless(isPotentiallyEvaluated())),
287+
// The controlling expression of
288+
// `GenericSelectionExpr` is unevaluated.
289+
genericSelectionExpr(
290+
hasControllingExpr(hasDescendant(equalsNode(Stm)))),
291+
cxxNoexceptExpr()))))),
292+
*Stm, Context)
293+
.empty();
306294
}
307295

308296
const Stmt *

0 commit comments

Comments
 (0)