aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGExprComplex.cpp33
-rw-r--r--lib/CodeGen/CodeGenFunction.h1
-rw-r--r--test/CodeGen/conditional-gnu-ext.c15
-rw-r--r--test/CodeGenCXX/gnu-conditional-scalar-ext.cpp22
4 files changed, 58 insertions, 13 deletions
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
index 79e9dd42ee..517a8da34d 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/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/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index d2fa57a9ed..8b0f12e418 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/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/test/CodeGen/conditional-gnu-ext.c b/test/CodeGen/conditional-gnu-ext.c
index 5e5801af93..2e32d3a016 100644
--- a/test/CodeGen/conditional-gnu-ext.c
+++ b/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/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp b/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp
index dfd9d41489..a3f9fd2190 100644
--- a/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp
+++ b/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;
+}
+}