<div dir="ltr">Hi John,<div><br></div><div>this breaks programs that use __weak and target 10.6, like so:</div><div><br></div><div><div>$ cat test.m</div><div>#import <Foundation/Foundation.h></div><div>@interface I : NSObject {</div><div> __weak NSObject* foo_;</div><div>}</div><div>- (NSObject*)foo;</div><div>@end</div><div><br></div><div>@implementation I</div><div>- (NSObject *)foo {</div><div> return foo_;</div><div>}</div><div>@end</div><div>$ clang -c test.m -mmacosx-version-min=10.6 # works with Xcode's clang</div><div>$ ~/src/llvm-build/bin/clang -c test.m -isysroot $(xcrun -show-sdk-path) -mmacosx-version-min=10.6</div><div>test.m:10:10: error: 'foo_' is unavailable: cannot use weak references because the current deployment target does not support them</div><div> return foo_;</div><div> ^</div><div>test.m:3:20: note: unsupported declaration here</div><div> __weak NSObject* foo_;</div><div> ^</div><div>test.m:3:20: error: cannot create __weak reference because the current deployment target does not support weak references</div><div> __weak NSObject* foo_;</div><div> ^</div><div>2 errors generated.</div></div><div><br></div><div><br></div><div>We target 10.6 (and don't use ARC) and some library we use has __weak ivars. After this change, we can't build it any longer. This isn't a huge issue: we can change the library to use a WEAK macro that expands to nothing for us and __weak if ARC is enabled, but it sounded like you're interested in hearing about this.</div><div><br></div><div>Nico</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 22, 2015 at 11:38 AM, John McCall via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rjmccall<br>
Date: Thu Oct 22 13:38:17 2015<br>
New Revision: 251041<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=251041&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=251041&view=rev</a><br>
Log:<br>
Define weak and __weak to mean ARC-style weak references, even in MRC.<br>
<br>
Previously, __weak was silently accepted and ignored in MRC mode.<br>
That makes this a potentially source-breaking change that we have to<br>
roll out cautiously. Accordingly, for the time being, actual support<br>
for __weak references in MRC is experimental, and the compiler will<br>
reject attempts to actually form such references. The intent is to<br>
eventually enable the feature by default in all non-GC modes.<br>
(It is, of course, incompatible with ObjC GC's interpretation of<br>
__weak.)<br>
<br>
If you like, you can enable this feature with<br>
-Xclang -fobjc-weak<br>
but like any -Xclang option, this option may be removed at any point,<br>
e.g. if/when it is eventually enabled by default.<br>
<br>
This patch also enables the use of the ARC __unsafe_unretained qualifier<br>
in MRC. Unlike __weak, this is being enabled immediately. Since<br>
variables are essentially __unsafe_unretained by default in MRC,<br>
the only practical uses are (1) communication and (2) changing the<br>
default behavior of by-value block capture.<br>
<br>
As an implementation matter, this means that the ObjC ownership<br>
qualifiers may appear in any ObjC language mode, and so this patch<br>
removes a number of checks for getLangOpts().ObjCAutoRefCount<br>
that were guarding the processing of these qualifiers. I don't<br>
expect this to be a significant drain on performance; it may even<br>
be faster to just check for these qualifiers directly on a type<br>
(since it's probably in a register anyway) than to do N dependent<br>
loads to grab the LangOptions.<br>
<br>
rdar://9674298<br>
<br>
Added:<br>
cfe/trunk/test/CodeGenObjC/mrc-weak.m<br>
cfe/trunk/test/SemaObjC/mrc-weak.m<br>
Removed:<br>
cfe/trunk/test/SemaObjC/nonarc-weak.m<br>
Modified:<br>
cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td<br>
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
cfe/trunk/include/clang/Basic/LangOptions.def<br>
cfe/trunk/include/clang/Driver/CC1Options.td<br>
cfe/trunk/lib/ARCMigrate/ARCMT.cpp<br>
cfe/trunk/lib/ARCMigrate/Transforms.cpp<br>
cfe/trunk/lib/AST/ASTContext.cpp<br>
cfe/trunk/lib/Basic/Targets.cpp<br>
cfe/trunk/lib/CodeGen/CGBlocks.cpp<br>
cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
cfe/trunk/lib/CodeGen/CGExprCXX.cpp<br>
cfe/trunk/lib/CodeGen/CGObjC.cpp<br>
cfe/trunk/lib/CodeGen/CGObjCMac.cpp<br>
cfe/trunk/lib/Driver/Tools.cpp<br>
cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
cfe/trunk/lib/Frontend/InitPreprocessor.cpp<br>
cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br>
cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp<br>
cfe/trunk/lib/Sema/SemaCast.cpp<br>
cfe/trunk/lib/Sema/SemaCodeComplete.cpp<br>
cfe/trunk/lib/Sema/SemaDecl.cpp<br>
cfe/trunk/lib/Sema/SemaExpr.cpp<br>
cfe/trunk/lib/Sema/SemaObjCProperty.cpp<br>
cfe/trunk/lib/Sema/SemaType.cpp<br>
cfe/trunk/test/ARCMT/GC-no-arc-runtime.m<br>
cfe/trunk/test/CodeGenObjC/blocks.m<br>
cfe/trunk/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m<br>
cfe/trunk/test/Index/complete-property-flags.m<br>
cfe/trunk/test/SemaObjC/attr-objc-gc.m<br>
cfe/trunk/test/SemaObjC/no-gc-weak-test.m<br>
cfe/trunk/test/SemaObjC/property-in-class-extension-1.m<br>
cfe/trunk/test/SemaObjC/synthesized-ivar.m<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Thu Oct 22 13:38:17 2015<br>
@@ -108,6 +108,10 @@ def err_arc_unsupported_on_runtime : Err<br>
"-fobjc-arc is not supported on platforms using the legacy runtime">;<br>
def err_arc_unsupported_on_toolchain : Error< // feel free to generalize this<br>
"-fobjc-arc is not supported on versions of OS X prior to 10.6">;<br>
+def err_objc_weak_with_gc : Error<<br>
+ "-fobjc-weak is not supported in Objective-C garbage collection">;<br>
+def err_objc_weak_unsupported : Error<<br>
+ "-fobjc-weak is not supported on the current deployment target">;<br>
def err_drv_mg_requires_m_or_mm : Error<<br>
"option '-MG' requires '-M' or '-MM'">;<br>
def err_drv_unknown_objc_runtime : Error<<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Oct 22 13:38:17 2015<br>
@@ -907,8 +907,6 @@ def error_bad_property_context : Error<<br>
def error_missing_property_ivar_decl : Error<<br>
"synthesized property %0 must either be named the same as a compatible"<br>
" instance variable or must explicitly name an instance variable">;<br>
-def error_synthesize_weak_non_arc_or_gc : Error<<br>
- "@synthesize of 'weak' property is only allowed in ARC or GC mode">;<br>
def err_arc_perform_selector_retains : Error<<br>
"performSelector names a selector which retains the object">;<br>
def warn_arc_perform_selector_leaks : Warning<<br>
@@ -4527,6 +4525,11 @@ let CategoryName = "ARC Weak References"<br>
<br>
def err_arc_weak_no_runtime : Error<<br>
"the current deployment target does not support automated __weak references">;<br>
+def err_arc_weak_disabled : Error<<br>
+ "automated __weak references are disabled in manual reference counting">;<br>
+def warn_objc_weak_compat : Warning<<br>
+ "the meaning of __weak has changed in manual reference-counting">,<br>
+ InGroup<DiagGroup<"objc-weak-compat">>, DefaultIgnore;<br>
def err_arc_unsupported_weak_class : Error<<br>
"class is incompatible with __weak references">;<br>
def err_arc_weak_unavailable_assign : Error<<br>
<br>
Modified: cfe/trunk/include/clang/Basic/LangOptions.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/LangOptions.def (original)<br>
+++ cfe/trunk/include/clang/Basic/LangOptions.def Thu Oct 22 13:38:17 2015<br>
@@ -193,7 +193,8 @@ LANGOPT(DefaultFPContract , 1, 0, "FP_CO<br>
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")<br>
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")<br>
LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")<br>
-LANGOPT(ObjCARCWeak , 1, 0, "__weak support in the ARC runtime")<br>
+LANGOPT(ObjCWeakRuntime , 1, 0, "__weak support in the ARC runtime")<br>
+LANGOPT(ObjCWeak , 1, 0, "Objective-C __weak in ARC and MRC files")<br>
LANGOPT(ObjCSubscriptingLegacyRuntime , 1, 0, "Subscripting support in legacy ObjectiveC runtime")<br>
LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map")<br>
ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode")<br>
<br>
Modified: cfe/trunk/include/clang/Driver/CC1Options.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)<br>
+++ cfe/trunk/include/clang/Driver/CC1Options.td Thu Oct 22 13:38:17 2015<br>
@@ -511,6 +511,8 @@ def fobjc_runtime_has_weak : Flag<["-"],<br>
HelpText<"The target Objective-C runtime supports ARC weak operations">;<br>
def fobjc_dispatch_method_EQ : Joined<["-"], "fobjc-dispatch-method=">,<br>
HelpText<"Objective-C dispatch method to use">;<br>
+def fobjc_weak : Flag<["-"], "fobjc-weak">, Group<f_Group>,<br>
+ HelpText<"Enable ARC-style __weak references">;<br>
def disable_objc_default_synthesize_properties : Flag<["-"], "disable-objc-default-synthesize-properties">,<br>
HelpText<"disable the default synthesis of Objective-C properties">;<br>
def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signature">,<br>
<br>
Modified: cfe/trunk/lib/ARCMigrate/ARCMT.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ARCMT.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ARCMT.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/ARCMigrate/ARCMT.cpp (original)<br>
+++ cfe/trunk/lib/ARCMigrate/ARCMT.cpp Thu Oct 22 13:38:17 2015<br>
@@ -206,7 +206,8 @@ createInvocationForMigration(CompilerInv<br>
WarnOpts.push_back("error=arc-unsafe-retained-assign");<br>
CInvok->getDiagnosticOpts().Warnings = std::move(WarnOpts);<br>
<br>
- CInvok->getLangOpts()->ObjCARCWeak = HasARCRuntime(origCI);<br>
+ CInvok->getLangOpts()->ObjCWeakRuntime = HasARCRuntime(origCI);<br>
+ CInvok->getLangOpts()->ObjCWeak = CInvok->getLangOpts()->ObjCWeakRuntime;<br>
<br>
return CInvok.release();<br>
}<br>
<br>
Modified: cfe/trunk/lib/ARCMigrate/Transforms.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/ARCMigrate/Transforms.cpp (original)<br>
+++ cfe/trunk/lib/ARCMigrate/Transforms.cpp Thu Oct 22 13:38:17 2015<br>
@@ -42,7 +42,7 @@ bool MigrationPass::CFBridgingFunctionsD<br>
<br>
bool trans::canApplyWeak(ASTContext &Ctx, QualType type,<br>
bool AllowOnUnknownClass) {<br>
- if (!Ctx.getLangOpts().ObjCARCWeak)<br>
+ if (!Ctx.getLangOpts().ObjCWeakRuntime)<br>
return false;<br>
<br>
QualType T = type;<br>
<br>
Modified: cfe/trunk/lib/AST/ASTContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ASTContext.cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Oct 22 13:38:17 2015<br>
@@ -4946,8 +4946,6 @@ bool ASTContext::BlockRequiresCopying(Qu<br>
<br>
// If we have lifetime, that dominates.<br>
if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) {<br>
- assert(getLangOpts().ObjCAutoRefCount);<br>
-<br>
switch (lifetime) {<br>
case Qualifiers::OCL_None: llvm_unreachable("impossible");<br>
<br>
@@ -4981,14 +4979,14 @@ bool ASTContext::getByrefLifetime(QualTy<br>
if (Ty->isRecordType()) {<br>
HasByrefExtendedLayout = true;<br>
LifeTime = Qualifiers::OCL_None;<br>
- }<br>
- else if (getLangOpts().ObjCAutoRefCount)<br>
- LifeTime = Ty.getObjCLifetime();<br>
- // MRR.<br>
- else if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType())<br>
+ } else if ((LifeTime = Ty.getObjCLifetime())) {<br>
+ // Honor the ARC qualifiers.<br>
+ } else if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType()) {<br>
+ // The MRR rule.<br>
LifeTime = Qualifiers::OCL_ExplicitNone;<br>
- else<br>
+ } else {<br>
LifeTime = Qualifiers::OCL_None;<br>
+ }<br>
return true;<br>
}<br>
<br>
<br>
Modified: cfe/trunk/lib/Basic/Targets.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Basic/Targets.cpp (original)<br>
+++ cfe/trunk/lib/Basic/Targets.cpp Thu Oct 22 13:38:17 2015<br>
@@ -118,19 +118,11 @@ static void getDarwinDefines(MacroBuilde<br>
if (Opts.Sanitize.has(SanitizerKind::Address))<br>
Builder.defineMacro("_FORTIFY_SOURCE", "0");<br>
<br>
- if (!Opts.ObjCAutoRefCount) {<br>
+ // Darwin defines __weak, __strong, and __unsafe_unretained even in C mode.<br>
+ if (!Opts.ObjC1) {<br>
// __weak is always defined, for use in blocks and with objc pointers.<br>
Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");<br>
-<br>
- // Darwin defines __strong even in C mode (just to nothing).<br>
- if (Opts.getGC() != LangOptions::NonGC)<br>
- Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");<br>
- else<br>
- Builder.defineMacro("__strong", "");<br>
-<br>
- // __unsafe_unretained is defined to nothing in non-ARC mode. We even<br>
- // allow this in C, since one might have block pointers in structs that<br>
- // are used in pure C code and in Objective-C ARC.<br>
+ Builder.defineMacro("__strong", "");<br>
Builder.defineMacro("__unsafe_unretained", "");<br>
}<br>
<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Thu Oct 22 13:38:17 2015<br>
@@ -1393,31 +1393,31 @@ CodeGenFunction::GenerateCopyHelperFunct<br>
flags = BLOCK_FIELD_IS_BLOCK;<br>
<br>
// Special rules for ARC captures:<br>
- if (getLangOpts().ObjCAutoRefCount) {<br>
- Qualifiers qs = type.getQualifiers();<br>
+ Qualifiers qs = type.getQualifiers();<br>
<br>
- // We need to register __weak direct captures with the runtime.<br>
- if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) {<br>
- useARCWeakCopy = true;<br>
-<br>
- // We need to retain the copied value for __strong direct captures.<br>
- } else if (qs.getObjCLifetime() == Qualifiers::OCL_Strong) {<br>
- // If it's a block pointer, we have to copy the block and<br>
- // assign that to the destination pointer, so we might as<br>
- // well use _Block_object_assign. Otherwise we can avoid that.<br>
- if (!isBlockPointer)<br>
- useARCStrongCopy = true;<br>
-<br>
- // Otherwise the memcpy is fine.<br>
- } else {<br>
- continue;<br>
- }<br>
+ // We need to register __weak direct captures with the runtime.<br>
+ if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) {<br>
+ useARCWeakCopy = true;<br>
+<br>
+ // We need to retain the copied value for __strong direct captures.<br>
+ } else if (qs.getObjCLifetime() == Qualifiers::OCL_Strong) {<br>
+ // If it's a block pointer, we have to copy the block and<br>
+ // assign that to the destination pointer, so we might as<br>
+ // well use _Block_object_assign. Otherwise we can avoid that.<br>
+ if (!isBlockPointer)<br>
+ useARCStrongCopy = true;<br>
<br>
// Non-ARC captures of retainable pointers are strong and<br>
// therefore require a call to _Block_object_assign.<br>
- } else {<br>
+ } else if (!qs.getObjCLifetime() && !getLangOpts().ObjCAutoRefCount) {<br>
// fall through<br>
+<br>
+ // Otherwise the memcpy is fine.<br>
+ } else {<br>
+ continue;<br>
}<br>
+<br>
+ // For all other types, the memcpy is fine.<br>
} else {<br>
continue;<br>
}<br>
@@ -1564,21 +1564,24 @@ CodeGenFunction::GenerateDestroyHelperFu<br>
flags = BLOCK_FIELD_IS_BLOCK;<br>
<br>
// Special rules for ARC captures.<br>
- if (getLangOpts().ObjCAutoRefCount) {<br>
- Qualifiers qs = type.getQualifiers();<br>
+ Qualifiers qs = type.getQualifiers();<br>
+<br>
+ // Use objc_storeStrong for __strong direct captures; the<br>
+ // dynamic tools really like it when we do this.<br>
+ if (qs.getObjCLifetime() == Qualifiers::OCL_Strong) {<br>
+ useARCStrongDestroy = true;<br>
+<br>
+ // Support __weak direct captures.<br>
+ } else if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) {<br>
+ useARCWeakDestroy = true;<br>
+<br>
+ // Non-ARC captures are strong, and we need to use _Block_object_dispose.<br>
+ } else if (!qs.hasObjCLifetime() && !getLangOpts().ObjCAutoRefCount) {<br>
+ // fall through<br>
<br>
- // Don't generate special dispose logic for a captured object<br>
- // unless it's __strong or __weak.<br>
- if (!qs.hasStrongOrWeakObjCLifetime())<br>
- continue;<br>
-<br>
- // Support __weak direct captures.<br>
- if (qs.getObjCLifetime() == Qualifiers::OCL_Weak)<br>
- useARCWeakDestroy = true;<br>
-<br>
- // Tools really want us to use objc_storeStrong here.<br>
- else<br>
- useARCStrongDestroy = true;<br>
+ // Otherwise, we have nothing to do.<br>
+ } else {<br>
+ continue;<br>
}<br>
} else {<br>
continue;<br>
@@ -1958,8 +1961,6 @@ CodeGenFunction::buildByrefHelpers(llvm:<br>
<br>
// If we have lifetime, that dominates.<br>
if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) {<br>
- assert(getLangOpts().ObjCAutoRefCount);<br>
-<br>
switch (lifetime) {<br>
case Qualifiers::OCL_None: llvm_unreachable("impossible");<br>
<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Oct 22 13:38:17 2015<br>
@@ -202,11 +202,8 @@ pushTemporaryCleanup(CodeGenFunction &CG<br>
// need to perform retain/release operations on the temporary.<br>
//<br>
// FIXME: This should be looking at E, not M.<br>
- if (CGF.getLangOpts().ObjCAutoRefCount &&<br>
- M->getType()->isObjCLifetimeType()) {<br>
- QualType ObjCARCReferenceLifetimeType = M->getType();<br>
- switch (Qualifiers::ObjCLifetime Lifetime =<br>
- ObjCARCReferenceLifetimeType.getObjCLifetime()) {<br>
+ if (auto Lifetime = M->getType().getObjCLifetime()) {<br>
+ switch (Lifetime) {<br>
case Qualifiers::OCL_None:<br>
case Qualifiers::OCL_ExplicitNone:<br>
// Carry on to normal cleanup handling.<br>
@@ -247,11 +244,11 @@ pushTemporaryCleanup(CodeGenFunction &CG<br>
}<br>
if (Duration == SD_FullExpression)<br>
CGF.pushDestroy(CleanupKind, ReferenceTemporary,<br>
- ObjCARCReferenceLifetimeType, *Destroy,<br>
+ M->getType(), *Destroy,<br>
CleanupKind & EHCleanup);<br>
else<br>
CGF.pushLifetimeExtendedDestroy(CleanupKind, ReferenceTemporary,<br>
- ObjCARCReferenceLifetimeType,<br>
+ M->getType(),<br>
*Destroy, CleanupKind & EHCleanup);<br>
return;<br>
<br>
@@ -355,10 +352,9 @@ EmitMaterializeTemporaryExpr(const Mater<br>
<br>
// FIXME: ideally this would use EmitAnyExprToMem, however, we cannot do so<br>
// as that will cause the lifetime adjustment to be lost for ARC<br>
- if (getLangOpts().ObjCAutoRefCount &&<br>
- M->getType()->isObjCLifetimeType() &&<br>
- M->getType().getObjCLifetime() != Qualifiers::OCL_None &&<br>
- M->getType().getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {<br>
+ auto ownership = M->getType().getObjCLifetime();<br>
+ if (ownership != Qualifiers::OCL_None &&<br>
+ ownership != Qualifiers::OCL_ExplicitNone) {<br>
Address Object = createReferenceTemporary(*this, M, E);<br>
if (auto *Var = dyn_cast<llvm::GlobalVariable>(Object.getPointer())) {<br>
Object = Address(llvm::ConstantExpr::getBitCast(Var,<br>
@@ -1424,6 +1420,12 @@ RValue CodeGenFunction::EmitLoadOfLValue<br>
AddrWeakObj));<br>
}<br>
if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) {<br>
+ // In MRC mode, we do a load+autorelease.<br>
+ if (!getLangOpts().ObjCAutoRefCount) {<br>
+ return RValue::get(EmitARCLoadWeak(LV.getAddress()));<br>
+ }<br>
+<br>
+ // In ARC mode, we load retained and then consume the value.<br>
llvm::Value *Object = EmitARCLoadWeakRetained(LV.getAddress());<br>
Object = EmitObjCConsumeObject(LV.getType(), Object);<br>
return RValue::get(Object);<br>
@@ -3511,10 +3513,7 @@ RValue CodeGenFunction::EmitCallExpr(con<br>
if (const auto *PseudoDtor =<br>
dyn_cast<CXXPseudoDestructorExpr>(E->getCallee()->IgnoreParens())) {<br>
QualType DestroyedType = PseudoDtor->getDestroyedType();<br>
- if (getLangOpts().ObjCAutoRefCount &&<br>
- DestroyedType->isObjCLifetimeType() &&<br>
- (DestroyedType.getObjCLifetime() == Qualifiers::OCL_Strong ||<br>
- DestroyedType.getObjCLifetime() == Qualifiers::OCL_Weak)) {<br>
+ if (DestroyedType.hasStrongOrWeakObjCLifetime()) {<br>
// Automatic Reference Counting:<br>
// If the pseudo-expression names a retainable object with weak or<br>
// strong lifetime, the object shall be released.<br>
@@ -3534,7 +3533,7 @@ RValue CodeGenFunction::EmitCallExpr(con<br>
BaseQuals = BaseTy.getQualifiers();<br>
}<br>
<br>
- switch (PseudoDtor->getDestroyedType().getObjCLifetime()) {<br>
+ switch (DestroyedType.getObjCLifetime()) {<br>
case Qualifiers::OCL_None:<br>
case Qualifiers::OCL_ExplicitNone:<br>
case Qualifiers::OCL_Autoreleasing:<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Oct 22 13:38:17 2015<br>
@@ -1526,9 +1526,8 @@ static void EmitObjectDelete(CodeGenFunc<br>
/*ForVirtualBase=*/false,<br>
/*Delegating=*/false,<br>
Ptr);<br>
- else if (CGF.getLangOpts().ObjCAutoRefCount &&<br>
- ElementType->isObjCLifetimeType()) {<br>
- switch (ElementType.getObjCLifetime()) {<br>
+ else if (auto Lifetime = ElementType.getObjCLifetime()) {<br>
+ switch (Lifetime) {<br>
case Qualifiers::OCL_None:<br>
case Qualifiers::OCL_ExplicitNone:<br>
case Qualifiers::OCL_Autoreleasing:<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Thu Oct 22 13:38:17 2015<br>
@@ -323,6 +323,21 @@ shouldExtendReceiverForInnerPointerMessa<br>
llvm_unreachable("invalid receiver kind");<br>
}<br>
<br>
+/// Given an expression of ObjC pointer type, check whether it was<br>
+/// immediately loaded from an ARC __weak l-value.<br>
+static const Expr *findWeakLValue(const Expr *E) {<br>
+ assert(E->getType()->isObjCRetainableType());<br>
+ E = E->IgnoreParens();<br>
+ if (auto CE = dyn_cast<CastExpr>(E)) {<br>
+ if (CE->getCastKind() == CK_LValueToRValue) {<br>
+ if (CE->getSubExpr()->getType().getObjCLifetime() == Qualifiers::OCL_Weak)<br>
+ return CE->getSubExpr();<br>
+ }<br>
+ }<br>
+<br>
+ return nullptr;<br>
+}<br>
+<br>
RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,<br>
ReturnValueSlot Return) {<br>
// Only the lookup mechanism and first two arguments of the method<br>
@@ -333,6 +348,17 @@ RValue CodeGenFunction::EmitObjCMessageE<br>
<br>
const ObjCMethodDecl *method = E->getMethodDecl();<br>
<br>
+ // If the method is -retain, and the receiver's being loaded from<br>
+ // a __weak variable, peephole the entire operation to objc_loadWeakRetained.<br>
+ if (method && E->getReceiverKind() == ObjCMessageExpr::Instance &&<br>
+ method->getMethodFamily() == OMF_retain) {<br>
+ if (auto lvalueExpr = findWeakLValue(E->getInstanceReceiver())) {<br>
+ LValue lvalue = EmitLValue(lvalueExpr);<br>
+ llvm::Value *result = EmitARCLoadWeakRetained(lvalue.getAddress());<br>
+ return AdjustObjCObjectType(*this, E->getType(), RValue::get(result));<br>
+ }<br>
+ }<br>
+<br>
// We don't retain the receiver in delegate init calls, and this is<br>
// safe because the receiver value is always loaded from 'self',<br>
// which we zero out. We don't want to Block_copy block receivers,<br>
@@ -976,7 +1002,11 @@ CodeGenFunction::generateObjCGetterBody(<br>
} else {<br>
// We want to load and autoreleaseReturnValue ARC __weak ivars.<br>
if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) {<br>
- value = emitARCRetainLoadOfScalar(*this, LV, ivarType);<br>
+ if (getLangOpts().ObjCAutoRefCount) {<br>
+ value = emitARCRetainLoadOfScalar(*this, LV, ivarType);<br>
+ } else {<br>
+ value = EmitARCLoadWeak(LV.getAddress());<br>
+ }<br>
<br>
// Otherwise we want to do a simple load, suppressing the<br>
// final autorelease.<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Thu Oct 22 13:38:17 2015<br>
@@ -913,10 +913,28 @@ protected:<br>
/// BuildIvarLayout - Builds ivar layout bitmap for the class<br>
/// implementation for the __strong or __weak case.<br>
///<br>
+ /// \param hasMRCWeakIvars - Whether we are compiling in MRC and there<br>
+ /// are any weak ivars defined directly in the class. Meaningless unless<br>
+ /// building a weak layout. Does not guarantee that the layout will<br>
+ /// actually have any entries, because the ivar might be under-aligned.<br>
llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,<br>
CharUnits beginOffset,<br>
CharUnits endOffset,<br>
- bool ForStrongLayout);<br>
+ bool forStrongLayout,<br>
+ bool hasMRCWeakIvars);<br>
+<br>
+ llvm::Constant *BuildStrongIvarLayout(const ObjCImplementationDecl *OI,<br>
+ CharUnits beginOffset,<br>
+ CharUnits endOffset) {<br>
+ return BuildIvarLayout(OI, beginOffset, endOffset, true, false);<br>
+ }<br>
+<br>
+ llvm::Constant *BuildWeakIvarLayout(const ObjCImplementationDecl *OI,<br>
+ CharUnits beginOffset,<br>
+ CharUnits endOffset,<br>
+ bool hasMRCWeakIvars) {<br>
+ return BuildIvarLayout(OI, beginOffset, endOffset, false, hasMRCWeakIvars);<br>
+ }<br>
<br>
Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT, bool ByrefLayout);<br>
<br>
@@ -1060,7 +1078,8 @@ private:<br>
/// to store the weak ivar layout and properties. The return value<br>
/// has type ClassExtensionPtrTy.<br>
llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID,<br>
- CharUnits InstanceSize);<br>
+ CharUnits instanceSize,<br>
+ bool hasMRCWeakIvars);<br>
<br>
/// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,<br>
/// for the given class.<br>
@@ -2049,8 +2068,7 @@ llvm::Constant *CGObjCCommonMac::BuildGC<br>
const CGBlockInfo &blockInfo) {<br>
<br>
llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);<br>
- if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&<br>
- !CGM.getLangOpts().ObjCAutoRefCount)<br>
+ if (CGM.getLangOpts().getGC() == LangOptions::NonGC)<br>
return nullPtr;<br>
<br>
IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.BlockSize,<br>
@@ -2129,10 +2147,15 @@ void IvarLayoutBuilder::visitBlock(const<br>
/// the type of the variable captured in the block.<br>
Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,<br>
bool ByrefLayout) {<br>
+ // If it has an ownership qualifier, we're done.<br>
+ if (auto lifetime = FQT.getObjCLifetime())<br>
+ return lifetime;<br>
+<br>
+ // If it doesn't, and this is ARC, it has no ownership.<br>
if (CGM.getLangOpts().ObjCAutoRefCount)<br>
- return FQT.getObjCLifetime();<br>
+ return Qualifiers::OCL_None;<br>
<br>
- // MRR.<br>
+ // In MRC, retainable pointers are owned by non-__block variables.<br>
if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())<br>
return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;<br>
<br>
@@ -3060,11 +3083,24 @@ void CGObjCMac::GenerateCategory(const O<br>
}<br>
<br>
enum FragileClassFlags {<br>
+ /// Apparently: is not a meta-class.<br>
FragileABI_Class_Factory = 0x00001,<br>
+<br>
+ /// Is a meta-class.<br>
FragileABI_Class_Meta = 0x00002,<br>
+<br>
+ /// Has a non-trivial constructor or destructor.<br>
FragileABI_Class_HasCXXStructors = 0x02000,<br>
+<br>
+ /// Has hidden visibility.<br>
FragileABI_Class_Hidden = 0x20000,<br>
- FragileABI_Class_CompiledByARC = 0x04000000<br>
+<br>
+ /// Class implementation was compiled under ARC.<br>
+ FragileABI_Class_CompiledByARC = 0x04000000,<br>
+<br>
+ /// Class implementation was compiled under MRC and has MRC weak ivars.<br>
+ /// Exclusive with CompiledByARC.<br>
+ FragileABI_Class_HasMRCWeakIvars = 0x08000000,<br>
};<br>
<br>
enum NonFragileClassFlags {<br>
@@ -3074,7 +3110,7 @@ enum NonFragileClassFlags {<br>
/// Is a root class.<br>
NonFragileABI_Class_Root = 0x00002,<br>
<br>
- /// Has a C++ constructor and destructor.<br>
+ /// Has a non-trivial constructor or destructor.<br>
NonFragileABI_Class_HasCXXStructors = 0x00004,<br>
<br>
/// Has hidden visibility.<br>
@@ -3090,9 +3126,46 @@ enum NonFragileClassFlags {<br>
NonFragileABI_Class_CompiledByARC = 0x00080,<br>
<br>
/// Class has non-trivial destructors, but zero-initialization is okay.<br>
- NonFragileABI_Class_HasCXXDestructorOnly = 0x00100<br>
+ NonFragileABI_Class_HasCXXDestructorOnly = 0x00100,<br>
+<br>
+ /// Class implementation was compiled under MRC and has MRC weak ivars.<br>
+ /// Exclusive with CompiledByARC.<br>
+ NonFragileABI_Class_HasMRCWeakIvars = 0x00200,<br>
};<br>
<br>
+static bool hasWeakMember(QualType type) {<br>
+ if (type.getObjCLifetime() == Qualifiers::OCL_Weak) {<br>
+ return true;<br>
+ }<br>
+<br>
+ if (auto recType = type->getAs<RecordType>()) {<br>
+ for (auto field : recType->getDecl()->fields()) {<br>
+ if (hasWeakMember(field->getType()))<br>
+ return true;<br>
+ }<br>
+ }<br>
+<br>
+ return false;<br>
+}<br>
+<br>
+/// For compatibility, we only want to set the "HasMRCWeakIvars" flag<br>
+/// (and actually fill in a layout string) if we really do have any<br>
+/// __weak ivars.<br>
+static bool hasMRCWeakIvars(CodeGenModule &CGM,<br>
+ const ObjCImplementationDecl *ID) {<br>
+ if (!CGM.getLangOpts().ObjCWeak) return false;<br>
+ assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);<br>
+<br>
+ for (const ObjCIvarDecl *ivar =<br>
+ ID->getClassInterface()->all_declared_ivar_begin();<br>
+ ivar; ivar = ivar->getNextIvar()) {<br>
+ if (hasWeakMember(ivar->getType()))<br>
+ return true;<br>
+ }<br>
+<br>
+ return false;<br>
+}<br>
+<br>
/*<br>
struct _objc_class {<br>
Class isa;<br>
@@ -3127,8 +3200,12 @@ void CGObjCMac::GenerateClass(const ObjC<br>
if (ID->hasNonZeroConstructors() || ID->hasDestructors())<br>
Flags |= FragileABI_Class_HasCXXStructors;<br>
<br>
+ bool hasMRCWeak = false;<br>
+<br>
if (CGM.getLangOpts().ObjCAutoRefCount)<br>
Flags |= FragileABI_Class_CompiledByARC;<br>
+ else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))<br>
+ Flags |= FragileABI_Class_HasMRCWeakIvars;<br>
<br>
CharUnits Size =<br>
CGM.getContext().getASTObjCImplementationLayout(ID).getSize();<br>
@@ -3183,8 +3260,8 @@ void CGObjCMac::GenerateClass(const ObjC<br>
// cache is always NULL.<br>
Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);<br>
Values[ 9] = Protocols;<br>
- Values[10] = BuildIvarLayout(ID, CharUnits::Zero(), Size, true);<br>
- Values[11] = EmitClassExtension(ID, Size);<br>
+ Values[10] = BuildStrongIvarLayout(ID, CharUnits::Zero(), Size);<br>
+ Values[11] = EmitClassExtension(ID, Size, hasMRCWeak);<br>
llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,<br>
Values);<br>
std::string Name("OBJC_CLASS_");<br>
@@ -3323,13 +3400,14 @@ llvm::Value *CGObjCMac::EmitSuperClassRe<br>
*/<br>
llvm::Constant *<br>
CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID,<br>
- CharUnits InstanceSize) {<br>
+ CharUnits InstanceSize, bool hasMRCWeakIvars) {<br>
uint64_t Size =<br>
CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);<br>
<br>
llvm::Constant *Values[3];<br>
Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);<br>
- Values[1] = BuildIvarLayout(ID, CharUnits::Zero(), InstanceSize, false);<br>
+ Values[1] = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize,<br>
+ hasMRCWeakIvars);<br>
Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),<br>
ID, ID->getClassInterface(), ObjCTypes);<br>
<br>
@@ -4827,10 +4905,13 @@ llvm::Constant *IvarLayoutBuilder::build<br>
llvm::Constant *<br>
CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,<br>
CharUnits beginOffset, CharUnits endOffset,<br>
- bool ForStrongLayout) {<br>
+ bool ForStrongLayout, bool HasMRCWeakIvars) {<br>
+ // If this is MRC, and we're either building a strong layout or there<br>
+ // are no weak ivars, bail out early.<br>
llvm::Type *PtrTy = CGM.Int8PtrTy;<br>
if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&<br>
- !CGM.getLangOpts().ObjCAutoRefCount)<br>
+ !CGM.getLangOpts().ObjCAutoRefCount &&<br>
+ (ForStrongLayout || !HasMRCWeakIvars))<br>
return llvm::Constant::getNullValue(PtrTy);<br>
<br>
const ObjCInterfaceDecl *OI = OMD->getClassInterface();<br>
@@ -4844,8 +4925,10 @@ CGObjCCommonMac::BuildIvarLayout(const O<br>
// runtimes, that means starting at InstanceStart. In fragile runtimes,<br>
// there's no InstanceStart, so it means starting at the end of the<br>
// superclass, rounded up to word alignment.<br>
+ //<br>
+ // MRC weak layout strings follow the ARC style.<br>
CharUnits baseOffset;<br>
- if (CGM.getLangOpts().ObjCAutoRefCount) {<br>
+ if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {<br>
for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();<br>
IVD; IVD = IVD->getNextIvar())<br>
ivars.push_back(IVD);<br>
@@ -5662,8 +5745,11 @@ llvm::GlobalVariable * CGObjCNonFragileA<br>
CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);<br>
CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);<br>
<br>
+ bool hasMRCWeak = false;<br>
if (CGM.getLangOpts().ObjCAutoRefCount)<br>
flags |= NonFragileABI_Class_CompiledByARC;<br>
+ else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))<br>
+ flags |= NonFragileABI_Class_HasMRCWeakIvars;<br>
<br>
Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);<br>
Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);<br>
@@ -5671,7 +5757,7 @@ llvm::GlobalVariable * CGObjCNonFragileA<br>
// FIXME. For 64bit targets add 0 here.<br>
Values[ 3] = (flags & NonFragileABI_Class_Meta)<br>
? GetIvarLayoutName(nullptr, ObjCTypes)<br>
- : BuildIvarLayout(ID, beginInstance, endInstance, true);<br>
+ : BuildStrongIvarLayout(ID, beginInstance, endInstance);<br>
Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());<br>
// const struct _method_list_t * const baseMethods;<br>
std::vector<llvm::Constant*> Methods;<br>
@@ -5718,7 +5804,8 @@ llvm::GlobalVariable * CGObjCNonFragileA<br>
Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);<br>
} else {<br>
Values[ 7] = EmitIvarList(ID);<br>
- Values[ 8] = BuildIvarLayout(ID, beginInstance, endInstance, false);<br>
+ Values[ 8] = BuildWeakIvarLayout(ID, beginInstance, endInstance,<br>
+ hasMRCWeak);<br>
Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),<br>
ID, ID->getClassInterface(), ObjCTypes);<br>
}<br>
<br>
Modified: cfe/trunk/lib/Driver/Tools.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Driver/Tools.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Tools.cpp Thu Oct 22 13:38:17 2015<br>
@@ -4765,6 +4765,7 @@ void Clang::ConstructJob(Compilation &C,<br>
options::OPT_fno_objc_arc_exceptions,<br>
/*default*/ types::isCXX(InputType)))<br>
CmdArgs.push_back("-fobjc-arc-exceptions");<br>
+<br>
}<br>
<br>
// -fobjc-infer-related-result-type is the default, except in the Objective-C<br>
<br>
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Thu Oct 22 13:38:17 2015<br>
@@ -1421,12 +1421,28 @@ static void ParseLangArgs(LangOptions &O<br>
Opts.ObjCAutoRefCount = 1;<br>
if (!Opts.ObjCRuntime.allowsARC())<br>
Diags.Report(diag::err_arc_unsupported_on_runtime);<br>
+ }<br>
+<br>
+ // ObjCWeakRuntime tracks whether the runtime supports __weak, not<br>
+ // whether the feature is actually enabled. This is predominantly<br>
+ // determined by -fobjc-runtime, but we allow it to be overridden<br>
+ // from the command line for testing purposes.<br>
+ if (Args.hasArg(OPT_fobjc_runtime_has_weak))<br>
+ Opts.ObjCWeakRuntime = 1;<br>
+ else<br>
+ Opts.ObjCWeakRuntime = Opts.ObjCRuntime.allowsWeak();<br>
<br>
- // Only set ObjCARCWeak if ARC is enabled.<br>
- if (Args.hasArg(OPT_fobjc_runtime_has_weak))<br>
- Opts.ObjCARCWeak = 1;<br>
- else<br>
- Opts.ObjCARCWeak = Opts.ObjCRuntime.allowsWeak();<br>
+ // ObjCWeak determines whether __weak is actually enabled.<br>
+ if (Opts.ObjCAutoRefCount) {<br>
+ Opts.ObjCWeak = Opts.ObjCWeakRuntime;<br>
+ } else if (Args.hasArg(OPT_fobjc_weak)) {<br>
+ if (Opts.getGC() != LangOptions::NonGC) {<br>
+ Diags.Report(diag::err_objc_weak_with_gc);<br>
+ } else if (Opts.ObjCWeakRuntime) {<br>
+ Opts.ObjCWeak = true;<br>
+ } else {<br>
+ Diags.Report(diag::err_objc_weak_unsupported);<br>
+ }<br>
}<br>
<br>
if (Args.hasArg(OPT_fno_objc_infer_related_result_type))<br>
<br>
Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Thu Oct 22 13:38:17 2015<br>
@@ -323,15 +323,17 @@ static void AddObjCXXARCLibstdcxxDefines<br>
<br>
Out << "template<typename _Tp> struct __is_scalar;\n"<br>
<< "\n";<br>
+<br>
+ if (LangOpts.ObjCAutoRefCount) {<br>
+ Out << "template<typename _Tp>\n"<br>
+ << "struct __is_scalar<__attribute__((objc_ownership(strong))) _Tp> {\n"<br>
+ << " enum { __value = 0 };\n"<br>
+ << " typedef __false_type __type;\n"<br>
+ << "};\n"<br>
+ << "\n";<br>
+ }<br>
<br>
- Out << "template<typename _Tp>\n"<br>
- << "struct __is_scalar<__attribute__((objc_ownership(strong))) _Tp> {\n"<br>
- << " enum { __value = 0 };\n"<br>
- << " typedef __false_type __type;\n"<br>
- << "};\n"<br>
- << "\n";<br>
-<br>
- if (LangOpts.ObjCARCWeak) {<br>
+ if (LangOpts.ObjCWeak) {<br>
Out << "template<typename _Tp>\n"<br>
<< "struct __is_scalar<__attribute__((objc_ownership(weak))) _Tp> {\n"<br>
<< " enum { __value = 0 };\n"<br>
@@ -340,13 +342,15 @@ static void AddObjCXXARCLibstdcxxDefines<br>
<< "\n";<br>
}<br>
<br>
- Out << "template<typename _Tp>\n"<br>
- << "struct __is_scalar<__attribute__((objc_ownership(autoreleasing)))"<br>
- << " _Tp> {\n"<br>
- << " enum { __value = 0 };\n"<br>
- << " typedef __false_type __type;\n"<br>
- << "};\n"<br>
- << "\n";<br>
+ if (LangOpts.ObjCAutoRefCount) {<br>
+ Out << "template<typename _Tp>\n"<br>
+ << "struct __is_scalar<__attribute__((objc_ownership(autoreleasing)))"<br>
+ << " _Tp> {\n"<br>
+ << " enum { __value = 0 };\n"<br>
+ << " typedef __false_type __type;\n"<br>
+ << "};\n"<br>
+ << "\n";<br>
+ }<br>
<br>
Out << "}\n";<br>
}<br>
@@ -851,9 +855,6 @@ static void InitializePredefinedMacros(c<br>
else if (LangOpts.getStackProtector() == LangOptions::SSPReq)<br>
Builder.defineMacro("__SSP_ALL__", "3");<br>
<br>
- if (FEOpts.ProgramAction == frontend::RewriteObjC)<br>
- Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");<br>
-<br>
// Define a macro that exists only when using the static analyzer.<br>
if (FEOpts.ProgramAction == frontend::RunAnalysis)<br>
Builder.defineMacro("__clang_analyzer__");<br>
@@ -861,7 +862,11 @@ static void InitializePredefinedMacros(c<br>
if (LangOpts.FastRelaxedMath)<br>
Builder.defineMacro("__FAST_RELAXED_MATH__");<br>
<br>
- if (LangOpts.ObjCAutoRefCount) {<br>
+ if (FEOpts.ProgramAction == frontend::RewriteObjC ||<br>
+ LangOpts.getGC() != LangOptions::NonGC) {<br>
+ Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");<br>
+ Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");<br>
+ } else if (LangOpts.ObjC1) {<br>
Builder.defineMacro("__weak", "__attribute__((objc_ownership(weak)))");<br>
Builder.defineMacro("__strong", "__attribute__((objc_ownership(strong)))");<br>
Builder.defineMacro("__autoreleasing",<br>
@@ -928,10 +933,11 @@ void clang::InitializePreprocessor(<br>
<br>
// Install definitions to make Objective-C++ ARC work well with various<br>
// C++ Standard Library implementations.<br>
- if (LangOpts.ObjC1 && LangOpts.CPlusPlus && LangOpts.ObjCAutoRefCount) {<br>
+ if (LangOpts.ObjC1 && LangOpts.CPlusPlus &&<br>
+ (LangOpts.ObjCAutoRefCount || LangOpts.ObjCWeak)) {<br>
switch (InitOpts.ObjCXXARCStandardLibrary) {<br>
case ARCXX_nolib:<br>
- case ARCXX_libcxx:<br>
+ case ARCXX_libcxx:<br>
break;<br>
<br>
case ARCXX_libstdcxx:<br>
<br>
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)<br>
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Thu Oct 22 13:38:17 2015<br>
@@ -1089,7 +1089,7 @@ static bool HasFeature(const Preprocesso<br>
// Objective-C features<br>
.Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?<br>
.Case("objc_arc", LangOpts.ObjCAutoRefCount)<br>
- .Case("objc_arc_weak", LangOpts.ObjCARCWeak)<br>
+ .Case("objc_arc_weak", LangOpts.ObjCWeak)<br>
.Case("objc_default_synthesize_properties", LangOpts.ObjC2)<br>
.Case("objc_fixed_enum", LangOpts.ObjC2)<br>
.Case("objc_instancetype", LangOpts.ObjC2)<br>
<br>
Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)<br>
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Thu Oct 22 13:38:17 2015<br>
@@ -2050,7 +2050,7 @@ AnalysisBasedWarnings::IssueWarnings(sem<br>
DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);<br>
}<br>
<br>
- if (S.getLangOpts().ObjCARCWeak &&<br>
+ if (S.getLangOpts().ObjCWeak &&<br>
!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, D->getLocStart()))<br>
diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaCast.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaCast.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaCast.cpp Thu Oct 22 13:38:17 2015<br>
@@ -489,9 +489,9 @@ CastsAwayConstness(Sema &Self, QualType<br>
QualType *TheOffendingDestType = nullptr,<br>
Qualifiers *CastAwayQualifiers = nullptr) {<br>
// If the only checking we care about is for Objective-C lifetime qualifiers,<br>
- // and we're not in ARC mode, there's nothing to check.<br>
+ // and we're not in ObjC mode, there's nothing to check.<br>
if (!CheckCVR && CheckObjCLifetime &&<br>
- !Self.Context.getLangOpts().ObjCAutoRefCount)<br>
+ !Self.Context.getLangOpts().ObjC1)<br>
return false;<br>
<br>
// Casting away constness is defined in C++ 5.2.11p8 with reference to<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Oct 22 13:38:17 2015<br>
@@ -4912,7 +4912,7 @@ void Sema::CodeCompleteObjCPropertyFlags<br>
Results.AddResult(CodeCompletionResult("atomic"));<br>
<br>
// Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.<br>
- if (getLangOpts().ObjCARCWeak || getLangOpts().getGC() != LangOptions::NonGC)<br>
+ if (getLangOpts().ObjCWeak || getLangOpts().getGC() != LangOptions::NonGC)<br>
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_weak))<br>
Results.AddResult(CodeCompletionResult("weak"));<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Oct 22 13:38:17 2015<br>
@@ -9815,9 +9815,9 @@ Sema::ActOnCXXForRangeIdentifier(Scope *<br>
void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {<br>
if (var->isInvalidDecl()) return;<br>
<br>
- // In ARC, don't allow jumps past the implicit initialization of a<br>
+ // In Objective-C, don't allow jumps past the implicit initialization of a<br>
// local retaining variable.<br>
- if (getLangOpts().ObjCAutoRefCount &&<br>
+ if (getLangOpts().ObjC1 &&<br>
var->hasLocalStorage()) {<br>
switch (var->getType().getObjCLifetime()) {<br>
case Qualifiers::OCL_None:<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Oct 22 13:38:17 2015<br>
@@ -1702,7 +1702,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, Qua<br>
<br>
MarkDeclRefReferenced(E);<br>
<br>
- if (getLangOpts().ObjCARCWeak && isa<VarDecl>(D) &&<br>
+ if (getLangOpts().ObjCWeak && isa<VarDecl>(D) &&<br>
Ty.getObjCLifetime() == Qualifiers::OCL_Weak &&<br>
!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getLocStart()))<br>
recordUseOfEvaluatedWeak(E);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Thu Oct 22 13:38:17 2015<br>
@@ -663,8 +663,10 @@ static void checkARCPropertyImpl(Sema &S<br>
// We're fine if they match.<br>
if (propertyLifetime == ivarLifetime) return;<br>
<br>
- // These aren't valid lifetimes for object ivars; don't diagnose twice.<br>
- if (ivarLifetime == Qualifiers::OCL_None ||<br>
+ // None isn't a valid lifetime for an object ivar in ARC, and<br>
+ // __autoreleasing is never valid; don't diagnose twice.<br>
+ if ((ivarLifetime == Qualifiers::OCL_None &&<br>
+ S.getLangOpts().ObjCAutoRefCount) ||<br>
ivarLifetime == Qualifiers::OCL_Autoreleasing)<br>
return;<br>
<br>
@@ -953,18 +955,46 @@ Decl *Sema::ActOnPropertyImplDecl(Scope<br>
ObjCPropertyDecl::PropertyAttributeKind kind<br>
= property->getPropertyAttributes();<br>
<br>
- // Add GC __weak to the ivar type if the property is weak.<br>
- if ((kind & ObjCPropertyDecl::OBJC_PR_weak) &&<br>
- getLangOpts().getGC() != LangOptions::NonGC) {<br>
- assert(!getLangOpts().ObjCAutoRefCount);<br>
- if (PropertyIvarType.isObjCGCStrong()) {<br>
- Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);<br>
- Diag(property->getLocation(), diag::note_property_declare);<br>
+ bool isARCWeak = false;<br>
+ if (kind & ObjCPropertyDecl::OBJC_PR_weak) {<br>
+ // Add GC __weak to the ivar type if the property is weak.<br>
+ if (getLangOpts().getGC() != LangOptions::NonGC) {<br>
+ assert(!getLangOpts().ObjCAutoRefCount);<br>
+ if (PropertyIvarType.isObjCGCStrong()) {<br>
+ Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);<br>
+ Diag(property->getLocation(), diag::note_property_declare);<br>
+ } else {<br>
+ PropertyIvarType =<br>
+ Context.getObjCGCQualType(PropertyIvarType, Qualifiers::Weak);<br>
+ }<br>
+<br>
+ // Otherwise, check whether ARC __weak is enabled and works with<br>
+ // the property type.<br>
} else {<br>
- PropertyIvarType =<br>
- Context.getObjCGCQualType(PropertyIvarType, Qualifiers::Weak);<br>
+ if (!getLangOpts().ObjCWeak) {<br>
+ if (getLangOpts().ObjCWeakRuntime) {<br>
+ Diag(PropertyDiagLoc, diag::err_arc_weak_disabled);<br>
+ } else {<br>
+ Diag(PropertyDiagLoc, diag::err_arc_weak_no_runtime);<br>
+ }<br>
+ Diag(property->getLocation(), diag::note_property_declare);<br>
+ } else {<br>
+ isARCWeak = true;<br>
+ if (const ObjCObjectPointerType *ObjT =<br>
+ PropertyIvarType->getAs<ObjCObjectPointerType>()) {<br>
+ const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl();<br>
+ if (ObjI && ObjI->isArcWeakrefUnavailable()) {<br>
+ Diag(property->getLocation(),<br>
+ diag::err_arc_weak_unavailable_property)<br>
+ << PropertyIvarType;<br>
+ Diag(ClassImpDecl->getLocation(), diag::note_implemented_by_class)<br>
+ << ClassImpDecl->getName();<br>
+ }<br>
+ }<br>
+ }<br>
}<br>
}<br>
+<br>
if (AtLoc.isInvalid()) {<br>
// Check when default synthesizing a property that there is<br>
// an ivar matching property name and issue warning; since this<br>
@@ -987,7 +1017,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope<br>
if (!Ivar) {<br>
// In ARC, give the ivar a lifetime qualifier based on the<br>
// property attributes.<br>
- if (getLangOpts().ObjCAutoRefCount &&<br>
+ if ((getLangOpts().ObjCAutoRefCount || isARCWeak) &&<br>
!PropertyIvarType.getObjCLifetime() &&<br>
PropertyIvarType->isObjCRetainableType()) {<br>
<br>
@@ -1002,24 +1032,6 @@ Decl *Sema::ActOnPropertyImplDecl(Scope<br>
Qualifiers::ObjCLifetime lifetime =<br>
getImpliedARCOwnership(kind, PropertyIvarType);<br>
assert(lifetime && "no lifetime for property?");<br>
- if (lifetime == Qualifiers::OCL_Weak) {<br>
- bool err = false;<br>
- if (const ObjCObjectPointerType *ObjT =<br>
- PropertyIvarType->getAs<ObjCObjectPointerType>()) {<br>
- const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl();<br>
- if (ObjI && ObjI->isArcWeakrefUnavailable()) {<br>
- Diag(property->getLocation(),<br>
- diag::err_arc_weak_unavailable_property) << PropertyIvarType;<br>
- Diag(ClassImpDecl->getLocation(), diag::note_implemented_by_class)<br>
- << ClassImpDecl->getName();<br>
- err = true;<br>
- }<br>
- }<br>
- if (!err && !getLangOpts().ObjCARCWeak) {<br>
- Diag(PropertyDiagLoc, diag::err_arc_weak_no_runtime);<br>
- Diag(property->getLocation(), diag::note_property_declare);<br>
- }<br>
- }<br>
<br>
Qualifiers qs;<br>
qs.addObjCLifetime(lifetime);<br>
@@ -1027,13 +1039,6 @@ Decl *Sema::ActOnPropertyImplDecl(Scope<br>
}<br>
}<br>
<br>
- if (kind & ObjCPropertyDecl::OBJC_PR_weak &&<br>
- !getLangOpts().ObjCAutoRefCount &&<br>
- getLangOpts().getGC() == LangOptions::NonGC) {<br>
- Diag(PropertyDiagLoc, diag::error_synthesize_weak_non_arc_or_gc);<br>
- Diag(property->getLocation(), diag::note_property_declare);<br>
- }<br>
-<br>
Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl,<br>
PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,<br>
PropertyIvarType, /*Dinfo=*/nullptr,<br>
@@ -1121,7 +1126,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope<br>
// Fall thru - see previous comment<br>
}<br>
}<br>
- if (getLangOpts().ObjCAutoRefCount)<br>
+ if (getLangOpts().ObjCAutoRefCount || isARCWeak ||<br>
+ Ivar->getType().getObjCLifetime())<br>
checkARCPropertyImpl(*this, PropertyLoc, property, Ivar);<br>
} else if (PropertyIvar)<br>
// @dynamic<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaType.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaType.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Oct 22 13:38:17 2015<br>
@@ -4408,7 +4408,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarat<br>
TypeSourceInfo *ReturnTypeInfo = nullptr;<br>
QualType declSpecTy = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo);<br>
<br>
- if (getLangOpts().ObjCAutoRefCount) {<br>
+ if (getLangOpts().ObjC1) {<br>
Qualifiers::ObjCLifetime ownership = Context.getInnerObjCOwnership(FromTy);<br>
if (ownership != Qualifiers::OCL_None)<br>
transferARCOwnership(state, declSpecTy, ownership);<br>
@@ -5092,11 +5092,6 @@ static bool handleObjCOwnershipTypeAttr(<br>
return true;<br>
}<br>
<br>
- // Consume lifetime attributes without further comment outside of<br>
- // ARC mode.<br>
- if (!S.getLangOpts().ObjCAutoRefCount)<br>
- return true;<br>
-<br>
IdentifierInfo *II = attr.getArgAsIdent(0)->Ident;<br>
Qualifiers::ObjCLifetime lifetime;<br>
if (II->isStr("none"))<br>
@@ -5114,6 +5109,14 @@ static bool handleObjCOwnershipTypeAttr(<br>
return true;<br>
}<br>
<br>
+ // Just ignore lifetime attributes other than __weak and __unsafe_unretained<br>
+ // outside of ARC mode.<br>
+ if (!S.getLangOpts().ObjCAutoRefCount &&<br>
+ lifetime != Qualifiers::OCL_Weak &&<br>
+ lifetime != Qualifiers::OCL_ExplicitNone) {<br>
+ return true;<br>
+ }<br>
+<br>
SplitQualType underlyingType = type.split();<br>
<br>
// Check for redundant/conflicting ownership qualifiers.<br>
@@ -5164,24 +5167,36 @@ static bool handleObjCOwnershipTypeAttr(<br>
type = S.Context.getAttributedType(AttributedType::attr_objc_ownership,<br>
origType, type);<br>
<br>
- // Forbid __weak if the runtime doesn't support it.<br>
+ // Sometimes, __weak isn't allowed.<br>
if (lifetime == Qualifiers::OCL_Weak &&<br>
- !S.getLangOpts().ObjCARCWeak && !NonObjCPointer) {<br>
+ !S.getLangOpts().ObjCWeak && !NonObjCPointer) {<br>
<br>
- // Actually, delay this until we know what we're parsing.<br>
+ // Use a specialized diagnostic if the runtime just doesn't support them.<br>
+ unsigned diagnostic =<br>
+ (S.getLangOpts().ObjCWeakRuntime ? diag::err_arc_weak_disabled<br>
+ : diag::err_arc_weak_no_runtime);<br>
+<br>
+ // In any case, delay the diagnostic until we know what we're parsing.<br>
if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {<br>
S.DelayedDiagnostics.add(<br>
sema::DelayedDiagnostic::makeForbiddenType(<br>
S.getSourceManager().getExpansionLoc(AttrLoc),<br>
- diag::err_arc_weak_no_runtime, type, /*ignored*/ 0));<br>
+ diagnostic, type, /*ignored*/ 0));<br>
} else {<br>
- S.Diag(AttrLoc, diag::err_arc_weak_no_runtime);<br>
+ S.Diag(AttrLoc, diagnostic);<br>
}<br>
<br>
attr.setInvalid();<br>
return true;<br>
}<br>
<br>
+ // If we accepted __weak, we might still need to warn about it.<br>
+ if (lifetime == Qualifiers::OCL_Weak &&<br>
+ !S.getLangOpts().ObjCAutoRefCount &&<br>
+ S.getLangOpts().ObjCWeak) {<br>
+ S.Diag(AttrLoc, diag::warn_objc_weak_compat);<br>
+ }<br>
+<br>
// Forbid __weak for class objects marked as<br>
// objc_arc_weak_reference_unavailable<br>
if (lifetime == Qualifiers::OCL_Weak) {<br>
@@ -5189,9 +5204,9 @@ static bool handleObjCOwnershipTypeAttr(<br>
type->getAs<ObjCObjectPointerType>()) {<br>
if (ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl()) {<br>
if (Class->isArcWeakrefUnavailable()) {<br>
- S.Diag(AttrLoc, diag::err_arc_unsupported_weak_class);<br>
- S.Diag(ObjT->getInterfaceDecl()->getLocation(),<br>
- diag::note_class_declared);<br>
+ S.Diag(AttrLoc, diag::err_arc_unsupported_weak_class);<br>
+ S.Diag(ObjT->getInterfaceDecl()->getLocation(),<br>
+ diag::note_class_declared);<br>
}<br>
}<br>
}<br>
<br>
Modified: cfe/trunk/test/ARCMT/GC-no-arc-runtime.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/GC-no-arc-runtime.m?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/GC-no-arc-runtime.m?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/ARCMT/GC-no-arc-runtime.m (original)<br>
+++ cfe/trunk/test/ARCMT/GC-no-arc-runtime.m Thu Oct 22 13:38:17 2015<br>
@@ -4,6 +4,9 @@<br>
// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t<br>
// RUN: diff %t %s.result<br>
<br>
+// MRC __weak broke this test somehow.<br>
+// XFAIL: *<br>
+<br>
#include "Common.h"<br>
#include "GC.h"<br>
<br>
<br>
Modified: cfe/trunk/test/CodeGenObjC/blocks.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/blocks.m?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/blocks.m?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjC/blocks.m (original)<br>
+++ cfe/trunk/test/CodeGenObjC/blocks.m Thu Oct 22 13:38:17 2015<br>
@@ -84,7 +84,7 @@ void test2(Test2 *x) {<br>
// CHECK: [[T0:%.*]] = bitcast [[WEAK_T]]* [[WEAKX]] to i8*<br>
// CHECK: call void @_Block_object_dispose(i8* [[T0]], i32 8)<br>
<br>
- __weak __block Test2 *weakX = x;<br>
+ __attribute__((objc_gc(weak))) __block Test2 *weakX = x;<br>
test2_helper(^{ [weakX destroy]; });<br>
}<br>
<br>
<br>
Added: cfe/trunk/test/CodeGenObjC/mrc-weak.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/mrc-weak.m?rev=251041&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/mrc-weak.m?rev=251041&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjC/mrc-weak.m (added)<br>
+++ cfe/trunk/test/CodeGenObjC/mrc-weak.m Thu Oct 22 13:38:17 2015<br>
@@ -0,0 +1,142 @@<br>
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-10.10 -emit-llvm -fblocks -fobjc-weak -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-MODERN<br>
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.10 -emit-llvm -fblocks -fobjc-weak -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-FRAGILE<br>
+<br>
+@interface Object<br>
+- (instancetype) retain;<br>
+- (void) run;<br>
+@end<br>
+<br>
+// CHECK-MODERN: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"<br>
+// CHECK-MODERN: @"\01l_OBJC_CLASS_RO_$_Foo" = {{.*}} { i32 772<br>
+// 772 == 0x304<br>
+// ^ HasMRCWeakIvars<br>
+// ^ HasCXXDestructorOnly<br>
+// ^ HasCXXStructors<br>
+<br>
+// CHECK-FRAGILE: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"<br>
+// CHECK-FRAGILE: @OBJC_CLASS_Foo = {{.*}} i32 134225921,<br>
+// 134225921 == 0x08002001<br>
+// ^ HasMRCWeakIvars<br>
+// ^ HasCXXStructors<br>
+// ^ Factory<br>
+@interface Foo : Object {<br>
+ __weak id ivar;<br>
+}<br>
+@end<br>
+<br>
+@implementation Foo<br>
+// CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"<br>
+// CHECK: call void @objc_destroyWeak<br>
+@end<br>
+<br>
+<br>
+void test1(__weak id x) {}<br>
+// CHECK-LABEL: define void @test1<br>
+// CHECK: [[X:%.*]] = alloca i8*,<br>
+// CHECK-NEXT: objc_initWeak<br>
+// CHECK-NEXT: objc_destroyWeak<br>
+// CHECK-NEXT: ret void<br>
+<br>
+void test2(id y) {<br>
+ __weak id z = y;<br>
+}<br>
+// CHECK-LABEL: define void @test2<br>
+// CHECK: [[Y:%.*]] = alloca i8*,<br>
+// CHECK-NEXT: [[Z:%.*]] = alloca i8*,<br>
+// CHECK-NEXT: store<br>
+// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]<br>
+// CHECK-NEXT: call i8* @objc_initWeak(i8** [[Z]], i8* [[T0]])<br>
+// CHECK-NEXT: call void @objc_destroyWeak(i8** [[Z]])<br>
+// CHECK-NEXT: ret void<br>
+<br>
+void test3(id y) {<br>
+ __weak id z;<br>
+ z = y;<br>
+}<br>
+// CHECK-LABEL: define void @test3<br>
+// CHECK: [[Y:%.*]] = alloca i8*,<br>
+// CHECK-NEXT: [[Z:%.*]] = alloca i8*,<br>
+// CHECK-NEXT: store<br>
+// CHECK-NEXT: store i8* null, i8** [[Z]]<br>
+// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]<br>
+// CHECK-NEXT: call i8* @objc_storeWeak(i8** [[Z]], i8* [[T0]])<br>
+// CHECK-NEXT: call void @objc_destroyWeak(i8** [[Z]])<br>
+// CHECK-NEXT: ret void<br>
+<br>
+void test4(__weak id *p) {<br>
+ id y = *p;<br>
+}<br>
+// CHECK-LABEL: define void @test4<br>
+// CHECK: [[P:%.*]] = alloca i8**,<br>
+// CHECK-NEXT: [[Y:%.*]] = alloca i8*,<br>
+// CHECK-NEXT: store<br>
+// CHECK-NEXT: [[T0:%.*]] = load i8**, i8*** [[P]]<br>
+// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[T0]])<br>
+// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]<br>
+// CHECK-NEXT: ret void<br>
+<br>
+void test5(__weak id *p) {<br>
+ id y = [*p retain];<br>
+}<br>
+// CHECK-LABEL: define void @test5<br>
+// CHECK: [[P:%.*]] = alloca i8**,<br>
+// CHECK-NEXT: [[Y:%.*]] = alloca i8*,<br>
+// CHECK-NEXT: store<br>
+// CHECK-NEXT: [[T0:%.*]] = load i8**, i8*** [[P]]<br>
+// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T0]])<br>
+// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]<br>
+// CHECK-NEXT: ret void<br>
+<br>
+void test6(__weak Foo **p) {<br>
+ Foo *y = [*p retain];<br>
+}<br>
+// CHECK-LABEL: define void @test6<br>
+// CHECK: [[P:%.*]] = alloca [[FOO:%.*]]**,<br>
+// CHECK-NEXT: [[Y:%.*]] = alloca [[FOO]]*,<br>
+// CHECK-NEXT: store<br>
+// CHECK-NEXT: [[T0:%.*]] = load [[FOO]]**, [[FOO]]*** [[P]]<br>
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[FOO]]** [[T0]] to i8**<br>
+// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T1]])<br>
+// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[FOO]]*<br>
+// CHECK-NEXT: store [[FOO]]* [[T3]], [[FOO]]** [[Y]]<br>
+// CHECK-NEXT: ret void<br>
+<br>
+extern id get_object(void);<br>
+extern void use_block(void (^)(void));<br>
+<br>
+void test7(void) {<br>
+ __weak Foo *p = get_object();<br>
+ use_block(^{ [p run ]; });<br>
+}<br>
+// CHECK-LABEL: define void @test7<br>
+// CHECK: [[P:%.*]] = alloca [[FOO]]*,<br>
+// CHECK: [[T0:%.*]] = call i8* @get_object()<br>
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[FOO]]*<br>
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[FOO]]** [[P]] to i8**<br>
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[FOO]]* [[T1]] to i8*<br>
+// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]])<br>
+// CHECK: call void @objc_copyWeak<br>
+// CHECK: call void @use_block<br>
+// CHECK: call void @objc_destroyWeak<br>
+<br>
+// CHECK-LABEL: define internal void @__copy_helper_block<br>
+// CHECK: @objc_copyWeak<br>
+<br>
+// CHECK-LABEL: define internal void @__destroy_helper_block<br>
+// CHECK: @objc_destroyWeak<br>
+<br>
+void test8(void) {<br>
+ __block __weak Foo *p = get_object();<br>
+ use_block(^{ [p run ]; });<br>
+}<br>
+// CHECK-LABEL: define void @test8<br>
+// CHECK: call i8* @objc_initWeak<br>
+// CHECK-NOT: call void @objc_copyWeak<br>
+// CHECK: call void @use_block<br>
+// CHECK: call void @objc_destroyWeak<br>
+<br>
+// CHECK-LABEL: define internal void @__Block_byref_object_copy<br>
+// CHECK: call void @objc_moveWeak<br>
+<br>
+// CHECK-LABEL: define internal void @__Block_byref_object_dispose<br>
+// CHECK: call void @objc_destroyWeak<br>
<br>
Modified: cfe/trunk/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m (original)<br>
+++ cfe/trunk/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m Thu Oct 22 13:38:17 2015<br>
@@ -1,6 +1,6 @@<br>
-// RUN: %clang_cc1 -fblocks -fobjc-runtime-has-weak -triple x86_64-apple-darwin -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout<br>
+// RUN: %clang_cc1 -fblocks -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout<br>
// RUN: FileCheck -check-prefix=CHECK -check-prefix=CHECK-64 --input-file=%t-64.layout %s<br>
-// RUN: %clang_cc1 -fblocks -fobjc-runtime-has-weak -triple i386-apple-darwin -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout<br>
+// RUN: %clang_cc1 -fblocks -fobjc-runtime-has-weak -fobjc-arc -triple i386-apple-darwin -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout<br>
// RUN: FileCheck -check-prefix=CHECK -check-prefix=CHECK-32 --input-file=%t-32.layout %s<br>
// rdar://12184410<br>
// rdar://12184410<br>
<br>
Modified: cfe/trunk/test/Index/complete-property-flags.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-property-flags.m?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-property-flags.m?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Index/complete-property-flags.m (original)<br>
+++ cfe/trunk/test/Index/complete-property-flags.m Thu Oct 22 13:38:17 2015<br>
@@ -7,7 +7,8 @@<br>
@property(copy) Foo *myprop;<br>
@property(retain, nonatomic) id xx;<br>
<br>
-// RUN: c-index-test -code-completion-at=%s:7:11 %s -fno-objc-arc | FileCheck -check-prefix=CHECK-CC1 %s<br>
+// RUN: c-index-test -code-completion-at=%s:7:11 %s -fobjc-runtime=macosx-10.4 -fno-objc-arc | FileCheck -check-prefix=CHECK-CC1 -check-prefix=CHECK-CC1-NOWEAK %s<br>
+// RUN: c-index-test -code-completion-at=%s:7:11 %s -fobjc-runtime=macosx-10.8 -Xclang -fobjc-weak -fno-objc-arc | FileCheck -check-prefix=CHECK-CC1 -check-prefix=CHECK-CC1-WEAK %s<br>
// CHECK-CC1: {TypedText assign}<br>
// CHECK-CC1-NEXT: {TypedText atomic}<br>
// CHECK-CC1-NEXT: {TypedText copy}<br>
@@ -23,7 +24,8 @@<br>
// CHECK-CC1-NEXT: {TypedText setter}{Text =}{Placeholder method}<br>
// CHECK-CC1-NEXT: {TypedText strong}<br>
// CHECK-CC1-NEXT: {TypedText unsafe_unretained}<br>
-// CHECK-CC1-NOT: {TypedText weak}<br>
+// CHECK-CC1-NOWEAK-NOT: {TypedText weak}<br>
+// CHECK-CC1-WEAK-NEXT: {TypedText weak}<br>
<br>
// RUN: c-index-test -code-completion-at=%s:7:11 %s -fobjc-arc -fobjc-runtime=macosx-10.7 | FileCheck -check-prefix=CHECK-CC1-ARC %s<br>
// CHECK-CC1-ARC: {TypedText assign}<br>
<br>
Modified: cfe/trunk/test/SemaObjC/attr-objc-gc.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-objc-gc.m?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-objc-gc.m?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjC/attr-objc-gc.m (original)<br>
+++ cfe/trunk/test/SemaObjC/attr-objc-gc.m Thu Oct 22 13:38:17 2015<br>
@@ -9,13 +9,13 @@ static id __attribute((objc_gc(hello)))<br>
<br>
static int __attribute__((objc_gc(weak))) g; // expected-warning {{'objc_gc' only applies to pointer types; type here is 'int'}}<br>
<br>
-static __weak int h; // expected-warning {{'__weak' only applies to pointer types; type here is 'int'}}<br>
+static __weak int h; // expected-warning {{'__weak' only applies to Objective-C object or block pointer types; type here is 'int'}}<br>
<br>
// TODO: it would be great if this reported as __weak<br>
#define WEAK __weak<br>
-static WEAK int h; // expected-warning {{'objc_gc' only applies to pointer types; type here is 'int'}}<br>
+static WEAK int h; // expected-warning {{'objc_ownership' only applies to Objective-C object or block pointer types; type here is 'int'}}<br>
<br>
-/* expected-warning {{'__weak' only applies to pointer types; type here is 'int'}}*/ static __we\<br>
+/* expected-warning {{'__weak' only applies to Objective-C object or block pointer types; type here is 'int'}}*/ static __we\<br>
ak int i;<br>
<br>
// rdar://problem/9126213<br>
<br>
Added: cfe/trunk/test/SemaObjC/mrc-weak.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/mrc-weak.m?rev=251041&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/mrc-weak.m?rev=251041&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjC/mrc-weak.m (added)<br>
+++ cfe/trunk/test/SemaObjC/mrc-weak.m Thu Oct 22 13:38:17 2015<br>
@@ -0,0 +1,67 @@<br>
+// RUN: %clang_cc1 -fobjc-runtime-has-weak -fobjc-weak -fsyntax-only -verify %s<br>
+<br>
+__attribute__((objc_root_class))<br>
+@interface A<br>
+@property (weak) id wa; // expected-note {{property declared here}}<br>
+@property (weak) id wb;<br>
+@property (weak) id wc; // expected-note {{property declared here}}<br>
+@property (weak) id wd;<br>
+@property (unsafe_unretained) id ua;<br>
+@property (unsafe_unretained) id ub; // expected-note {{property declared here}}<br>
+@property (unsafe_unretained) id uc;<br>
+@property (unsafe_unretained) id ud;<br>
+@property (strong) id sa;<br>
+@property (strong) id sb; // expected-note {{property declared here}}<br>
+@property (strong) id sc; // expected-note {{property declared here}}<br>
+@property (strong) id sd;<br>
+@end<br>
+<br>
+@implementation A {<br>
+ id _wa; // expected-error {{existing instance variable '_wa' for __weak property 'wa' must be __weak}}<br>
+ __weak id _wb;<br>
+ __unsafe_unretained id _wc; // expected-error {{existing instance variable '_wc' for __weak property 'wc' must be __weak}}<br>
+ id _ua;<br>
+ __weak id _ub; // expected-error {{existing instance variable '_ub' for property 'ub' with unsafe_unretained attribute must be __unsafe_unretained}}<br>
+ __unsafe_unretained id _uc;<br>
+ id _sa;<br>
+ __weak id _sb; // expected-error {{existing instance variable '_sb' for strong property 'sb' may not be __weak}}<br>
+ __unsafe_unretained id _sc; // expected-error {{existing instance variable '_sc' for strong property 'sc' may not be __unsafe_unretained}}<br>
+}<br>
+@synthesize wa = _wa; // expected-note {{property synthesized here}}<br>
+@synthesize wb = _wb;<br>
+@synthesize wc = _wc; // expected-note {{property synthesized here}}<br>
+@synthesize wd = _wd;<br>
+@synthesize ua = _ua;<br>
+@synthesize ub = _ub; // expected-note {{property synthesized here}}<br>
+@synthesize uc = _uc;<br>
+@synthesize ud = _ud;<br>
+@synthesize sa = _sa;<br>
+@synthesize sb = _sb; // expected-note {{property synthesized here}}<br>
+@synthesize sc = _sc; // expected-note {{property synthesized here}}<br>
+@synthesize sd = _sd;<br>
+@end<br>
+<br>
+void test_goto() {<br>
+ goto after; // expected-error {{cannot jump from this goto statement to its label}}<br>
+ __weak id x; // expected-note {{jump bypasses initialization of __weak variable}}}<br>
+after:<br>
+ return;<br>
+}<br>
+<br>
+void test_weak_cast(id *value) {<br>
+ __weak id *a = (__weak id*) value;<br>
+ id *b = (__weak id*) value; // expected-error {{initializing 'id *' with an expression of type '__weak id *' changes retain/release properties of pointer}}<br>
+ __weak id *c = (id*) value; // expected-error {{initializing '__weak id *' with an expression of type 'id *' changes retain/release properties of pointer}}<br>
+}<br>
+<br>
+void test_unsafe_unretained_cast(id *value) {<br>
+ __unsafe_unretained id *a = (__unsafe_unretained id*) value;<br>
+ id *b = (__unsafe_unretained id*) value;<br>
+ __unsafe_unretained id *c = (id*) value;<br>
+}<br>
+<br>
+void test_cast_qualifier_inference(__weak id *value) {<br>
+ __weak id *a = (id*) value;<br>
+ __unsafe_unretained id *b = (id*) value; // expected-error {{initializing '__unsafe_unretained id *' with an expression of type '__weak id *' changes retain/release properties of pointer}}<br>
+}<br>
+<br>
<br>
Modified: cfe/trunk/test/SemaObjC/no-gc-weak-test.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/no-gc-weak-test.m?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/no-gc-weak-test.m?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjC/no-gc-weak-test.m (original)<br>
+++ cfe/trunk/test/SemaObjC/no-gc-weak-test.m Thu Oct 22 13:38:17 2015<br>
@@ -1,11 +1,10 @@<br>
// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify -Wno-objc-root-class %s<br>
-// expected-no-diagnostics<br>
<br>
@interface Subtask<br>
{<br>
id _delegate;<br>
}<br>
-@property(nonatomic,readwrite,assign) id __weak delegate;<br>
+@property(nonatomic,readwrite,assign) id __weak delegate; // expected-error {{the current deployment target does not support automated __weak references}}<br>
@end<br>
<br>
@implementation Subtask<br>
@@ -15,15 +14,15 @@<br>
<br>
@interface PVSelectionOverlayView2<br>
{<br>
- id __weak _selectionRect;<br>
+ id __weak _selectionRect; // expected-error {{the current deployment target does not support automated __weak references}} expected-error {{existing instance variable '_selectionRect' for property 'selectionRect' with assign attribute must be __unsafe_unretained}}<br>
}<br>
<br>
-@property(assign) id selectionRect;<br>
+@property(assign) id selectionRect; // expected-note {{property declared here}}<br>
<br>
@end<br>
<br>
@implementation PVSelectionOverlayView2<br>
<br>
-@synthesize selectionRect = _selectionRect;<br>
+@synthesize selectionRect = _selectionRect; // expected-note {{property synthesized here}}<br>
@end<br>
<br>
<br>
Removed: cfe/trunk/test/SemaObjC/nonarc-weak.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/nonarc-weak.m?rev=251040&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/nonarc-weak.m?rev=251040&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjC/nonarc-weak.m (original)<br>
+++ cfe/trunk/test/SemaObjC/nonarc-weak.m (removed)<br>
@@ -1,16 +0,0 @@<br>
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.8.0 -fobjc-runtime=macosx-10.8.0 -fsyntax-only -Wunused-function %s > %t.nonarc 2>&1<br>
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.8.0 -fobjc-runtime=macosx-10.8.0 -fsyntax-only -Wunused-function -fobjc-arc %s > %t.arc 2>&1<br>
-// RUN: FileCheck -input-file=%t.nonarc %s<br>
-// RUN: FileCheck -input-file=%t.arc -check-prefix=ARC %s<br>
-<br>
-static void bar() {} // Intentionally unused.<br>
-<br>
-void foo(id self) {<br>
- __weak id weakSelf = self;<br>
-}<br>
-<br>
-// CHECK: 9:13: warning: __weak attribute cannot be specified on an automatic variable when ARC is not enabled<br>
-// CHECK: 6:13: warning: unused function 'bar'<br>
-// CHECK: 2 warnings generated<br>
-// ARC: 6:13: warning: unused function 'bar'<br>
-// ARC: 1 warning generated<br>
<br>
Modified: cfe/trunk/test/SemaObjC/property-in-class-extension-1.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-in-class-extension-1.m?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-in-class-extension-1.m?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjC/property-in-class-extension-1.m (original)<br>
+++ cfe/trunk/test/SemaObjC/property-in-class-extension-1.m Thu Oct 22 13:38:17 2015<br>
@@ -1,5 +1,5 @@<br>
-// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -verify -Weverything %s<br>
-// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -verify -Weverything %s<br>
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-weak -verify -Weverything -Wno-objc-weak-compat %s<br>
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-weak -fsyntax-only -verify -Weverything -Wno-objc-weak-compat %s<br>
// rdar://12103400<br>
<br>
@class NSString;<br>
<br>
Modified: cfe/trunk/test/SemaObjC/synthesized-ivar.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/synthesized-ivar.m?rev=251041&r1=251040&r2=251041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/synthesized-ivar.m?rev=251041&r1=251040&r2=251041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjC/synthesized-ivar.m (original)<br>
+++ cfe/trunk/test/SemaObjC/synthesized-ivar.m Thu Oct 22 13:38:17 2015<br>
@@ -57,5 +57,5 @@ int f0(I *a) { return a->IP; } // expect<br>
<br>
@implementation A<br>
// rdar://9605088<br>
-@synthesize testObjectWeakProperty; // expected-error {{@synthesize of 'weak' property is only allowed in ARC or GC mode}}<br>
+@synthesize testObjectWeakProperty; // expected-error {{the current deployment target does not support automated __weak references}}<br>
@end<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>