]> granicus.if.org Git - clang/commitdiff
IRgen for gnu extension's conditional lvalue expression
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 21 Sep 2010 18:32:21 +0000 (18:32 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 21 Sep 2010 18:32:21 +0000 (18:32 +0000)
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

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

index 9b69297bbed00f768cb8e27cc88731917ef6b24b..78c1da5060cedc6a5530b6ce3c993445f3c3f1e4 100644 (file)
@@ -495,6 +495,11 @@ LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) {
 /// length type, this is not possible.
 ///
 LValue CodeGenFunction::EmitLValue(const Expr *E) {
+  llvm::DenseMap<const Expr *, LValue>::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())
index 8b0f12e418eef6f24182648d13ca86a020b95eaa..740371115527c7daaef4653bf0e17fd6f3517efc 100644 (file)
@@ -517,6 +517,7 @@ public:
   /// extension's missing LHS expression in a conditional operator expression.
   llvm::DenseMap<const Expr *, llvm::Value *> ConditionalSaveExprs;
   llvm::DenseMap<const Expr *, ComplexPairTy> ConditionalSaveComplexExprs;
+  llvm::DenseMap<const Expr *, LValue> ConditionalSaveLValueExprs;
 
   EHScopeStack EHStack;
 
index a3f9fd2190b401456abae3673e353723915b9599..25eafc7e1b103d12fb536ff922eda89f50f596c0 100644 (file)
@@ -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;
 }
 }