Skip to content

[clang][dataflow] Refactor PropagateResultObject() with a switch statement. #88865

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

Merged
merged 1 commit into from
Apr 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 50 additions & 36 deletions clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,25 +414,52 @@ class ResultObjectVisitor : public RecursiveASTVisitor<ResultObjectVisitor> {

ResultObjectMap[E] = Loc;

switch (E->getStmtClass()) {
// The following AST node kinds are "original initializers": They are the
// lowest-level AST node that initializes a given object, and nothing
// below them can initialize the same object (or part of it).
if (isa<CXXConstructExpr>(E) || isa<CallExpr>(E) || isa<LambdaExpr>(E) ||
isa<CXXDefaultArgExpr>(E) || isa<CXXDefaultInitExpr>(E) ||
isa<CXXStdInitializerListExpr>(E) ||
// We treat `BuiltinBitCastExpr` as an "original initializer" too as
// it may not even be casting from a record type -- and even if it is,
// the two objects are in general of unrelated type.
isa<BuiltinBitCastExpr>(E)) {
case Stmt::CXXConstructExprClass:
case Stmt::CallExprClass:
case Stmt::LambdaExprClass:
case Stmt::CXXDefaultArgExprClass:
case Stmt::CXXDefaultInitExprClass:
case Stmt::CXXStdInitializerListExprClass:
// We treat `BuiltinBitCastExpr` as an "original initializer" too as it may
// not even be casting from a record type -- and even if it is, the two
// objects are in general of unrelated type.
case Stmt::BuiltinBitCastExprClass:
return;
case Stmt::BinaryOperatorClass: {
auto *Op = cast<BinaryOperator>(E);
if (Op->getOpcode() == BO_Cmp) {
// Builtin `<=>` returns a `std::strong_ordering` object. We
// consider this to be an "original" initializer too (see above).
return;
}
if (Op->isCommaOp()) {
PropagateResultObject(Op->getRHS(), Loc);
return;
}
// We don't expect any other binary operators to produce a record
// prvalue, so if we get here, we've hit some case we don't know
// about.
assert(false);
return;
}
if (auto *Op = dyn_cast<BinaryOperator>(E);
Op && Op->getOpcode() == BO_Cmp) {
// Builtin `<=>` returns a `std::strong_ordering` object.
case Stmt::BinaryConditionalOperatorClass:
case Stmt::ConditionalOperatorClass: {
auto *Cond = cast<AbstractConditionalOperator>(E);
PropagateResultObject(Cond->getTrueExpr(), Loc);
PropagateResultObject(Cond->getFalseExpr(), Loc);
return;
}

if (auto *InitList = dyn_cast<InitListExpr>(E)) {
case Stmt::StmtExprClass: {
auto *SE = cast<StmtExpr>(E);
PropagateResultObject(cast<Expr>(SE->getSubStmt()->body_back()), Loc);
return;
}
case Stmt::InitListExprClass: {
auto *InitList = cast<InitListExpr>(E);
if (!InitList->isSemanticForm())
return;
if (InitList->isTransparent()) {
Expand Down Expand Up @@ -462,33 +489,20 @@ class ResultObjectVisitor : public RecursiveASTVisitor<ResultObjectVisitor> {
}
return;
}

if (auto *Op = dyn_cast<BinaryOperator>(E); Op && Op->isCommaOp()) {
PropagateResultObject(Op->getRHS(), Loc);
default: {
// All other expression nodes that propagate a record prvalue should
// have exactly one child.
SmallVector<Stmt *, 1> Children(E->child_begin(), E->child_end());
LLVM_DEBUG({
if (Children.size() != 1)
E->dump();
});
assert(Children.size() == 1);
for (Stmt *S : Children)
PropagateResultObject(cast<Expr>(S), Loc);
return;
}

if (auto *Cond = dyn_cast<AbstractConditionalOperator>(E)) {
PropagateResultObject(Cond->getTrueExpr(), Loc);
PropagateResultObject(Cond->getFalseExpr(), Loc);
return;
}

if (auto *SE = dyn_cast<StmtExpr>(E)) {
PropagateResultObject(cast<Expr>(SE->getSubStmt()->body_back()), Loc);
return;
}

// All other expression nodes that propagate a record prvalue should have
// exactly one child.
SmallVector<Stmt *, 1> Children(E->child_begin(), E->child_end());
LLVM_DEBUG({
if (Children.size() != 1)
E->dump();
});
assert(Children.size() == 1);
for (Stmt *S : Children)
PropagateResultObject(cast<Expr>(S), Loc);
}

private:
Expand Down