Teach -Wunsequenced that the side-effects of a function evaluation are sequenced
before the value computation of the result. In C, this is implied by there being
a sequence point after their evaluation, and in C++, it's implied by the
side-effects being sequenced before the expressions and statements in the
function body.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185282 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 5afb653..f5296ce 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -5274,6 +5274,8 @@
/// \brief Visitor for expressions which looks for unsequenced operations on the
/// same object.
class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> {
+ typedef EvaluatedExprVisitor<SequenceChecker> Base;
+
/// \brief A tree of sequenced regions within an expression. Two regions are
/// unsequenced if one is an ancestor or a descendent of the other. When we
/// finish processing an expression with sequencing, such as a comma
@@ -5518,9 +5520,8 @@
public:
SequenceChecker(Sema &S, Expr *E,
llvm::SmallVectorImpl<Expr*> &WorkList)
- : EvaluatedExprVisitor<SequenceChecker>(S.Context), SemaRef(S),
- Region(Tree.root()), ModAsSideEffect(0), WorkList(WorkList),
- EvalTracker(0) {
+ : Base(S.Context), SemaRef(S), Region(Tree.root()),
+ ModAsSideEffect(0), WorkList(WorkList), EvalTracker(0) {
Visit(E);
}
@@ -5530,7 +5531,7 @@
void VisitExpr(Expr *E) {
// By default, just recurse to evaluated subexpressions.
- EvaluatedExprVisitor<SequenceChecker>::VisitStmt(E);
+ Base::VisitStmt(E);
}
void VisitCastExpr(CastExpr *E) {
@@ -5695,7 +5696,23 @@
}
}
+ void VisitCallExpr(CallExpr *CE) {
+ // C++11 [intro.execution]p15:
+ // When calling a function [...], every value computation and side effect
+ // associated with any argument expression, or with the postfix expression
+ // designating the called function, is sequenced before execution of every
+ // expression or statement in the body of the function [and thus before
+ // the value computation of its result].
+ SequencedSubexpression Sequenced(*this);
+ Base::VisitCallExpr(CE);
+
+ // FIXME: CXXNewExpr and CXXDeleteExpr implicitly call functions.
+ }
+
void VisitCXXConstructExpr(CXXConstructExpr *CCE) {
+ // This is a call, so all subexpressions are sequenced before the result.
+ SequencedSubexpression Sequenced(*this);
+
if (!CCE->isListInitialization())
return VisitExpr(CCE);