summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-08 22:20:28 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-08 22:20:28 +0000
commitff73a9e3809d81dbf752a9d6142d740b66ade619 (patch)
tree6ea3c968d1fd5e785487fabf83bfcdba98ef7d6d /clang/lib/Sema
parent84d461865965192f7a71627887a0ea8e5dd5afb7 (diff)
downloadbcm5719-llvm-ff73a9e3809d81dbf752a9d6142d740b66ade619.tar.gz
bcm5719-llvm-ff73a9e3809d81dbf752a9d6142d740b66ade619.zip
When instantiating statements that involve conditions (if, while, do,
for, and switch), be careful to construct the full expressions as soon as we perform template instantation, so we don't either forget to call temporary destructors or destroy temporaries at the wrong time. This is the template-instantiation analogue to r103187, during which I hadn't realized that the issue would affect the handling of these constructs differently inside and outside of templates. Fixes a regression in Boost.Function. llvm-svn: 103357
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/TreeTransform.h109
1 files changed, 58 insertions, 51 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 9825086809a..ec6e96b706d 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -758,21 +758,10 @@ 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::ExprArg Cond,
+ OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
VarDecl *CondVar, StmtArg Then,
SourceLocation ElseLoc, StmtArg Else) {
- if (Cond.get()) {
- // Convert the condition to a boolean value.
- OwningExprResult CondE = getSema().ActOnBooleanCondition(0, IfLoc,
- move(Cond));
- if (CondE.isInvalid())
- return getSema().StmtError();
-
- Cond = move(CondE);
- }
-
- Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
- return getSema().ActOnIfStmt(IfLoc, FullCond, DeclPtrTy::make(CondVar),
+ return getSema().ActOnIfStmt(IfLoc, Cond, DeclPtrTy::make(CondVar),
move(Then), ElseLoc, move(Else));
}
@@ -802,20 +791,10 @@ 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::ExprArg Cond,
+ Sema::FullExprArg Cond,
VarDecl *CondVar,
StmtArg Body) {
- if (Cond.get()) {
- // Convert the condition to a boolean value.
- OwningExprResult CondE = getSema().ActOnBooleanCondition(0, WhileLoc,
- move(Cond));
- if (CondE.isInvalid())
- return getSema().StmtError();
- Cond = move(CondE);
- }
-
- Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
- return getSema().ActOnWhileStmt(WhileLoc, FullCond,
+ return getSema().ActOnWhileStmt(WhileLoc, Cond,
DeclPtrTy::make(CondVar), move(Body));
}
@@ -838,21 +817,10 @@ public:
/// Subclasses may override this routine to provide different behavior.
OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
SourceLocation LParenLoc,
- StmtArg Init, Sema::ExprArg Cond,
+ StmtArg Init, Sema::FullExprArg Cond,
VarDecl *CondVar, Sema::FullExprArg Inc,
SourceLocation RParenLoc, StmtArg Body) {
- if (Cond.get()) {
- // Convert the condition to a boolean value.
- OwningExprResult CondE = getSema().ActOnBooleanCondition(0, ForLoc,
- move(Cond));
- if (CondE.isInvalid())
- return getSema().StmtError();
-
- Cond = move(CondE);
- }
-
- Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
- return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), FullCond,
+ return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), Cond,
DeclPtrTy::make(CondVar),
Inc, RParenLoc, move(Body));
}
@@ -3523,8 +3491,20 @@ TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
if (Cond.isInvalid())
return SemaRef.StmtError();
+
+ // Convert the condition to a boolean value.
+ OwningExprResult CondE = getSema().ActOnBooleanCondition(0, S->getIfLoc(),
+ move(Cond));
+ if (CondE.isInvalid())
+ return getSema().StmtError();
+
+ Cond = move(CondE);
}
+ Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
+ if (!S->getConditionVariable() && S->getCond() && !FullCond->get())
+ return SemaRef.StmtError();
+
// Transform the "then" branch.
OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
if (Then.isInvalid())
@@ -3536,13 +3516,13 @@ TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
return SemaRef.StmtError();
if (!getDerived().AlwaysRebuild() &&
- Cond.get() == S->getCond() &&
+ FullCond->get() == S->getCond() &&
ConditionVar == S->getConditionVariable() &&
Then.get() == S->getThen() &&
Else.get() == S->getElse())
return SemaRef.Owned(S->Retain());
- return getDerived().RebuildIfStmt(S->getIfLoc(), move(Cond), ConditionVar,
+ return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
move(Then),
S->getElseLoc(), move(Else));
}
@@ -3604,36 +3584,48 @@ TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
if (Cond.isInvalid())
return SemaRef.StmtError();
+
+ // Convert the condition to a boolean value.
+ OwningExprResult CondE = getSema().ActOnBooleanCondition(0,
+ S->getWhileLoc(),
+ move(Cond));
+ if (CondE.isInvalid())
+ return getSema().StmtError();
+ Cond = move(CondE);
}
+ Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
+ if (!S->getConditionVariable() && S->getCond() && !FullCond->get())
+ return SemaRef.StmtError();
+
// Transform the body
OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
if (Body.isInvalid())
return SemaRef.StmtError();
if (!getDerived().AlwaysRebuild() &&
- Cond.get() == S->getCond() &&
+ FullCond->get() == S->getCond() &&
ConditionVar == S->getConditionVariable() &&
Body.get() == S->getBody())
return SemaRef.Owned(S->Retain());
- return getDerived().RebuildWhileStmt(S->getWhileLoc(), move(Cond),
+ return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond,
ConditionVar, move(Body));
}
template<typename Derived>
Sema::OwningStmtResult
TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
- // Transform the condition
- OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
- if (Cond.isInvalid())
- return SemaRef.StmtError();
-
// Transform the body
OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
if (Body.isInvalid())
return SemaRef.StmtError();
+ // Transform the condition
+ OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
+ if (Cond.isInvalid())
+ return SemaRef.StmtError();
+
if (!getDerived().AlwaysRebuild() &&
Cond.get() == S->getCond() &&
Body.get() == S->getBody())
@@ -3668,13 +3660,29 @@ TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
if (Cond.isInvalid())
return SemaRef.StmtError();
+
+ // Convert the condition to a boolean value.
+ OwningExprResult CondE = getSema().ActOnBooleanCondition(0, S->getForLoc(),
+ move(Cond));
+ if (CondE.isInvalid())
+ return getSema().StmtError();
+
+ Cond = move(CondE);
}
+ Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
+ if (!S->getConditionVariable() && S->getCond() && !FullCond->get())
+ return SemaRef.StmtError();
+
// Transform the increment
OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
if (Inc.isInvalid())
return SemaRef.StmtError();
+ Sema::FullExprArg FullInc(getSema().MakeFullExpr(Inc));
+ if (S->getInc() && !FullInc->get())
+ return SemaRef.StmtError();
+
// Transform the body
OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
if (Body.isInvalid())
@@ -3682,15 +3690,14 @@ TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
if (!getDerived().AlwaysRebuild() &&
Init.get() == S->getInit() &&
- Cond.get() == S->getCond() &&
+ FullCond->get() == S->getCond() &&
Inc.get() == S->getInc() &&
Body.get() == S->getBody())
return SemaRef.Owned(S->Retain());
return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
- move(Init), move(Cond), ConditionVar,
- getSema().MakeFullExpr(Inc),
- S->getRParenLoc(), move(Body));
+ move(Init), FullCond, ConditionVar,
+ FullInc, S->getRParenLoc(), move(Body));
}
template<typename Derived>
OpenPOWER on IntegriCloud