Fix a block sema bug where result type of initializer
is unqualified but its initialized is qualified.
This is for c only and fixes the imm. problem.
c++ is more involved and is wip.
// rdar://8979379


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125386 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 03c0abd..dcbfd9d 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -5076,9 +5076,14 @@
 
   // Check return type
   QualType retType;
-  if (OfBlockPointer)
-    retType = mergeTypes(rbase->getResultType(), lbase->getResultType(), true,
-                         Unqualified);
+  if (OfBlockPointer) {
+    QualType RHS = rbase->getResultType();
+    QualType LHS = lbase->getResultType();
+    bool UnqualifiedResult = Unqualified;
+    if (!UnqualifiedResult)
+      UnqualifiedResult = (!RHS.hasQualifiers() && LHS.hasQualifiers());
+    retType = mergeTypes(RHS, LHS, true, UnqualifiedResult);
+  }
   else
     retType = mergeTypes(lbase->getResultType(), rbase->getResultType(), false,
                          Unqualified);
diff --git a/test/Sema/block-call.c b/test/Sema/block-call.c
index fbf0da4..2aa1422 100644
--- a/test/Sema/block-call.c
+++ b/test/Sema/block-call.c
@@ -13,7 +13,7 @@
   int (^IFP) () = PFR; // OK
 
 
-  const int (^CIC) () = IFP; // expected-error {{incompatible block pointer types initializing 'const int (^)()' with an expression of type 'int (^)()'}}
+  const int (^CIC) () = IFP; // OK -  initializing 'const int (^)()' with an expression of type 'int (^)()'}}
 
   const int (^CICC) () = CIC;
 
diff --git a/test/Sema/block-return.c b/test/Sema/block-return.c
index 23dbbc2..c6e1e9d 100644
--- a/test/Sema/block-return.c
+++ b/test/Sema/block-return.c
@@ -110,7 +110,7 @@
 
 void foo7()
 {
- const int (^BB) (void) = ^{ const int i = 1; return i; }; // expected-error{{incompatible block pointer types initializing 'const int (^)(void)' with an expression of type 'int (^)(void)'}}
+ const int (^BB) (void) = ^{ const int i = 1; return i; }; // OK - initializing 'const int (^)(void)' with an expression of type 'int (^)(void)'
 
  const int (^CC) (void)  = ^const int{ const int i = 1; return i; };
 
diff --git a/test/SemaObjC/block-return.m b/test/SemaObjC/block-return.m
new file mode 100644
index 0000000..15c3fb6
--- /dev/null
+++ b/test/SemaObjC/block-return.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -fobjc-gc-only %s
+// rdar://8979379
+
+@interface NSString
+- (__attribute__((objc_gc(strong))) const char *)UTF8String;
+@end
+
+int main() {
+__attribute__((objc_gc(strong))) char const *(^libraryNameForIndex)() = ^() {
+        NSString *moduleName;
+        return [moduleName UTF8String];
+    };
+}