diff options
author | Bruno Ricci <riccibrun@gmail.com> | 2019-12-22 12:41:14 +0000 |
---|---|---|
committer | Bruno Ricci <riccibrun@gmail.com> | 2019-12-22 12:41:14 +0000 |
commit | 7394c15178ed9cb7bd04585526a1e73396e60e17 (patch) | |
tree | 0a891d1fa3d4ab0ac15880512244f425b36d9e62 /clang/lib/Sema/SemaChecking.cpp | |
parent | 8a571538dff6dbc1b7f4fed6aed8be7ec1a00a8d (diff) | |
download | bcm5719-llvm-7394c15178ed9cb7bd04585526a1e73396e60e17.tar.gz bcm5719-llvm-7394c15178ed9cb7bd04585526a1e73396e60e17.zip |
[Sema] SequenceChecker: C++17 sequencing rules for built-in operators <<, >>, .*, ->*, =, op=
Implement the C++17 sequencing rules for the built-in operators <<, >>, .*,
->*, = and op=.
Differential Revision: https://reviews.llvm.org/D58297
Reviewed By: rsmith
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 108 |
1 files changed, 83 insertions, 25 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 2cbe3632be3..b8295bc741e 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -12832,8 +12832,37 @@ public: // expression E1 is sequenced before the expression E2. if (SemaRef.getLangOpts().CPlusPlus17) VisitSequencedExpressions(ASE->getLHS(), ASE->getRHS()); - else - Base::VisitStmt(ASE); + else { + Visit(ASE->getLHS()); + Visit(ASE->getRHS()); + } + } + + void VisitBinPtrMemD(const BinaryOperator *BO) { VisitBinPtrMem(BO); } + void VisitBinPtrMemI(const BinaryOperator *BO) { VisitBinPtrMem(BO); } + void VisitBinPtrMem(const BinaryOperator *BO) { + // C++17 [expr.mptr.oper]p4: + // Abbreviating pm-expression.*cast-expression as E1.*E2, [...] + // the expression E1 is sequenced before the expression E2. + if (SemaRef.getLangOpts().CPlusPlus17) + VisitSequencedExpressions(BO->getLHS(), BO->getRHS()); + else { + Visit(BO->getLHS()); + Visit(BO->getRHS()); + } + } + + void VisitBinShl(const BinaryOperator *BO) { VisitBinShlShr(BO); } + void VisitBinShr(const BinaryOperator *BO) { VisitBinShlShr(BO); } + void VisitBinShlShr(const BinaryOperator *BO) { + // C++17 [expr.shift]p4: + // The expression E1 is sequenced before the expression E2. + if (SemaRef.getLangOpts().CPlusPlus17) + VisitSequencedExpressions(BO->getLHS(), BO->getRHS()); + else { + Visit(BO->getLHS()); + Visit(BO->getRHS()); + } } void VisitBinComma(const BinaryOperator *BO) { @@ -12845,38 +12874,67 @@ public: } void VisitBinAssign(const BinaryOperator *BO) { - // The modification is sequenced after the value computation of the LHS - // and RHS, so check it before inspecting the operands and update the + SequenceTree::Seq RHSRegion; + SequenceTree::Seq LHSRegion; + if (SemaRef.getLangOpts().CPlusPlus17) { + RHSRegion = Tree.allocate(Region); + LHSRegion = Tree.allocate(Region); + } else { + RHSRegion = Region; + LHSRegion = Region; + } + SequenceTree::Seq OldRegion = Region; + + // C++11 [expr.ass]p1: + // [...] the assignment is sequenced after the value computation + // of the right and left operands, [...] + // + // so check it before inspecting the operands and update the // map afterwards. - Object O = getObject(BO->getLHS(), true); - if (!O) - return VisitExpr(BO); + Object O = getObject(BO->getLHS(), /*Mod=*/true); + if (O) + notePreMod(O, BO); + + if (SemaRef.getLangOpts().CPlusPlus17) { + // C++17 [expr.ass]p1: + // [...] The right operand is sequenced before the left operand. [...] + { + SequencedSubexpression SeqBefore(*this); + Region = RHSRegion; + Visit(BO->getRHS()); + } - notePreMod(O, BO); + Region = LHSRegion; + Visit(BO->getLHS()); - // C++11 [expr.ass]p7: - // E1 op= E2 is equivalent to E1 = E1 op E2, except that E1 is evaluated - // only once. - // - // Therefore, for a compound assignment operator, O is considered used - // everywhere except within the evaluation of E1 itself. - if (isa<CompoundAssignOperator>(BO)) - notePreUse(O, BO); + if (O && isa<CompoundAssignOperator>(BO)) + notePostUse(O, BO); - Visit(BO->getLHS()); + } else { + // C++11 does not specify any sequencing between the LHS and RHS. + Region = LHSRegion; + Visit(BO->getLHS()); - if (isa<CompoundAssignOperator>(BO)) - notePostUse(O, BO); + if (O && isa<CompoundAssignOperator>(BO)) + notePostUse(O, BO); - Visit(BO->getRHS()); + Region = RHSRegion; + Visit(BO->getRHS()); + } // C++11 [expr.ass]p1: - // the assignment is sequenced [...] before the value computation of the - // assignment expression. + // the assignment is sequenced [...] before the value computation of the + // assignment expression. // C11 6.5.16/3 has no such rule. - notePostMod(O, BO, - SemaRef.getLangOpts().CPlusPlus ? UK_ModAsValue - : UK_ModAsSideEffect); + Region = OldRegion; + if (O) + notePostMod(O, BO, + SemaRef.getLangOpts().CPlusPlus ? UK_ModAsValue + : UK_ModAsSideEffect); + if (SemaRef.getLangOpts().CPlusPlus17) { + Tree.merge(RHSRegion); + Tree.merge(LHSRegion); + } } void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO) { |