r203043 - Objective-C properties. Fixes a crash in Sema where RHS of

Fariborz Jahanian fjahanian at apple.com
Wed Mar 5 16:34:05 PST 2014


Author: fjahanian
Date: Wed Mar  5 18:34:05 2014
New Revision: 203043

URL: http://llvm.org/viewvc/llvm-project?rev=203043&view=rev
Log:
Objective-C properties. Fixes a crash in Sema where RHS of
the property assignment is an lvalue for an incomplete type.
// rdar://15118128. Reviewed offline by John McCall.

Added:
    cfe/trunk/test/CodeGenObjCXX/property-lvalue-capture.mm
Modified:
    cfe/trunk/lib/Sema/SemaPseudoObject.cpp

Modified: cfe/trunk/lib/Sema/SemaPseudoObject.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaPseudoObject.cpp?rev=203043&r1=203042&r2=203043&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaPseudoObject.cpp (original)
+++ cfe/trunk/lib/Sema/SemaPseudoObject.cpp Wed Mar  5 18:34:05 2014
@@ -235,7 +235,10 @@ namespace {
     }
 
     /// Return true if assignments have a non-void result.
-    bool CanCaptureValueOfType(QualType ty) {
+    bool CanCaptureValue(Expr *exp) {
+      if (exp->isGLValue())
+        return true;
+      QualType ty = exp->getType();
       assert(!ty->isIncompleteType());
       assert(!ty->isDependentType());
 
@@ -461,7 +464,7 @@ PseudoOpBuilder::buildIncDecOperation(Sc
 
   // That's the postfix result.
   if (UnaryOperator::isPostfix(opcode) &&
-      (result.get()->isTypeDependent() || CanCaptureValueOfType(resultType))) {
+      (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) {
     result = capture(result.take());
     setResultToLastSemantic();
   }
@@ -762,7 +765,7 @@ ExprResult ObjCPropertyOpBuilder::buildS
     ObjCMessageExpr *msgExpr =
       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
     Expr *arg = msgExpr->getArg(0);
-    if (CanCaptureValueOfType(arg->getType()))
+    if (CanCaptureValue(arg))
       msgExpr->setArg(0, captureValueAsResult(arg));
   }
 
@@ -1368,7 +1371,7 @@ ExprResult ObjCSubscriptOpBuilder::build
     ObjCMessageExpr *msgExpr =
       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
     Expr *arg = msgExpr->getArg(0);
-    if (CanCaptureValueOfType(arg->getType()))
+    if (CanCaptureValue(arg))
       msgExpr->setArg(0, captureValueAsResult(arg));
   }
   

Added: cfe/trunk/test/CodeGenObjCXX/property-lvalue-capture.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/property-lvalue-capture.mm?rev=203043&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/property-lvalue-capture.mm (added)
+++ cfe/trunk/test/CodeGenObjCXX/property-lvalue-capture.mm Wed Mar  5 18:34:05 2014
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// rdar://15118128
+
+template <typename T> struct Quad2 {
+  Quad2() {}
+};
+
+typedef Quad2<double> Quad2d;
+
+ at interface Root @end
+
+ at interface PAGeometryFrame
+- (const Quad2d &)quad;
+- (void)setQuad:(const Quad2d &)quad;
+ at end
+
+ at interface PA2DScaleTransform  : Root
+ at end
+
+ at implementation PA2DScaleTransform
+- (void)transformFrame:(PAGeometryFrame *)frame {
+ PAGeometryFrame *result;
+ result.quad  = frame.quad;
+}
+ at end
+
+// CHECK:   [[TWO:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", !invariant.load !5
+// CHECK:   [[THREE:%.*]] = bitcast [[ONET:%.*]]* [[ONE:%.*]] to i8*
+// CHECK:   [[CALL:%.*]] = call %struct.Quad2* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %struct.Quad2* (i8*, i8*)*)(i8* [[THREE]], i8* [[TWO]])
+// CHECK:   [[FOUR:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_2", !invariant.load !5
+// CHECK:   [[FIVE:%.*]] = bitcast [[ONET]]* [[ZERO:%.*]] to i8*
+// CHECK:   call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.Quad2*)*)(i8* [[FIVE]], i8* [[FOUR]], %struct.Quad2* [[CALL]])
+
+
+struct A {
+ void *ptr;
+ A();
+ A(const A &);
+ ~A();
+};
+
+ at interface C
+- (void) setProp: (const A&) value;
+ at end
+void test(C *c, const A &a) {
+ const A &result = c.prop = a;
+}
+
+// CHECK:   [[ONE1:%.*]] = load %struct.A** [[AADDR:%.*]], align 8
+// CHECK:   [[TWO1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_5", !invariant.load !5
+// CHECK:   [[THREE1:%.*]] = bitcast [[TWOT:%.*]]* [[ZERO1:%.*]] to i8*
+// CHECK:   call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.A*)*)(i8* [[THREE1]], i8* [[TWO1]], %struct.A* [[ONE1]])
+// CHECK:   store %struct.A* [[ONE1]], %struct.A** [[RESULT:%.*]], align 8





More information about the cfe-commits mailing list