[cfe-commits] r125744 - in /cfe/trunk: include/clang/AST/ include/clang/Analysis/Visitors/ include/clang/Basic/ include/clang/Sema/ include/clang/Serialization/ lib/AST/ lib/Analysis/ lib/CodeGen/ lib/Rewrite/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Checkers/ lib/StaticAnalyzer/Core/ test/Analysis/ test/CodeGenCXX/ tools/libclang/
Benjamin Kramer
benny.kra at googlemail.com
Fri Feb 18 11:04:56 PST 2011
On 17.02.2011, at 11:25, John McCall wrote:
> Author: rjmccall
> Date: Thu Feb 17 04:25:35 2011
> New Revision: 125744
>
> URL: http://llvm.org/viewvc/llvm-project?rev=125744&view=rev
> Log:
> Change the representation of GNU ?: expressions to use a different expression
> class and to bind the shared value using OpaqueValueExpr. This fixes an
> unnoticed problem with deserialization of these expressions where the
> deserialized form would lose the vital pointer-equality trait; or rather,
> it fixes it because this patch also does the right thing for deserializing
> OVEs.
>
> Change OVEs to not be a "temporary object" in the sense that copy elision is
> permitted.
>
> This new representation is not totally unawkward to work with, but I think
> that's really part and parcel with the semantics we're modelling here. In
> particular, it's much easier to fix things like the copy elision bug and to
> make the CFG look right.
>
> I've tried to update the analyzer to deal with this in at least some
> obvious cases, and I think we get a much better CFG out, but the printing
> of OpaqueValueExprs probably needs some work.
[…]
> Modified: cfe/trunk/lib/Analysis/CFG.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=125744&r1=125743&r2=125744&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Analysis/CFG.cpp (original)
> +++ cfe/trunk/lib/Analysis/CFG.cpp Thu Feb 17 04:25:35 2011
> @@ -290,7 +290,8 @@
> CFGBlock *VisitCaseStmt(CaseStmt *C);
> CFGBlock *VisitChooseExpr(ChooseExpr *C, AddStmtChoice asc);
> CFGBlock *VisitCompoundStmt(CompoundStmt *C);
> - CFGBlock *VisitConditionalOperator(ConditionalOperator *C, AddStmtChoice asc);
> + CFGBlock *VisitConditionalOperator(AbstractConditionalOperator *C,
> + AddStmtChoice asc);
> CFGBlock *VisitContinueStmt(ContinueStmt *C);
> CFGBlock *VisitDeclStmt(DeclStmt *DS);
> CFGBlock *VisitDeclSubExpr(DeclStmt* DS);
> @@ -326,8 +327,9 @@
> CFGBlock *VisitBinaryOperatorForTemporaryDtors(BinaryOperator *E);
> CFGBlock *VisitCXXBindTemporaryExprForTemporaryDtors(CXXBindTemporaryExpr *E,
> bool BindToTemporary);
> - CFGBlock *VisitConditionalOperatorForTemporaryDtors(ConditionalOperator *E,
> - bool BindToTemporary);
> + CFGBlock *
> + VisitConditionalOperatorForTemporaryDtors(AbstractConditionalOperator *E,
> + bool BindToTemporary);
>
> // NYS == Not Yet Supported
> CFGBlock* NYS() {
> @@ -785,6 +787,9 @@
> case Stmt::AddrLabelExprClass:
> return VisitAddrLabelExpr(cast<AddrLabelExpr>(S), asc);
>
> + case Stmt::BinaryConditionalOperatorClass:
> + return VisitConditionalOperator(cast<BinaryConditionalOperator>(S), asc);
> +
> case Stmt::BinaryOperatorClass:
> return VisitBinaryOperator(cast<BinaryOperator>(S), asc);
>
> @@ -1174,8 +1179,11 @@
> return LastBlock;
> }
>
> -CFGBlock *CFGBuilder::VisitConditionalOperator(ConditionalOperator *C,
> +CFGBlock *CFGBuilder::VisitConditionalOperator(AbstractConditionalOperator *C,
> AddStmtChoice asc) {
> + const BinaryConditionalOperator *BCO = dyn_cast<BinaryConditionalOperator>(C);
> + const OpaqueValueExpr *opaqueValue = (BCO ? BCO->getOpaqueValue() : NULL);
> +
> // Create the confluence block that will "merge" the results of the ternary
> // expression.
> CFGBlock* ConfluenceBlock = Block ? Block : createBlock();
> @@ -1191,9 +1199,10 @@
> // e.g: x ?: y is shorthand for: x ? x : y;
> Succ = ConfluenceBlock;
> Block = NULL;
> - CFGBlock* LHSBlock = NULL;
> - if (C->getLHS()) {
> - LHSBlock = Visit(C->getLHS(), alwaysAdd);
> + CFGBlock* LHSBlock = 0;
> + const Expr *trueExpr = C->getTrueExpr();
> + if (trueExpr != opaqueValue) {
> + LHSBlock = Visit(C->getTrueExpr(), alwaysAdd);
> if (badCFG)
> return 0;
> Block = NULL;
> @@ -1201,7 +1210,7 @@
>
> // Create the block for the RHS expression.
> Succ = ConfluenceBlock;
> - CFGBlock* RHSBlock = Visit(C->getRHS(), alwaysAdd);
> + CFGBlock* RHSBlock = Visit(C->getFalseExpr(), alwaysAdd);
> if (badCFG)
> return 0;
>
> @@ -1210,33 +1219,15 @@
>
> // See if this is a known constant.
> const TryResult& KnownVal = tryEvaluateBool(C->getCond());
> - if (LHSBlock) {
> + if (LHSBlock)
> addSuccessor(Block, KnownVal.isFalse() ? NULL : LHSBlock);
> - } else {
> - if (KnownVal.isFalse()) {
> - // If we know the condition is false, add NULL as the successor for
> - // the block containing the condition. In this case, the confluence
> - // block will have just one predecessor.
> - addSuccessor(Block, 0);
> - assert(ConfluenceBlock->pred_size() == 1);
> - } else {
> - // If we have no LHS expression, add the ConfluenceBlock as a direct
> - // successor for the block containing the condition. Moreover, we need to
> - // reverse the order of the predecessors in the ConfluenceBlock because
> - // the RHSBlock will have been added to the succcessors already, and we
> - // want the first predecessor to the the block containing the expression
> - // for the case when the ternary expression evaluates to true.
> - addSuccessor(Block, ConfluenceBlock);
> - // Note that there can possibly only be one predecessor if one of the
> - // subexpressions resulted in calling a noreturn function.
> - std::reverse(ConfluenceBlock->pred_begin(),
> - ConfluenceBlock->pred_end());
> - }
> - }
> -
> addSuccessor(Block, KnownVal.isTrue() ? NULL : RHSBlock);
> Block->setTerminator(C);
> - return addStmt(C->getCond());
> + CFGBlock *result;
> + Expr *condExpr = C->getCond();
> + if (condExpr != opaqueValue) result = addStmt(condExpr);
> + if (BCO) result = addStmt(BCO->getCommon());
> + return result;
> }
Hi John,
gcc says: CFG.cpp:1226: warning: 'result' may be used uninitialized in this function
More information about the cfe-commits
mailing list