]> granicus.if.org Git - clang/commitdiff
Bind function "r-values" as l-values when emitting them as
authorJohn McCall <rjmccall@apple.com>
Tue, 8 Nov 2011 22:54:08 +0000 (22:54 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 8 Nov 2011 22:54:08 +0000 (22:54 +0000)
opaque values.  Silly C type system.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144144 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenObjC/property.m

index d7e3168a3a8f532676522f4f7359c46e71d461bf..4d14d18e595ad4fc9d7cc66a9b4a5345510e1539 100644 (file)
@@ -2137,7 +2137,7 @@ LValue CodeGenFunction::EmitNullInitializationLValue(
 }
 
 LValue CodeGenFunction::EmitOpaqueValueLValue(const OpaqueValueExpr *e) {
-  assert(e->isGLValue() || e->getType()->isRecordType());
+  assert(OpaqueValueMappingData::shouldBindAsLValue(e));
   return getOpaqueLValueMapping(e);
 }
 
index 3a0be7a5627d25f76a6644aab3e8ec358b3b71df..383eb587ca530d0e8b47ce3556dad7b023382ea9 100644 (file)
@@ -970,7 +970,14 @@ public:
     OpaqueValueMappingData() : OpaqueValue(0) {}
 
     static bool shouldBindAsLValue(const Expr *expr) {
-      return expr->isGLValue() || expr->getType()->isRecordType();
+      // gl-values should be bound as l-values for obvious reasons.
+      // Records should be bound as l-values because IR generation
+      // always keeps them in memory.  Expressions of function type
+      // act exactly like l-values but are formally required to be
+      // r-values in C.
+      return expr->isGLValue() ||
+             expr->getType()->isRecordType() ||
+             expr->getType()->isFunctionType();
     }
 
     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
index 3cc9200f333c8772add5ea48fd7206d9996b980f..30f68e5b27f1bdad15a4883d55fa7cbb14bc6471 100644 (file)
@@ -112,3 +112,14 @@ void test4(Test4 *t) {
 @implementation Test5
 @synthesize x = _x;
 @end
+
+// rdar://problem/10410531
+@interface Test6
+@property void (*prop)(void);
+@end
+
+void test6_func(void);
+void test6(Test6 *a) {
+  a.prop = test6_func;
+}
+