]> granicus.if.org Git - clang/commitdiff
Implements in IRgen gnu extensions missing LHS for
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 20 Sep 2010 23:50:22 +0000 (23:50 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 20 Sep 2010 23:50:22 +0000 (23:50 +0000)
complex conditionals. Radar 8453812.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114376 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGen/conditional-gnu-ext.c
test/CodeGenCXX/gnu-conditional-scalar-ext.cpp

index 79e9dd42ee2827122c4fa0530e533f0efacece3a..517a8da34d38c89f5f6addc88d91a79263705628 100644 (file)
@@ -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);
 
index d2fa57a9edc350d0f785dcc0fdcb23baf70bfb91..8b0f12e418eef6f24182648d13ca86a020b95eaa 100644 (file)
@@ -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;
 
index 5e5801af93c795583df5750a58990b0e873d4b0d..2e32d3a01669a4c2738e6d1b7d91f2474a20e74b 100644 (file)
@@ -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;
+}
index dfd9d41489558ec89aae30c7f786435217536ef7..a3f9fd2190b401456abae3673e353723915b9599 100644 (file)
@@ -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;
+}
+}