From 3911a1a0ab0bbbf2304db8e965f5b8365eb6887b Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 25 Sep 2010 01:08:05 +0000 Subject: [PATCH] Fix a NYI in IRGen which was due to incorrect AST for property reference expression (of c++ object type) in the conditional expression. Fixes // rdar://8291337 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114783 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExprCXX.cpp | 12 +++++-- .../property-object-conditional-exp.mm | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 test/CodeGenObjCXX/property-object-conditional-exp.mm 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(LHS) || + isa(LHS)); + bool rhsProperty = (isa(RHS) || + isa(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 -- 2.40.0