From 15ced59e27cdc4c4978b9422ca5f8805f7f64b64 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 8 Feb 2010 21:09:39 +0000 Subject: [PATCH] Merge block/function pointer types with objc's __weak attribute properly and avoid bogus warning. This is an objective-c fix only. objective-c++ follows different code pass and requires separate fix (which will come at a later time). Fixes radar 7214820. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95571 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTContext.cpp | 19 ++++++++++++++++--- test/SemaObjC/gc-attr-block-ivar.m | 17 +++++++++++++++++ test/SemaObjC/objc2-merge-gc-attribue-decl.m | 4 ++-- 3 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 test/SemaObjC/gc-attr-block-ivar.m diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 7e03f56f62..386a5f3c7b 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4303,11 +4303,24 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) { bool allRTypes = true; // Check return type - QualType retType = mergeTypes(lbase->getResultType(), rbase->getResultType()); + QualType LRES = lbase->getResultType(); + QualType RRES = rbase->getResultType(); + Qualifiers::GC GC_L = LRES.getObjCGCAttr(); + Qualifiers::GC GC_R = RRES.getObjCGCAttr(); + // __weak/__strong attribute on one function/block return type but + // not the other is OK. + if (GC_L != GC_R) { + if (GC_R == Qualifiers::GCNone) + RRES = getObjCGCQualType(RRES, GC_L); + else if (GC_L == Qualifiers::GCNone) + LRES = getObjCGCQualType(LRES, GC_R); + } + + QualType retType = mergeTypes(LRES, RRES); if (retType.isNull()) return QualType(); - if (getCanonicalType(retType) != getCanonicalType(lbase->getResultType())) + if (getCanonicalType(retType) != getCanonicalType(LRES)) allLTypes = false; - if (getCanonicalType(retType) != getCanonicalType(rbase->getResultType())) + if (getCanonicalType(retType) != getCanonicalType(RRES)) allRTypes = false; // FIXME: double check this bool NoReturn = lbase->getNoReturnAttr() || rbase->getNoReturnAttr(); diff --git a/test/SemaObjC/gc-attr-block-ivar.m b/test/SemaObjC/gc-attr-block-ivar.m new file mode 100644 index 0000000000..c3e00337fd --- /dev/null +++ b/test/SemaObjC/gc-attr-block-ivar.m @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -fobjc-gc %s + +@interface Intf { +@public + void (^block) (id); + __weak void (^weak_block) (id); + void (*fptr) (id); + __weak void (*weak_fptr) (id); +} +@end + +int main() { + Intf *observer; + return (observer->block != observer->weak_block || + observer->fptr != observer->weak_fptr); +} + diff --git a/test/SemaObjC/objc2-merge-gc-attribue-decl.m b/test/SemaObjC/objc2-merge-gc-attribue-decl.m index 673a7417e3..f8d5f0018d 100644 --- a/test/SemaObjC/objc2-merge-gc-attribue-decl.m +++ b/test/SemaObjC/objc2-merge-gc-attribue-decl.m @@ -10,8 +10,8 @@ extern id p1; extern id CFRunLoopGetMain(); extern __strong id CFRunLoopGetMain(); -extern __weak id WLoopGetMain(); // expected-note {{previous declaration is here}} -extern id WLoopGetMain(); // expected-error {{conflicting types for 'WLoopGetMain'}} +extern __weak id WLoopGetMain(); +extern id WLoopGetMain(); extern id p3; // expected-note {{previous definition is here}} extern __weak id p3; // expected-error {{redefinition of 'p3' with a different type}} -- 2.40.0