From: Fariborz Jahanian Date: Mon, 19 Dec 2011 21:06:15 +0000 (+0000) Subject: objc-arc: bridge casts in non-objc-arc mode are ignord. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=00852e41261f9860233d3b407fce0506346cdacb;p=clang objc-arc: bridge casts in non-objc-arc mode are ignord. But, warn too. // rdar://10597832 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146904 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 28f9f93419..7ce2a8e928 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -326,6 +326,9 @@ def err_illegal_super_cast : Error< let CategoryName = "ARC Parse Issue" in { def err_arc_bridge_retain : Error< "unknown cast annotation __bridge_retain; did you mean __bridge_retained?">; +def warn_arc_bridge_retain : Warning< + "bridge casts will have no effect in non-arc mode and will be ignored">, + InGroup>; } def err_objc_illegal_visibility_spec : Error< diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index 94ca1789f3..f5b417c72c 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -125,7 +125,9 @@ static void AddKeyword(StringRef Keyword, else if (LangOpts.OpenCL && (Flags & KEYOPENCL)) AddResult = 2; else if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) AddResult = 2; else if (LangOpts.C1X && (Flags & KEYC1X)) AddResult = 2; - else if (LangOpts.ObjCAutoRefCount && (Flags & KEYARC)) AddResult = 2; + // We treat bridge casts as objective-C keywords so we can warn on them + // in non-arc mode. + else if (LangOpts.ObjC2 && (Flags & KEYARC)) AddResult = 2; else if (LangOpts.CPlusPlus && (Flags & KEYCXX0X)) AddResult = 3; // Don't add this keyword if disabled in this language. diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 07e61d80ba..34ae1d3b16 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -99,13 +99,6 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, // allow this in C, since one might have block pointers in structs that // are used in pure C code and in Objective-C ARC. Builder.defineMacro("__unsafe_unretained", ""); - - // The Objective-C bridged cast keywords are defined to nothing in non-ARC - // mode; then they become normal, C-style casts. - Builder.defineMacro("__bridge", ""); - Builder.defineMacro("__bridge_transfer", ""); - Builder.defineMacro("__bridge_retained", ""); - Builder.defineMacro("__bridge_retain", ""); } if (Opts.Static) diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index dcbee4f9e6..bb446f5ab2 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -1817,9 +1817,23 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, return ExprError(); } + // Diagnose use of bridge casts in non-arc mode. + bool BridgeCast = (getLang().ObjC2 && + (Tok.is(tok::kw___bridge) || + Tok.is(tok::kw___bridge_transfer) || + Tok.is(tok::kw___bridge_retained) || + Tok.is(tok::kw___bridge_retain))); + if (BridgeCast && !getLang().ObjCAutoRefCount) { + SourceLocation BridgeKeywordLoc = ConsumeToken(); + if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) + Diag(BridgeKeywordLoc, diag::warn_arc_bridge_retain) + << FixItHint::CreateReplacement(BridgeKeywordLoc, + ""); + BridgeCast = false; + } + // None of these cases should fall through with an invalid Result // unless they've already reported an error. - if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { Diag(Tok, diag::ext_gnu_statement_expr); ParsedAttributes attrs(AttrFactory); @@ -1829,11 +1843,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // If the substmt parsed correctly, build the AST node. if (!Stmt.isInvalid()) Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.take(), Tok.getLocation()); - } else if (ExprType >= CompoundLiteral && - (Tok.is(tok::kw___bridge) || - Tok.is(tok::kw___bridge_transfer) || - Tok.is(tok::kw___bridge_retained) || - Tok.is(tok::kw___bridge_retain))) { + } else if (ExprType >= CompoundLiteral && BridgeCast) { tok::TokenKind tokenKind = Tok.getKind(); SourceLocation BridgeKeywordLoc = ConsumeToken(); diff --git a/test/SemaObjC/arc-bridged-cast.m b/test/SemaObjC/arc-bridged-cast.m index 47476c8306..d3853f76f6 100644 --- a/test/SemaObjC/arc-bridged-cast.m +++ b/test/SemaObjC/arc-bridged-cast.m @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fblocks %s typedef const void *CFTypeRef; typedef const struct __CFString *CFStringRef; diff --git a/test/SemaObjC/illegal-nonarc-bridged-cast.m b/test/SemaObjC/illegal-nonarc-bridged-cast.m new file mode 100644 index 0000000000..04d82b9557 --- /dev/null +++ b/test/SemaObjC/illegal-nonarc-bridged-cast.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fblocks -verify %s +// rdar://10597832 + +typedef const void *CFTypeRef; +typedef const struct __CFString *CFStringRef; + +@interface NSString +@end + +CFTypeRef CFCreateSomething(); +CFStringRef CFCreateString(); +CFTypeRef CFGetSomething(); +CFStringRef CFGetString(); + +id CreateSomething(); +NSString *CreateNSString(); + +void from_cf() { + id obj1 = (__bridge_transfer id)CFCreateSomething(); // expected-warning {{bridge casts will have no effect in non-arc mode and will be ignored}} + id obj2 = (__bridge_transfer NSString*)CFCreateString(); // expected-warning {{bridge casts will have no effect in non-arc mode and will be ignored}} + (__bridge int*)CFCreateSomething(); // expected-warning {{bridge casts will have no effect in non-arc mode and will be ignored}} \ + // expected-warning {{expression result unused}} + id obj3 = (__bridge id)CFGetSomething(); // expected-warning {{bridge casts will have no effect in non-arc mode and will be ignored}} + id obj4 = (__bridge NSString*)CFGetString(); // expected-warning {{bridge casts will have no effect in non-arc mode and will be ignored}} +} + +void to_cf(id obj) { + CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); // expected-warning {{bridge casts will have no effect in non-arc mode and will be ignored}} + CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString(); // expected-warning {{bridge casts will have no effect in non-arc mode and will be ignored}} + CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); // expected-warning {{bridge casts will have no effect in non-arc mode and will be ignored}} + CFStringRef cf4 = (__bridge CFStringRef)CreateNSString(); // expected-warning {{bridge casts will have no effect in non-arc mode and will be ignored}} +} + +void fixits() { + id obj1 = (id)CFCreateSomething(); + CFTypeRef cf1 = (CFTypeRef)CreateSomething(); +}