erik.pilkington created this revision. erik.pilkington added reviewers: arphaman, ahatanak. erik.pilkington requested review of this revision.
Clang used to emit a bad -Wbridge-cast diagnostic on the cast in the attached test. This was because, after 09abecef7 <https://reviews.llvm.org/rG09abecef7bbfda18d34f046954eaa4d491062839>, `struct __CFString` was not added to lookup, so the `objc_bridge` attribute wasn't getting duplicated onto the most recent declaration, causing us to fail to find it in `getObjCBridgeAttr`. This patch fixes this by instead walking through the redeclarations to find an appropriate bridge attribute. rdar://72823399 https://reviews.llvm.org/D99661 Files: clang/lib/Sema/SemaExprObjC.cpp clang/test/SemaObjCXX/bridge-cast-redecl.mm Index: clang/test/SemaObjCXX/bridge-cast-redecl.mm =================================================================== --- /dev/null +++ clang/test/SemaObjCXX/bridge-cast-redecl.mm @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=gnu++17 -verify %s + +// expected-no-diagnostics + +typedef const struct __CFString * CFStringRef; + +extern "C" { + typedef const struct __attribute__((objc_bridge(NSString))) __CFString * CFStringRef; + typedef struct __attribute__((objc_bridge_mutable(NSMutableString))) __CFString * CFMutableStringRef; +} + +@interface NSString @end +@interface NSMutableString : NSString @end + +void CFStringGetLength(CFStringRef theString); + +int main() { + CFStringGetLength((__bridge CFStringRef)(NSString *)0); +} Index: clang/lib/Sema/SemaExprObjC.cpp =================================================================== --- clang/lib/Sema/SemaExprObjC.cpp +++ clang/lib/Sema/SemaExprObjC.cpp @@ -3847,9 +3847,12 @@ QualType QT = TDNDecl->getUnderlyingType(); if (QT->isPointerType()) { QT = QT->getPointeeType(); - if (const RecordType *RT = QT->getAs<RecordType>()) - if (RecordDecl *RD = RT->getDecl()->getMostRecentDecl()) - return RD->getAttr<T>(); + if (const RecordType *RT = QT->getAs<RecordType>()) { + for (auto *Redecl : RT->getDecl()->redecls()) { + if (auto *attr = Redecl->getAttr<T>()) + return attr; + } + } } return nullptr; }
Index: clang/test/SemaObjCXX/bridge-cast-redecl.mm =================================================================== --- /dev/null +++ clang/test/SemaObjCXX/bridge-cast-redecl.mm @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=gnu++17 -verify %s + +// expected-no-diagnostics + +typedef const struct __CFString * CFStringRef; + +extern "C" { + typedef const struct __attribute__((objc_bridge(NSString))) __CFString * CFStringRef; + typedef struct __attribute__((objc_bridge_mutable(NSMutableString))) __CFString * CFMutableStringRef; +} + +@interface NSString @end +@interface NSMutableString : NSString @end + +void CFStringGetLength(CFStringRef theString); + +int main() { + CFStringGetLength((__bridge CFStringRef)(NSString *)0); +} Index: clang/lib/Sema/SemaExprObjC.cpp =================================================================== --- clang/lib/Sema/SemaExprObjC.cpp +++ clang/lib/Sema/SemaExprObjC.cpp @@ -3847,9 +3847,12 @@ QualType QT = TDNDecl->getUnderlyingType(); if (QT->isPointerType()) { QT = QT->getPointeeType(); - if (const RecordType *RT = QT->getAs<RecordType>()) - if (RecordDecl *RD = RT->getDecl()->getMostRecentDecl()) - return RD->getAttr<T>(); + if (const RecordType *RT = QT->getAs<RecordType>()) { + for (auto *Redecl : RT->getDecl()->redecls()) { + if (auto *attr = Redecl->getAttr<T>()) + return attr; + } + } } return nullptr; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits