@@ -500,72 +500,86 @@ class ResultObjectVisitor : public RecursiveASTVisitor<ResultObjectVisitor> {
500
500
501
501
ResultObjectMap[E] = Loc;
502
502
503
- // The following AST node kinds are "original initializers": They are the
504
- // lowest-level AST node that initializes a given object, and nothing
505
- // below them can initialize the same object (or part of it).
506
- if (isa<CXXConstructExpr>(E) || isa<CallExpr>(E) || isa<LambdaExpr>(E) ||
507
- isa<CXXDefaultArgExpr>(E) || isa<CXXDefaultInitExpr>(E) ||
508
- isa<CXXStdInitializerListExpr>(E)) {
509
- return ;
510
- }
511
- if (auto *Op = dyn_cast<BinaryOperator>(E);
512
- Op && Op->getOpcode () == BO_Cmp) {
513
- // Builtin `<=>` returns a `std::strong_ordering` object.
514
- return ;
515
- }
516
-
517
- if (auto *InitList = dyn_cast<InitListExpr>(E)) {
518
- if (!InitList->isSemanticForm ())
503
+ switch (E->getStmtClass ()) {
504
+ // The following AST node kinds are "original initializers": They are the
505
+ // lowest-level AST node that initializes a given object, and nothing
506
+ // below them can initialize the same object (or part of it).
507
+ case Stmt::CXXConstructExprClass:
508
+ case Stmt::CallExprClass:
509
+ case Stmt::LambdaExprClass:
510
+ case Stmt::CXXDefaultArgExprClass:
511
+ case Stmt::CXXDefaultInitExprClass:
512
+ case Stmt::CXXStdInitializerListExprClass:
513
+ return ;
514
+ case Stmt::BinaryOperatorClass: {
515
+ auto *Op = cast<BinaryOperator>(E);
516
+ if (Op->getOpcode () == BO_Cmp) {
517
+ // Builtin `<=>` returns a `std::strong_ordering` object. We
518
+ // consider this to be an "original" initializer too (see above).
519
+ return ;
520
+ }
521
+ if (Op->isCommaOp ()) {
522
+ PropagateResultObject (Op->getRHS (), Loc);
523
+ return ;
524
+ }
525
+ // We don't expect any other binary operators to produce a record
526
+ // prvalue, so if we get here, we've hit some case we don't know
527
+ // about.
528
+ assert (false );
519
529
return ;
520
- if (InitList->isTransparent ()) {
521
- PropagateResultObject (InitList->getInit (0 ), Loc);
530
+ }
531
+ case Stmt::BinaryConditionalOperatorClass:
532
+ case Stmt::ConditionalOperatorClass: {
533
+ auto *Cond = cast<AbstractConditionalOperator>(E);
534
+ PropagateResultObject (Cond->getTrueExpr (), Loc);
535
+ PropagateResultObject (Cond->getFalseExpr (), Loc);
522
536
return ;
523
537
}
538
+ case Stmt::InitListExprClass: {
539
+ auto *InitList = cast<InitListExpr>(E);
540
+ if (!InitList->isSemanticForm ())
541
+ return ;
542
+ if (InitList->isTransparent ()) {
543
+ PropagateResultObject (InitList->getInit (0 ), Loc);
544
+ return ;
545
+ }
524
546
525
- RecordInitListHelper InitListHelper (InitList);
547
+ RecordInitListHelper InitListHelper (InitList);
526
548
527
- for (auto [Base, Init] : InitListHelper.base_inits ()) {
528
- assert (Base->getType ().getCanonicalType () ==
529
- Init->getType ().getCanonicalType ());
549
+ for (auto [Base, Init] : InitListHelper.base_inits ()) {
550
+ assert (Base->getType ().getCanonicalType () ==
551
+ Init->getType ().getCanonicalType ());
530
552
531
- // Storage location for the base class is the same as that of the
532
- // derived class because we "flatten" the object hierarchy and put all
533
- // fields in `RecordStorageLocation` of the derived class.
534
- PropagateResultObject (Init, Loc);
535
- }
553
+ // Storage location for the base class is the same as that of the
554
+ // derived class because we "flatten" the object hierarchy and put all
555
+ // fields in `RecordStorageLocation` of the derived class.
556
+ PropagateResultObject (Init, Loc);
557
+ }
536
558
537
- for (auto [Field, Init] : InitListHelper.field_inits ()) {
538
- // Fields of non-record type are handled in
539
- // `TransferVisitor::VisitInitListExpr()`.
540
- if (!Field->getType ()->isRecordType ())
541
- continue ;
542
- PropagateResultObject (
543
- Init, cast<RecordStorageLocation>(Loc->getChild (*Field)));
559
+ for (auto [Field, Init] : InitListHelper.field_inits ()) {
560
+ // Fields of non-record type are handled in
561
+ // `TransferVisitor::VisitInitListExpr()`.
562
+ if (!Field->getType ()->isRecordType ())
563
+ continue ;
564
+ PropagateResultObject (
565
+ Init, cast<RecordStorageLocation>(Loc->getChild (*Field)));
566
+ }
567
+ return ;
568
+ }
569
+ default : {
570
+ // All other expression nodes that propagate a record prvalue should
571
+ // have exactly one child.
572
+ SmallVector<Stmt *, 1 > Children (E->child_begin (), E->child_end ());
573
+ LLVM_DEBUG ({
574
+ if (Children.size () != 1 )
575
+ E->dump ();
576
+ });
577
+ assert (Children.size () == 1 );
578
+ for (Stmt *S : Children)
579
+ PropagateResultObject (cast<Expr>(S), Loc);
580
+ return ;
544
581
}
545
- return ;
546
- }
547
-
548
- if (auto *Op = dyn_cast<BinaryOperator>(E); Op && Op->isCommaOp ()) {
549
- PropagateResultObject (Op->getRHS (), Loc);
550
- return ;
551
- }
552
-
553
- if (auto *Cond = dyn_cast<AbstractConditionalOperator>(E)) {
554
- PropagateResultObject (Cond->getTrueExpr (), Loc);
555
- PropagateResultObject (Cond->getFalseExpr (), Loc);
556
- return ;
557
582
}
558
-
559
- // All other expression nodes that propagate a record prvalue should have
560
- // exactly one child.
561
- SmallVector<Stmt *, 1 > Children (E->child_begin (), E->child_end ());
562
- LLVM_DEBUG ({
563
- if (Children.size () != 1 )
564
- E->dump ();
565
- });
566
- assert (Children.size () == 1 );
567
- for (Stmt *S : Children)
568
- PropagateResultObject (cast<Expr>(S), Loc);
569
583
}
570
584
571
585
private:
0 commit comments