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