summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2014-03-06 00:34:05 +0000
committerFariborz Jahanian <fjahanian@apple.com>2014-03-06 00:34:05 +0000
commit15dde89357c4a62a263cee0dddd52c8770a22cad (patch)
tree590d39d5c4a07132e03ff0944a769043388d975f
parentbb29e518c80d672ce9413b9dc0f086a5eb5b463b (diff)
downloadbcm5719-llvm-15dde89357c4a62a263cee0dddd52c8770a22cad.tar.gz
bcm5719-llvm-15dde89357c4a62a263cee0dddd52c8770a22cad.zip
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. llvm-svn: 203043
-rw-r--r--clang/lib/Sema/SemaPseudoObject.cpp11
-rw-r--r--clang/test/CodeGenObjCXX/property-lvalue-capture.mm53
2 files changed, 60 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp
index 81657e366e5..0f1df58e6d1 100644
--- a/clang/lib/Sema/SemaPseudoObject.cpp
+++ b/clang/lib/Sema/SemaPseudoObject.cpp
@@ -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(Scope *Sc, SourceLocation opcLoc,
// 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::buildSet(Expr *op, SourceLocation opcLoc,
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::buildSet(Expr *op, SourceLocation opcLoc,
ObjCMessageExpr *msgExpr =
cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
Expr *arg = msgExpr->getArg(0);
- if (CanCaptureValueOfType(arg->getType()))
+ if (CanCaptureValue(arg))
msgExpr->setArg(0, captureValueAsResult(arg));
}
diff --git a/clang/test/CodeGenObjCXX/property-lvalue-capture.mm b/clang/test/CodeGenObjCXX/property-lvalue-capture.mm
new file mode 100644
index 00000000000..a4024fd29a3
--- /dev/null
+++ b/clang/test/CodeGenObjCXX/property-lvalue-capture.mm
@@ -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;
+
+@interface Root @end
+
+@interface PAGeometryFrame
+- (const Quad2d &)quad;
+- (void)setQuad:(const Quad2d &)quad;
+@end
+
+@interface PA2DScaleTransform : Root
+@end
+
+@implementation PA2DScaleTransform
+- (void)transformFrame:(PAGeometryFrame *)frame {
+ PAGeometryFrame *result;
+ result.quad = frame.quad;
+}
+@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();
+};
+
+@interface C
+- (void) setProp: (const A&) value;
+@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
OpenPOWER on IntegriCloud