diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-09-20 23:50:22 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-09-20 23:50:22 +0000 |
commit | 8162d4ad319d309be3ede9cefc0bd9870396b87f (patch) | |
tree | 01fe4ac6fd5e4b223e8c02240f50544a45d03681 | |
parent | f86e4da7ae8084261d95565568354b92e5790373 (diff) | |
download | bcm5719-llvm-8162d4ad319d309be3ede9cefc0bd9870396b87f.tar.gz bcm5719-llvm-8162d4ad319d309be3ede9cefc0bd9870396b87f.zip |
Implements in IRgen gnu extensions missing LHS for
complex conditionals. Radar 8453812.
llvm-svn: 114376
-rw-r--r-- | clang/lib/CodeGen/CGExprComplex.cpp | 33 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 1 | ||||
-rw-r--r-- | clang/test/CodeGen/conditional-gnu-ext.c | 15 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp | 22 |
4 files changed, 58 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 79e9dd42ee2..517a8da34d3 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -102,6 +102,15 @@ public: // Visitor Methods //===--------------------------------------------------------------------===// + ComplexPairTy Visit(Expr *E) { + llvm::DenseMap<const Expr *, ComplexPairTy>::iterator I = + CGF.ConditionalSaveComplexExprs.find(E); + if (I != CGF.ConditionalSaveComplexExprs.end()) + return I->second; + + return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E); + } + ComplexPairTy VisitStmt(Stmt *S) { S->dump(CGF.getContext().getSourceManager()); assert(0 && "Stmt can't have complex result type!"); @@ -622,13 +631,6 @@ ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { ComplexPairTy ComplexExprEmitter:: VisitConditionalOperator(const ConditionalOperator *E) { - if (!E->getLHS()) { - CGF.ErrorUnsupported(E, "conditional operator with missing LHS"); - const llvm::Type *EltTy = - CGF.ConvertType(E->getType()->getAs<ComplexType>()->getElementType()); - llvm::Value *U = llvm::UndefValue::get(EltTy); - return ComplexPairTy(U, U); - } TestAndClearIgnoreReal(); TestAndClearIgnoreImag(); @@ -638,14 +640,19 @@ VisitConditionalOperator(const ConditionalOperator *E) { llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); - CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); + if (E->getLHS()) + CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); + else { + Expr *save = E->getSAVE(); + assert(save && "VisitConditionalOperator - save is null"); + // Intentianlly not doing direct assignment to ConditionalSaveExprs[save] !! + ComplexPairTy SaveVal = Visit(save); + CGF.ConditionalSaveComplexExprs[save] = SaveVal; + CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); + } CGF.EmitBlock(LHSBlock); - - // Handle the GNU extension for missing LHS. - assert(E->getLHS() && "Must have LHS for complex value"); - - ComplexPairTy LHS = Visit(E->getLHS()); + ComplexPairTy LHS = Visit(E->getTrueExpr()); LHSBlock = Builder.GetInsertBlock(); CGF.EmitBranch(ContBlock); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index d2fa57a9edc..8b0f12e418e 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -516,6 +516,7 @@ public: /// to the IR for this expression. Used to implement IR gen. for Gnu /// extension's missing LHS expression in a conditional operator expression. llvm::DenseMap<const Expr *, llvm::Value *> ConditionalSaveExprs; + llvm::DenseMap<const Expr *, ComplexPairTy> ConditionalSaveComplexExprs; EHScopeStack EHStack; diff --git a/clang/test/CodeGen/conditional-gnu-ext.c b/clang/test/CodeGen/conditional-gnu-ext.c index 5e5801af93c..2e32d3a0166 100644 --- a/clang/test/CodeGen/conditional-gnu-ext.c +++ b/clang/test/CodeGen/conditional-gnu-ext.c @@ -19,3 +19,18 @@ void test1 () { if (x != y) abort(); } + +// rdar://8453812 +_Complex int getComplex(_Complex int val) { + static int count; + if (count++) + abort(); + return val; +} + +_Complex int complx() { + _Complex int cond; + _Complex int rhs; + + return getComplex(1+2i) ? : rhs; +} diff --git a/clang/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp b/clang/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp index dfd9d414895..a3f9fd2190b 100644 --- a/clang/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp +++ b/clang/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp @@ -22,3 +22,25 @@ int main () { abort(); } } + +namespace radar8453812 { +extern "C" void abort(); +_Complex int getComplex(_Complex int val) { + static int count; + if (count++) + abort(); + return val; +} + +_Complex int cmplx() { + _Complex int cond; + _Complex int rhs; + + return getComplex(1+2i) ? : rhs; +} + +int main() { + cmplx(); + return 0; +} +} |