From: Fariborz Jahanian Date: Tue, 21 Sep 2010 18:32:21 +0000 (+0000) Subject: IRgen for gnu extension's conditional lvalue expression X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0b78710636671eeb2c5c4dedffa4ad1d58fa4bb8;p=clang IRgen for gnu extension's conditional lvalue expression with missing LHS. radar 8453812. Executable test is checked into llvm test suite. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114457 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 9b69297bbe..78c1da5060 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -495,6 +495,11 @@ LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) { /// length type, this is not possible. /// LValue CodeGenFunction::EmitLValue(const Expr *E) { + llvm::DenseMap::iterator I = + CGF.ConditionalSaveLValueExprs.find(E); + if (I != CGF.ConditionalSaveLValueExprs.end()) + return I->second; + switch (E->getStmtClass()) { default: return EmitUnsupportedLValue(E, "l-value expression"); @@ -1694,19 +1699,26 @@ CodeGenFunction::EmitConditionalOperatorLValue(const ConditionalOperator *E) { return EmitLValue(Live); } - if (!E->getLHS()) - return EmitUnsupportedLValue(E, "conditional operator with missing LHS"); - llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true"); llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false"); llvm::BasicBlock *ContBlock = createBasicBlock("cond.end"); - EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); + if (E->getLHS()) + EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); + else { + Expr *save = E->getSAVE(); + assert(save && "VisitConditionalOperator - save is null"); + // Intentianlly not doing direct assignment to ConditionalSaveExprs[save] + LValue SaveVal = EmitLValue(save); + ConditionalSaveLValueExprs[save] = SaveVal; + EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); + } // Any temporaries created here are conditional. BeginConditionalBranch(); EmitBlock(LHSBlock); - LValue LHS = EmitLValue(E->getLHS()); + LValue LHS = EmitLValue(E->getTrueExpr()); + EndConditionalBranch(); if (!LHS.isSimple()) diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 8b0f12e418..7403711155 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -517,6 +517,7 @@ public: /// extension's missing LHS expression in a conditional operator expression. llvm::DenseMap ConditionalSaveExprs; llvm::DenseMap ConditionalSaveComplexExprs; + llvm::DenseMap ConditionalSaveLValueExprs; EHScopeStack EHStack; diff --git a/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp b/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp index a3f9fd2190..25eafc7e1b 100644 --- a/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp +++ b/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp @@ -39,8 +39,25 @@ _Complex int cmplx() { return getComplex(1+2i) ? : rhs; } +// lvalue test +void foo (int& lv) { + ++lv; +} + +int global = 1; + +int &cond() { + static int count; + if (count++) + abort(); + return global; +} + + int main() { cmplx(); - return 0; + int rhs = 10; + foo (cond()? : rhs); + return global-2; } }