<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>