diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-05-06 17:25:47 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-05-06 17:25:47 +0000 |
| commit | e60e41add90ad34557655b5f763d56ced62de508 (patch) | |
| tree | b0474f9d7c18bf92fa8ca54d275766ce54d95406 /clang/lib/Sema/TreeTransform.h | |
| parent | f0ac19a6d54de51d0f85eeb89d47897f2ef7c2cc (diff) | |
| download | bcm5719-llvm-e60e41add90ad34557655b5f763d56ced62de508.tar.gz bcm5719-llvm-e60e41add90ad34557655b5f763d56ced62de508.zip | |
Rework our handling of temporary objects within the conditions of
if/switch/while/do/for statements. Previously, we would end up either:
(1) Forgetting to destroy temporaries created in the condition (!),
(2) Destroying the temporaries created in the condition *before*
converting the condition to a boolean value (or, in the case of a
switch statement, to an integral or enumeral value), or
(3) In a for statement, destroying the condition's temporaries at
the end of the increment expression (!).
We now destroy temporaries in conditions at the right times. This
required some tweaking of the Parse/Sema interaction, since the parser
was building full expressions too early in many places.
Fixes PR7067.
llvm-svn: 103187
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index cc9842a57ea..43ffbfb737b 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -758,10 +758,18 @@ public: /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond, + OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::ExprArg Cond, VarDecl *CondVar, StmtArg Then, SourceLocation ElseLoc, StmtArg Else) { - return getSema().ActOnIfStmt(IfLoc, Cond, DeclPtrTy::make(CondVar), + if (Cond.get()) { + // Convert the condition to a boolean value. + Cond = getSema().ActOnBooleanCondition(0, IfLoc, move(Cond)); + if (Cond.isInvalid()) + return getSema().StmtError(); + } + + Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond)); + return getSema().ActOnIfStmt(IfLoc, FullCond, DeclPtrTy::make(CondVar), move(Then), ElseLoc, move(Else)); } @@ -769,9 +777,11 @@ public: /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - OwningStmtResult RebuildSwitchStmtStart(Sema::FullExprArg Cond, + OwningStmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc, + Sema::ExprArg Cond, VarDecl *CondVar) { - return getSema().ActOnStartOfSwitchStmt(Cond, DeclPtrTy::make(CondVar)); + return getSema().ActOnStartOfSwitchStmt(SwitchLoc, move(Cond), + DeclPtrTy::make(CondVar)); } /// \brief Attach the body to the switch statement. @@ -789,11 +799,19 @@ public: /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc, - Sema::FullExprArg Cond, + Sema::ExprArg Cond, VarDecl *CondVar, StmtArg Body) { - return getSema().ActOnWhileStmt(WhileLoc, Cond, DeclPtrTy::make(CondVar), - move(Body)); + if (Cond.get()) { + // Convert the condition to a boolean value. + Cond = getSema().ActOnBooleanCondition(0, WhileLoc, move(Cond)); + if (Cond.isInvalid()) + return getSema().StmtError(); + } + + Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond)); + return getSema().ActOnWhileStmt(WhileLoc, FullCond, + DeclPtrTy::make(CondVar), move(Body)); } /// \brief Build a new do-while statement. @@ -815,10 +833,18 @@ public: /// Subclasses may override this routine to provide different behavior. OwningStmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, - StmtArg Init, Sema::FullExprArg Cond, + StmtArg Init, Sema::ExprArg Cond, VarDecl *CondVar, Sema::FullExprArg Inc, SourceLocation RParenLoc, StmtArg Body) { - return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), Cond, + if (Cond.get()) { + // Convert the condition to a boolean value. + Cond = getSema().ActOnBooleanCondition(0, ForLoc, move(Cond)); + if (Cond.isInvalid()) + return getSema().StmtError(); + } + + Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond)); + return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), FullCond, DeclPtrTy::make(CondVar), Inc, RParenLoc, move(Body)); } @@ -3491,8 +3517,6 @@ TreeTransform<Derived>::TransformIfStmt(IfStmt *S) { return SemaRef.StmtError(); } - Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond)); - // Transform the "then" branch. OwningStmtResult Then = getDerived().TransformStmt(S->getThen()); if (Then.isInvalid()) @@ -3504,13 +3528,13 @@ TreeTransform<Derived>::TransformIfStmt(IfStmt *S) { return SemaRef.StmtError(); if (!getDerived().AlwaysRebuild() && - FullCond->get() == S->getCond() && + Cond.get() == S->getCond() && ConditionVar == S->getConditionVariable() && Then.get() == S->getThen() && Else.get() == S->getElse()) return SemaRef.Owned(S->Retain()); - return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar, + return getDerived().RebuildIfStmt(S->getIfLoc(), move(Cond), ConditionVar, move(Then), S->getElseLoc(), move(Else)); } @@ -3536,11 +3560,10 @@ TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) { return SemaRef.StmtError(); } - Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond)); - // Rebuild the switch statement. - OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(FullCond, - ConditionVar); + OwningStmtResult Switch + = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), move(Cond), + ConditionVar); if (Switch.isInvalid()) return SemaRef.StmtError(); @@ -3575,21 +3598,19 @@ TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) { return SemaRef.StmtError(); } - Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond)); - // Transform the body OwningStmtResult Body = getDerived().TransformStmt(S->getBody()); if (Body.isInvalid()) return SemaRef.StmtError(); if (!getDerived().AlwaysRebuild() && - FullCond->get() == S->getCond() && + Cond.get() == S->getCond() && ConditionVar == S->getConditionVariable() && Body.get() == S->getBody()) return SemaRef.Owned(S->Retain()); - return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, ConditionVar, - move(Body)); + return getDerived().RebuildWhileStmt(S->getWhileLoc(), move(Cond), + ConditionVar, move(Body)); } template<typename Derived> @@ -3659,8 +3680,7 @@ TreeTransform<Derived>::TransformForStmt(ForStmt *S) { return SemaRef.Owned(S->Retain()); return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(), - move(Init), getSema().MakeFullExpr(Cond), - ConditionVar, + move(Init), move(Cond), ConditionVar, getSema().MakeFullExpr(Inc), S->getRParenLoc(), move(Body)); } |

