aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaExprCXX.cpp12
-rw-r--r--test/CodeGenObjCXX/property-object-conditional-exp.mm36
2 files changed, 46 insertions, 2 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index f30fcf7312..e4ee90d668 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2592,8 +2592,16 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// the result is of that type [...]
bool Same = Context.hasSameType(LTy, RTy);
if (Same && LHS->isLvalue(Context) == Expr::LV_Valid &&
- RHS->isLvalue(Context) == Expr::LV_Valid)
- return LTy;
+ RHS->isLvalue(Context) == Expr::LV_Valid) {
+ // In this context, property reference is really a message call and
+ // is not considered an l-value.
+ bool lhsProperty = (isa<ObjCPropertyRefExpr>(LHS) ||
+ isa<ObjCImplicitSetterGetterRefExpr>(LHS));
+ bool rhsProperty = (isa<ObjCPropertyRefExpr>(RHS) ||
+ isa<ObjCImplicitSetterGetterRefExpr>(RHS));
+ if (!lhsProperty && !rhsProperty)
+ return LTy;
+ }
// C++0x 5.16p5
// Otherwise, the result is an rvalue. If the second and third operands
diff --git a/test/CodeGenObjCXX/property-object-conditional-exp.mm b/test/CodeGenObjCXX/property-object-conditional-exp.mm
new file mode 100644
index 0000000000..0f44a2248a
--- /dev/null
+++ b/test/CodeGenObjCXX/property-object-conditional-exp.mm
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+struct CGRect {
+ char* origin;
+ unsigned size;
+};
+typedef struct CGRect CGRect;
+
+extern "C" bool CGRectIsEmpty(CGRect);
+
+@interface Foo {
+ CGRect out;
+}
+@property CGRect bounds;
+- (CGRect) out;
+@end
+
+
+@implementation Foo
+
+- (void)bar {
+ CGRect dataRect;
+ CGRect virtualBounds;
+
+ dataRect = CGRectIsEmpty(virtualBounds) ? self.bounds : virtualBounds;
+ dataRect = CGRectIsEmpty(virtualBounds) ? [self bounds] : virtualBounds;
+ dataRect = CGRectIsEmpty(virtualBounds) ? virtualBounds : self.bounds;
+
+ dataRect = CGRectIsEmpty(virtualBounds) ? self.out : virtualBounds;
+ dataRect = CGRectIsEmpty(virtualBounds) ? [self out] : virtualBounds;
+ dataRect = CGRectIsEmpty(virtualBounds) ? virtualBounds : self.out;
+}
+
+@dynamic bounds;
+- (CGRect) out { return out; }
+@end