Skip to content

Commit 69f4445

Browse files
committed
[clang][dataflow] Refactor PropagateResultObject() with a switch statement.
See also discussion in #88726.
1 parent 9f3334e commit 69f4445

File tree

1 file changed

+50
-36
lines changed

1 file changed

+50
-36
lines changed

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -414,25 +414,52 @@ class ResultObjectVisitor : public RecursiveASTVisitor<ResultObjectVisitor> {
414414

415415
ResultObjectMap[E] = Loc;
416416

417+
switch (E->getStmtClass()) {
417418
// The following AST node kinds are "original initializers": They are the
418419
// lowest-level AST node that initializes a given object, and nothing
419420
// below them can initialize the same object (or part of it).
420-
if (isa<CXXConstructExpr>(E) || isa<CallExpr>(E) || isa<LambdaExpr>(E) ||
421-
isa<CXXDefaultArgExpr>(E) || isa<CXXDefaultInitExpr>(E) ||
422-
isa<CXXStdInitializerListExpr>(E) ||
423-
// We treat `BuiltinBitCastExpr` as an "original initializer" too as
424-
// it may not even be casting from a record type -- and even if it is,
425-
// the two objects are in general of unrelated type.
426-
isa<BuiltinBitCastExpr>(E)) {
421+
case Stmt::CXXConstructExprClass:
422+
case Stmt::CallExprClass:
423+
case Stmt::LambdaExprClass:
424+
case Stmt::CXXDefaultArgExprClass:
425+
case Stmt::CXXDefaultInitExprClass:
426+
case Stmt::CXXStdInitializerListExprClass:
427+
// We treat `BuiltinBitCastExpr` as an "original initializer" too as it may
428+
// not even be casting from a record type -- and even if it is, the two
429+
// objects are in general of unrelated type.
430+
case Stmt::BuiltinBitCastExprClass:
431+
return;
432+
case Stmt::BinaryOperatorClass: {
433+
auto *Op = cast<BinaryOperator>(E);
434+
if (Op->getOpcode() == BO_Cmp) {
435+
// Builtin `<=>` returns a `std::strong_ordering` object. We
436+
// consider this to be an "original" initializer too (see above).
437+
return;
438+
}
439+
if (Op->isCommaOp()) {
440+
PropagateResultObject(Op->getRHS(), Loc);
441+
return;
442+
}
443+
// We don't expect any other binary operators to produce a record
444+
// prvalue, so if we get here, we've hit some case we don't know
445+
// about.
446+
assert(false);
427447
return;
428448
}
429-
if (auto *Op = dyn_cast<BinaryOperator>(E);
430-
Op && Op->getOpcode() == BO_Cmp) {
431-
// Builtin `<=>` returns a `std::strong_ordering` object.
449+
case Stmt::BinaryConditionalOperatorClass:
450+
case Stmt::ConditionalOperatorClass: {
451+
auto *Cond = cast<AbstractConditionalOperator>(E);
452+
PropagateResultObject(Cond->getTrueExpr(), Loc);
453+
PropagateResultObject(Cond->getFalseExpr(), Loc);
432454
return;
433455
}
434-
435-
if (auto *InitList = dyn_cast<InitListExpr>(E)) {
456+
case Stmt::StmtExprClass: {
457+
auto *SE = cast<StmtExpr>(E);
458+
PropagateResultObject(cast<Expr>(SE->getSubStmt()->body_back()), Loc);
459+
return;
460+
}
461+
case Stmt::InitListExprClass: {
462+
auto *InitList = cast<InitListExpr>(E);
436463
if (!InitList->isSemanticForm())
437464
return;
438465
if (InitList->isTransparent()) {
@@ -462,33 +489,20 @@ class ResultObjectVisitor : public RecursiveASTVisitor<ResultObjectVisitor> {
462489
}
463490
return;
464491
}
465-
466-
if (auto *Op = dyn_cast<BinaryOperator>(E); Op && Op->isCommaOp()) {
467-
PropagateResultObject(Op->getRHS(), Loc);
492+
default: {
493+
// All other expression nodes that propagate a record prvalue should
494+
// have exactly one child.
495+
SmallVector<Stmt *, 1> Children(E->child_begin(), E->child_end());
496+
LLVM_DEBUG({
497+
if (Children.size() != 1)
498+
E->dump();
499+
});
500+
assert(Children.size() == 1);
501+
for (Stmt *S : Children)
502+
PropagateResultObject(cast<Expr>(S), Loc);
468503
return;
469504
}
470-
471-
if (auto *Cond = dyn_cast<AbstractConditionalOperator>(E)) {
472-
PropagateResultObject(Cond->getTrueExpr(), Loc);
473-
PropagateResultObject(Cond->getFalseExpr(), Loc);
474-
return;
475505
}
476-
477-
if (auto *SE = dyn_cast<StmtExpr>(E)) {
478-
PropagateResultObject(cast<Expr>(SE->getSubStmt()->body_back()), Loc);
479-
return;
480-
}
481-
482-
// All other expression nodes that propagate a record prvalue should have
483-
// exactly one child.
484-
SmallVector<Stmt *, 1> Children(E->child_begin(), E->child_end());
485-
LLVM_DEBUG({
486-
if (Children.size() != 1)
487-
E->dump();
488-
});
489-
assert(Children.size() == 1);
490-
for (Stmt *S : Children)
491-
PropagateResultObject(cast<Expr>(S), Loc);
492506
}
493507

494508
private:

0 commit comments

Comments
 (0)