]> granicus.if.org Git - clang/commitdiff
Fix rdar://6095061 - gcc allows __builtin_choose_expr as an lvalue
authorChris Lattner <sabre@nondot.org>
Fri, 12 Dec 2008 05:35:08 +0000 (05:35 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 12 Dec 2008 05:35:08 +0000 (05:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60924 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Expr.cpp
lib/CodeGen/CGExpr.cpp
test/Sema/exprs.c

index b5f966d86219f0c35eee2bab08ea55c4ae818d42..728b13534a349f0bb974fc42f17f91540a27b4cc 100644 (file)
@@ -467,6 +467,13 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
   }
   case CompoundLiteralExprClass: // C99 6.5.2.5p5
     return LV_Valid;
+  case ChooseExprClass:
+    // __builtin_choose_expr is an lvalue if the selected operand is.
+    if (cast<ChooseExpr>(this)->isConditionTrue(Ctx))
+      return cast<ChooseExpr>(this)->getLHS()->isLvalue(Ctx);
+    else
+      return cast<ChooseExpr>(this)->getRHS()->isLvalue(Ctx);
+
   case ExtVectorElementExprClass:
     if (cast<ExtVectorElementExpr>(this)->containsDuplicateElements())
       return LV_DuplicateVectorComponents;
@@ -476,7 +483,7 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
   case ObjCPropertyRefExprClass: // FIXME: check if read-only property.
     return LV_Valid;
   case ObjCKVCRefExprClass: // FIXME: check if read-only property.
-      return LV_Valid;
+    return LV_Valid;
   case PredefinedExprClass:
     return LV_Valid;
   case VAArgExprClass:
@@ -1213,8 +1220,7 @@ bool ChooseExpr::isConditionTrue(ASTContext &C) const {
   return getCond()->getIntegerConstantExprValue(C) != 0;
 }
 
-static int64_t evaluateOffsetOf(ASTContext& C, const Expr *E)
-{
+static int64_t evaluateOffsetOf(ASTContext& C, const Expr *E) {
   if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
     QualType Ty = ME->getBase()->getType();
     
index bdbd5caa089e37cdb31a0facb306ea0a155ebc58..a7a64e3860aeb1b9a9adc270ff0b0d6419dd5659 100644 (file)
@@ -146,6 +146,12 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
   case Expr::MemberExprClass: return EmitMemberExpr(cast<MemberExpr>(E));
   case Expr::CompoundLiteralExprClass:
     return EmitCompoundLiteralLValue(cast<CompoundLiteralExpr>(E));
+  case Expr::ChooseExprClass:
+    // __builtin_choose_expr is the lvalue of the selected operand.
+    if (cast<ChooseExpr>(E)->isConditionTrue(getContext()))
+      return EmitLValue(cast<ChooseExpr>(E)->getLHS());
+    else
+      return EmitLValue(cast<ChooseExpr>(E)->getRHS());
   }
 }
 
index db252b8d9d50cc46a4e388edd18dfbf931466e64..1b8e13405f1a0fef68d4993eeff74846ac85d230 100644 (file)
@@ -38,3 +38,10 @@ void test7(int *P, _Complex float Gamma) {
    P = (P-42) + Gamma*4;  // expected-error {{invalid operands to binary expression ('int *' and '_Complex float')}}
 }
 
+
+// rdar://6095061
+int test8(void) {
+  int i;
+  __builtin_choose_expr (0, 42, i) = 10;
+  return i;
+}