blocks: fixes an ast bug when block pointer variable
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 7 Jun 2013 00:48:14 +0000 (00:48 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 7 Jun 2013 00:48:14 +0000 (00:48 +0000)
is evaluated in a condition expression and then
dereferenced to envoke the block. This is
pr15663 and I applied a slight variation of the
patch with a test case. (patch is from
Arthur O'Dwyer). Also // rdar://14085217

llvm-svn: 183471

clang/lib/Sema/SemaExpr.cpp
clang/test/CodeGen/blocks.c

index 2a3482238d86090dd5dd753231d8f53051787cf7..7bbbe72ac31635f56d2ae786ff25ab3023449ee5 100644 (file)
@@ -5149,7 +5149,10 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
 
   // The pointer types are compatible.
   QualType ResultTy = CompositeTy.withCVRQualifiers(MergedCVRQual);
-  ResultTy = S.Context.getPointerType(ResultTy);
+  if (isa<BlockPointerType>(LHSTy))
+    ResultTy = S.Context.getBlockPointerType(ResultTy);
+  else
+    ResultTy = S.Context.getPointerType(ResultTy);
 
   LHS = S.ImpCastExprToType(LHS.take(), ResultTy, CK_BitCast);
   RHS = S.ImpCastExprToType(RHS.take(), ResultTy, CK_BitCast);
index 71f7171c7181c734efe70a3f0349b680f760baa3..47708e7481f7676bc808e7d6f68e216f8535138a 100644 (file)
@@ -66,3 +66,15 @@ void f5(void) {
   // CHECK: alloca <{ i8*, i32, i32, i8*, {{%.*}}*, [12 x i8], [[F5:%.*]] }>, align 16
   f5_helper(^(struct F5 *slot) { *slot = value; });
 }
+
+// rdar://14085217
+void (^b)() = ^{};
+int main() {
+   (b?: ^{})();
+}
+// CHECK: [[ZERO:%.*]] = load void (...)** @b
+// CHECK-NEXT: [[TB:%.*]] = icmp ne void (...)* [[ZERO]], null
+// CHECK-NEXT: br i1 [[TB]], label [[CT:%.*]], label [[CF:%.*]]
+// CHECK: [[ONE:%.*]] = bitcast void (...)* [[ZERO]] to void ()*
+// CHECK-NEXT:   br label [[CE:%.*]]
+