summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2008-09-24 22:26:48 +0000
committerSteve Naroff <snaroff@apple.com>2008-09-24 22:26:48 +0000
commitc60873ce44253fdee24f3f6982701837b1ef2bf5 (patch)
tree57a132c804ad68f8faeacf6af1a4ed312c25459d
parent2d59db7ae401c4686476671afcceb54312b4133e (diff)
downloadbcm5719-llvm-c60873ce44253fdee24f3f6982701837b1ef2bf5.tar.gz
bcm5719-llvm-c60873ce44253fdee24f3f6982701837b1ef2bf5.zip
Fix <rdar://problem/6243788> clang: Incorrect return statement for Blocks?
llvm-svn: 56590
-rw-r--r--clang/lib/Sema/SemaStmt.cpp4
-rw-r--r--clang/test/Sema/block-return.c20
2 files changed, 23 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 3cadd526a77..df832b70dc7 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -679,7 +679,9 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// the block from it.
if (CurBlock->ReturnType == 0) {
if (RetValExp) {
- UsualUnaryConversions(RetValExp);
+ // Don't call UsualUnaryConversions(), since we don't want to do
+ // integer promotions here.
+ DefaultFunctionArrayConversion(RetValExp);
CurBlock->ReturnType = RetValExp->getType().getTypePtr();
} else
CurBlock->ReturnType = Context.VoidTy.getTypePtr();
diff --git a/clang/test/Sema/block-return.c b/clang/test/Sema/block-return.c
index 93511dbd7e3..2110f2ce452 100644
--- a/clang/test/Sema/block-return.c
+++ b/clang/test/Sema/block-return.c
@@ -50,3 +50,23 @@ typedef int (^CL2)(void);
CL2 foo2() {
return ^{ return 1; }; // expected-error {{returning block that lives on the local stack}}
}
+
+typedef unsigned int * uintptr_t;
+typedef char Boolean;
+typedef int CFBasicHash;
+
+#define INVOKE_CALLBACK2(P, A, B) (P)(A, B)
+
+typedef struct {
+ Boolean (^isEqual)(const CFBasicHash *, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key);
+} CFBasicHashCallbacks;
+
+int foo3() {
+ CFBasicHashCallbacks cb;
+
+ Boolean (*value_equal)(uintptr_t, uintptr_t) = 0;
+
+ cb.isEqual = ^(const CFBasicHash *table, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key) {
+ return (Boolean)(uintptr_t)INVOKE_CALLBACK2(value_equal, (uintptr_t)stack_value_or_key1, (uintptr_t)stack_value_or_key2);
+ };
+}
OpenPOWER on IntegriCloud