mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 16:56:35 +00:00

We have a new policy in place making links to private resources something we try to avoid in source and test files. Normally, we'd organically switch to the new policy rather than make a sweeping change across a project. However, Clang is in a somewhat special circumstance currently: recently, I've had several new contributors run into rdar links around test code which their patch was changing the behavior of. This turns out to be a surprisingly bad experience, especially for newer folks, for a handful of reasons: not understanding what the link is and feeling intimidated by it, wondering whether their changes are actually breaking something important to a downstream in some way, having to hunt down strangers not involved with the patch to impose on them for help, accidental pressure from asking for potentially private IP to be made public, etc. Because folks run into these links entirely by chance (through fixing bugs or working on new features), there's not really a set of problematic links to focus on -- all of the links have basically the same potential for causing these problems. As a result, this is an omnibus patch to remove all such links. This was not a mechanical change; it was done by manually searching for rdar, radar, radr, and other variants to find all the various problematic links. From there, I tried to retain or reword the surrounding comments so that we would lose as little context as possible. However, because most links were just a plain link with no supporting context, the majority of the changes are simple removals. Differential Review: https://reviews.llvm.org/D158071
180 lines
7.0 KiB
Objective-C
180 lines
7.0 KiB
Objective-C
// RUN: %clang_cc1 -fsyntax-only -fblocks -fobjc-arc -verify -Wno-objc-root-class -Wno-strict-prototypes %s
|
|
|
|
struct A {
|
|
id x[4];
|
|
id y;
|
|
};
|
|
|
|
union u {
|
|
id u;
|
|
};
|
|
|
|
// Volatile fields are fine.
|
|
struct C {
|
|
volatile int x[4];
|
|
volatile int y;
|
|
};
|
|
|
|
union u_trivial_c {
|
|
volatile int b;
|
|
struct C c;
|
|
};
|
|
|
|
@interface I {
|
|
struct A a;
|
|
struct B {
|
|
id y[10][20];
|
|
id z;
|
|
} b;
|
|
|
|
union u c;
|
|
};
|
|
@end
|
|
|
|
struct r10260525 {
|
|
id (^block1) ();
|
|
id (^block2) (void);
|
|
};
|
|
|
|
struct S {
|
|
id __attribute__((objc_ownership(none))) i;
|
|
void * vp;
|
|
int i1;
|
|
};
|
|
|
|
@class NSError;
|
|
|
|
__autoreleasing id X; // expected-error {{global variables cannot have __autoreleasing ownership}}
|
|
__autoreleasing NSError *E; // expected-error {{global variables cannot have __autoreleasing ownership}}
|
|
|
|
|
|
extern id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}}
|
|
|
|
void func(void)
|
|
{
|
|
id X;
|
|
static id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}}
|
|
extern id __autoreleasing E; // expected-error {{global variables cannot have __autoreleasing ownership}}
|
|
|
|
}
|
|
|
|
@interface J
|
|
@property (retain) id newFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-newFoo' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
|
|
@property (strong) id copyBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-copyBar' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
|
|
@property (copy) id allocBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-allocBaz' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
|
|
@property (copy, nonatomic) id new;
|
|
@property (retain) id newDFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-newDFoo' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
|
|
@property (strong) id copyDBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-copyDBar' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
|
|
@property (copy) id allocDBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-allocDBaz' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
|
|
@end
|
|
|
|
@implementation J
|
|
@synthesize newFoo;
|
|
@synthesize copyBar;
|
|
@synthesize allocBaz;
|
|
@synthesize new;
|
|
- new {return 0; };
|
|
|
|
@dynamic newDFoo;
|
|
@dynamic copyDBar;
|
|
@dynamic allocDBaz;
|
|
@end
|
|
|
|
|
|
@interface MethodFamilyDiags
|
|
@property (retain) id newFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}}
|
|
- (id)newFoo; // expected-note {{explicitly declare getter '-newFoo' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
|
|
|
|
#define OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
|
|
- (id)newBar; // expected-note {{explicitly declare getter '-newBar' with 'OBJC_METHOD_FAMILY_NONE' to return an 'unowned' object}}
|
|
@property (retain) id newBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}}
|
|
|
|
@property (retain) id newBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note {{explicitly declare getter '-newBaz' with 'OBJC_METHOD_FAMILY_NONE' to return an 'unowned' object}}
|
|
#undef OBJC_METHOD_FAMILY_NONE
|
|
|
|
@property (retain, readonly) id newGarply; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note {{explicitly declare getter '-newGarply' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
|
|
@end
|
|
|
|
@interface MethodFamilyDiags (Redeclarations)
|
|
- (id)newGarply; // no note here
|
|
@end
|
|
|
|
@implementation MethodFamilyDiags
|
|
@synthesize newGarply;
|
|
@end
|
|
|
|
|
|
@interface Super
|
|
- (void)bar:(id)b; // expected-note {{parameter declared here}}
|
|
- (void)bar1:(id) __attribute((ns_consumed)) b;
|
|
- (void)ok:(id) __attribute((ns_consumed)) b;
|
|
- (id)ns_non; // expected-note {{method declared here}}
|
|
- (id)not_ret:(id) b __attribute((ns_returns_not_retained)); // expected-note {{method declared here}}
|
|
- (id)both__returns_not_retained:(id) b __attribute((ns_returns_not_retained));
|
|
@end
|
|
|
|
@interface Sub : Super
|
|
- (void)bar:(id) __attribute((ns_consumed)) b; // expected-error {{overriding method has mismatched ns_consumed attribute on its parameter}}
|
|
- (void)bar1:(id)b;
|
|
- (void)ok:(id) __attribute((ns_consumed)) b;
|
|
- (id)ns_non __attribute((ns_returns_not_retained)); // expected-error {{overriding method has mismatched ns_returns_not_retained attributes}}
|
|
- (id)not_ret:(id) b __attribute((ns_returns_retained)); // expected-error {{overriding method has mismatched ns_returns_retained attributes}}
|
|
- (id)both__returns_not_retained:(id) b __attribute((ns_returns_not_retained));
|
|
@property (copy, nonatomic) __attribute__((ns_returns_retained)) id (^fblock)(void);
|
|
@end
|
|
|
|
// Test that we give a good diagnostic here that mentions the missing
|
|
// ownership qualifier. We don't want this to get suppressed because
|
|
// of an invalid conversion.
|
|
void test7(void) {
|
|
id x;
|
|
id *px = &x; // expected-error {{pointer to non-const type 'id' with no explicit ownership}}
|
|
|
|
I *y;
|
|
J **py = &y; // expected-error {{pointer to non-const type 'J *' with no explicit ownership}} expected-warning {{incompatible pointer types initializing}}
|
|
}
|
|
|
|
void func(void) __attribute__((objc_ownership(none))); // expected-warning {{'objc_ownership' only applies to Objective-C object or block pointer types; type here is 'void (void)'}}
|
|
struct __attribute__((objc_ownership(none))) S2 {}; // expected-error {{'objc_ownership' attribute only applies to variables}}
|
|
@interface I2
|
|
@property __attribute__((objc_ownership(frob))) id i; // expected-warning {{'objc_ownership' attribute argument not supported: 'frob'}}
|
|
@end
|
|
|
|
@interface NSObject @end
|
|
|
|
@interface ControllerClass : NSObject @end
|
|
|
|
@interface SomeClassOwnedByController
|
|
@property (readonly) ControllerClass *controller; // expected-note {{property declared here}}
|
|
|
|
@property (readonly, weak) ControllerClass *weak_controller;
|
|
@end
|
|
|
|
@interface SomeClassOwnedByController ()
|
|
@property (readwrite, weak) ControllerClass *controller; // expected-warning {{primary property declaration is implicitly strong while redeclaration in class extension is weak}}
|
|
|
|
@property (readwrite, weak) ControllerClass *weak_controller;
|
|
@end
|
|
|
|
@interface I3
|
|
@end
|
|
|
|
@interface D3 : I3
|
|
@end
|
|
|
|
@interface D3 (Cat1)
|
|
- (id)method;
|
|
@end
|
|
|
|
@interface I3 (Cat2)
|
|
// FIXME: clang should diagnose mismatch between methods in D3(Cat1) and
|
|
// I3(Cat2).
|
|
- (id)method __attribute__((ns_returns_retained));
|
|
@end
|
|
|
|
@implementation D3
|
|
- (id)method {
|
|
return (id)0;
|
|
}
|
|
@end
|