summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2014-08-08 07:37:13 +0000
committerManuel Klimek <klimek@google.com>2014-08-08 07:37:13 +0000
commitdeb0262a5eae90fe9847cab3708afc36f823a573 (patch)
tree4ab73f3ec3603ee0e8c632dcc6735cac281b7e89 /clang/lib/Analysis
parentf9834d5fa0944872a662eca971fb216058d2514d (diff)
downloadbcm5719-llvm-deb0262a5eae90fe9847cab3708afc36f823a573.tar.gz
bcm5719-llvm-deb0262a5eae90fe9847cab3708afc36f823a573.zip
Fix branch reachabiliy annotation for temp dtor branches.
As we only create temp dtor decision branches when a temp dtor needs to be run (as opposed to for each logical branch in the original expression), we must include the information about all previous logical branches when we annotate the temp dtor decision branch. llvm-svn: 215188
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r--clang/lib/Analysis/CFG.cpp50
1 files changed, 29 insertions, 21 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 29f21ec8d47..49f35ef10f1 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -234,6 +234,12 @@ public:
}
};
+TryResult bothKnownTrue(TryResult R1, TryResult R2) {
+ if (!R1.isKnown() || !R2.isKnown())
+ return TryResult();
+ return TryResult(R1.isTrue() && R2.isTrue());
+}
+
class reverse_children {
llvm::SmallVector<Stmt *, 12> childrenBuf;
ArrayRef<Stmt*> children;
@@ -439,10 +445,10 @@ private:
/// if the CXXBindTemporaryExpr was marked executed, and otherwise
/// branches to the stored successor.
struct TempDtorContext {
- TempDtorContext(bool IsConditional)
- : IsConditional(IsConditional),
- Succ(nullptr),
- TerminatorExpr(nullptr) {}
+ TempDtorContext() : KnownExecuted(true) {}
+
+ TempDtorContext(TryResult KnownExecuted)
+ : IsConditional(true), KnownExecuted(KnownExecuted) {}
/// Returns whether we need to start a new branch for a temporary destructor
/// call. This is the case when the the temporary destructor is
@@ -461,9 +467,10 @@ private:
TerminatorExpr = E;
}
- const bool IsConditional;
- CFGBlock *Succ;
- CXXBindTemporaryExpr *TerminatorExpr;
+ const bool IsConditional = false;
+ const TryResult KnownExecuted;
+ CFGBlock *Succ = nullptr;
+ CXXBindTemporaryExpr *TerminatorExpr = nullptr;
};
// Visitors to walk an AST and generate destructors of temporaries in
@@ -479,7 +486,6 @@ private:
AbstractConditionalOperator *E, bool BindToTemporary,
TempDtorContext &Context);
void InsertTempDtorDecisionBlock(const TempDtorContext &Context,
- TryResult ConditionVal,
CFGBlock *FalseSucc = nullptr);
// NYS == Not Yet Supported
@@ -1071,7 +1077,7 @@ CFGBlock *CFGBuilder::addInitializer(CXXCtorInitializer *I) {
if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
// Generate destructors for temporaries in initialization expression.
- TempDtorContext Context(/*IsConditional=*/false);
+ TempDtorContext Context;
VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
/*BindToTemporary=*/false, Context);
}
@@ -2030,7 +2036,7 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) {
if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
// Generate destructors for temporaries in initialization expression.
- TempDtorContext Context(/*IsConditional=*/false);
+ TempDtorContext Context;
VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
/*BindToTemporary=*/false, Context);
}
@@ -3412,7 +3418,7 @@ CFGBlock *CFGBuilder::VisitExprWithCleanups(ExprWithCleanups *E,
if (BuildOpts.AddTemporaryDtors) {
// If adding implicit destructors visit the full expression for adding
// destructors of temporaries.
- TempDtorContext Context(/*IsConditional=*/false);
+ TempDtorContext Context;
VisitForTemporaryDtors(E->getSubExpr(), false, Context);
// Full expression has to be added as CFGStmt so it will be sequenced
@@ -3639,9 +3645,10 @@ CFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors(
// We do not know at CFG-construction time whether the right-hand-side was
// executed, thus we add a branch node that depends on the temporary
// constructor call.
- TempDtorContext RHSContext(/*IsConditional=*/true);
+ TempDtorContext RHSContext(
+ bothKnownTrue(Context.KnownExecuted, RHSExecuted));
VisitForTemporaryDtors(E->getRHS(), false, RHSContext);
- InsertTempDtorDecisionBlock(RHSContext, RHSExecuted);
+ InsertTempDtorDecisionBlock(RHSContext);
return Block;
}
@@ -3698,7 +3705,6 @@ CFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors(
}
void CFGBuilder::InsertTempDtorDecisionBlock(const TempDtorContext &Context,
- TryResult ConditionVal,
CFGBlock *FalseSucc) {
if (!Context.TerminatorExpr) {
// If no temporary was found, we do not need to insert a decision point.
@@ -3707,9 +3713,9 @@ void CFGBuilder::InsertTempDtorDecisionBlock(const TempDtorContext &Context,
assert(Context.TerminatorExpr);
CFGBlock *Decision = createBlock(false);
Decision->setTerminator(CFGTerminator(Context.TerminatorExpr, true));
- addSuccessor(Decision, Block, !ConditionVal.isFalse());
+ addSuccessor(Decision, Block, !Context.KnownExecuted.isFalse());
addSuccessor(Decision, FalseSucc ? FalseSucc : Context.Succ,
- !ConditionVal.isTrue());
+ !Context.KnownExecuted.isTrue());
Block = Decision;
}
@@ -3723,22 +3729,24 @@ CFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors(
TryResult NegatedVal = ConditionVal;
if (NegatedVal.isKnown()) NegatedVal.negate();
- TempDtorContext TrueContext(/*IsConditional=*/true);
+ TempDtorContext TrueContext(
+ bothKnownTrue(Context.KnownExecuted, ConditionVal));
VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext);
CFGBlock *TrueBlock = Block;
Block = ConditionBlock;
Succ = ConditionSucc;
- TempDtorContext FalseContext(/*IsConditional=*/true);
+ TempDtorContext FalseContext(
+ bothKnownTrue(Context.KnownExecuted, NegatedVal));
VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext);
if (TrueContext.TerminatorExpr && FalseContext.TerminatorExpr) {
- InsertTempDtorDecisionBlock(FalseContext, NegatedVal, TrueBlock);
+ InsertTempDtorDecisionBlock(FalseContext, TrueBlock);
} else if (TrueContext.TerminatorExpr) {
Block = TrueBlock;
- InsertTempDtorDecisionBlock(TrueContext, ConditionVal);
+ InsertTempDtorDecisionBlock(TrueContext);
} else {
- InsertTempDtorDecisionBlock(FalseContext, NegatedVal);
+ InsertTempDtorDecisionBlock(FalseContext);
}
return Block;
}
OpenPOWER on IntegriCloud