ADD: code refactoring

This commit is contained in:
shengxuanwei 2022-04-16 23:58:26 +08:00
parent d573d87610
commit 28e71ed6ea
581 changed files with 770331 additions and 2 deletions

31
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,31 @@
---
name: Bug report
about: Report unexpected parsing results
title: ''
labels: 'bug'
assignees: ''
---
The following piece of code is valid but it is parsed incorrectly:
```javascript
```
Here's a link to the TypeScript Playground showing that the snippet above is valid JavaScript or TypeScript:
<!-- Please check your code at https://www.typescriptlang.org/play
and paste the URL below. -->
<!-- Please run `tree-sitter parse YOUR_FILE` and show us the output. -->
The output of `tree-sitter parse` is the following:
```
```
<!-- If there is no `ERROR` or `MISSING` node in the output above,
explain what you were expecting: -->
<!-- Name of the broken/missing feature, link to official
documentation, and any other relevant info is appreciated: -->

View File

@ -0,0 +1,13 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
<!--
The tree-sitter-javascript project is a JavaScript and JSX parser only.
How can we improve it?
-->

8
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,8 @@
Checklist:
- [ ] All tests pass in CI.
- [ ] There are sufficient tests for the new fix/feature.
- [ ] Grammar rules have not been renamed unless absolutely necessary.
- [ ] The conflicts section hasn't grown too much.
- [ ] The parser size hasn't grown too much (check the value of STATE_COUNT in src/parser.c).

20
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: CI
on:
workflow_dispatch:
pull_request:
push:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: [macos-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 14
- run: npm install
- run: npm test

16
.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
# Logs
*.log
npm-debug.log*
# Dependency directories
node_modules/
package-lock.json
# Builds
build/
# Tests
examples/SemaObjC*.txt
# wasm
*.wasm

27
Cargo.toml Normal file
View File

@ -0,0 +1,27 @@
[package]
name = "tree-sitter-objc"
description = "Objective-C grammar for the tree-sitter parsing library"
version = "1.0.0"
authors = ["Jiyee Sheng <jiyee.sheng@gmail.com>"]
license = "MIT"
keywords = ["tree-sitter", "incremental", "parsing", "objc"]
categories = ["parsing", "text-editors"]
repository = "https://github.com/jiyee/tree-sitter-objc"
edition = "2022"
build = "bindings/rust/build.rs"
include = [
"bindings/rust/*",
"grammar.js",
"queries/*",
"src/*",
]
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = "0.20.6"
[build-dependencies]
cc = "1.0"

View File

@ -1,6 +1,6 @@
MIT License
The MIT License (MIT)
Copyright (c) 2022 jiyee
Copyright (c) 2022 Jiyee Sheng
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

10
README.md Normal file
View File

@ -0,0 +1,10 @@
tree-sitter-objc
=======================
[![CI Status](https://github.com/jiyee/tree-sitter-objc/actions/workflows/ci.yml/badge.svg)](https://github.com/jiyee/tree-sitter-objc/actions/workflows/ci.yml)
Objective-C grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter).
## References
* [Objective-C Language Reference](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html) - The full grammar reference for Objective-C.
* [LLVM Objective-C Test Cases](https://github.com/llvm-mirror/clang/tree/master/test/CodeGenObjC) - The full test cases for Objective-C.

4
TODO.md Normal file
View File

@ -0,0 +1,4 @@
# TODO
[ ] precedence order
[ ] highlights.scm
[ ] highlights tests

18
binding.gyp Normal file
View File

@ -0,0 +1,18 @@
{
"targets": [
{
"target_name": "tree_sitter_objc_binding",
"include_dirs": [
"<!(node -e \"require('nan')\")",
"src"
],
"sources": [
"src/parser.c",
"bindings/node/binding.cc"
],
"cflags_c": [
"-std=c99",
]
}
]
}

28
bindings/node/binding.cc Normal file
View File

@ -0,0 +1,28 @@
#include "tree_sitter/parser.h"
#include <node.h>
#include "nan.h"
using namespace v8;
extern "C" TSLanguage * tree_sitter_objc();
namespace {
NAN_METHOD(New) {}
void Init(Local<Object> exports, Local<Object> module) {
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Local<Function> constructor = Nan::GetFunction(tpl).ToLocalChecked();
Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
Nan::SetInternalFieldPointer(instance, 0, tree_sitter_objc());
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("objc").ToLocalChecked());
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
}
NODE_MODULE(tree_sitter_objc_binding, Init)
} // namespace

19
bindings/node/index.js Normal file
View File

@ -0,0 +1,19 @@
try {
module.exports = require("../../build/Release/tree_sitter_objc_binding");
} catch (error1) {
if (error1.code !== 'MODULE_NOT_FOUND') {
throw error1;
}
try {
module.exports = require("../../build/Debug/tree_sitter_objc_binding");
} catch (error2) {
if (error2.code !== 'MODULE_NOT_FOUND') {
throw error2;
}
throw error1
}
}
try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
} catch (_) {}

40
bindings/rust/build.rs Normal file
View File

@ -0,0 +1,40 @@
fn main() {
let src_dir = std::path::Path::new("src");
let mut c_config = cc::Build::new();
c_config.include(&src_dir);
c_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable")
.flag_if_supported("-Wno-trigraphs");
let parser_path = src_dir.join("parser.c");
c_config.file(&parser_path);
// If your language uses an external scanner written in C,
// then include this block of code:
/*
let scanner_path = src_dir.join("scanner.c");
c_config.file(&scanner_path);
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
*/
c_config.compile("parser");
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
// If your language uses an external scanner written in C++,
// then include this block of code:
/*
let mut cpp_config = cc::Build::new();
cpp_config.cpp(true);
cpp_config.include(&src_dir);
cpp_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable");
let scanner_path = src_dir.join("scanner.cc");
cpp_config.file(&scanner_path);
cpp_config.compile("scanner");
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
*/
}

52
bindings/rust/lib.rs Normal file
View File

@ -0,0 +1,52 @@
//! This crate provides objc language support for the [tree-sitter][] parsing library.
//!
//! Typically, you will use the [language][language func] function to add this language to a
//! tree-sitter [Parser][], and then use the parser to parse some code:
//!
//! ```
//! let code = "";
//! let mut parser = tree_sitter::Parser::new();
//! parser.set_language(tree_sitter_objc::language()).expect("Error loading objc grammar");
//! let tree = parser.parse(code, None).unwrap();
//! ```
//!
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
//! [language func]: fn.language.html
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
//! [tree-sitter]: https://tree-sitter.github.io/
use tree_sitter::Language;
extern "C" {
fn tree_sitter_objc() -> Language;
}
/// Get the tree-sitter [Language][] for this grammar.
///
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
pub fn language() -> Language {
unsafe { tree_sitter_objc() }
}
/// The content of the [`node-types.json`][] file for this grammar.
///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json");
// Uncomment these to include any queries that this grammar contains
// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm");
// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
#[cfg(test)]
mod tests {
#[test]
fn test_can_load_grammar() {
let mut parser = tree_sitter::Parser::new();
parser
.set_language(super::language())
.expect("Error loading objc language");
}
}

12
examples/SemaObjC.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
BASE_DIR=$(git rev-parse --show-toplevel)
TMP_DIR=$(mktemp -d)
fd -e h -e m . "${BASE_DIR}/examples/SemaObjC" -x tree-sitter parse {} --quiet | perl -pe 's/\d+ ms\s+\((ERROR|MISSING [^\[]+) \[(\d+),.*$/$2/' | perl -pe 's/\.(h|m)\s*(\d+)/.$1:$2/' > "${TMP_DIR}/temp.txt"
cat "${TMP_DIR}/temp.txt" | awk -F ":" '{print "echo \"###########\" && echo \"" $0 "\" && echo \"\" && "}' > "${TMP_DIR}/echo.txt"
cat "${TMP_DIR}/temp.txt" | awk -F ":" '{print $2}' | xargs -I {} sh -c 'seq -s"," `echo "{}-1" | bc` 2 `echo "{}+1" | bc` && echo ""' | perl -pe 's/,$/p/' | perl -pe "s/^/sed -n '/" | perl -pe "s/$/' /" | perl -pe "s/-1,/0,/" > "${TMP_DIR}/sed.txt"
cat "${TMP_DIR}/temp.txt" | awk -F ":" '{print $1}' > "${TMP_DIR}/file.txt"
paste "${TMP_DIR}/sed.txt" "${TMP_DIR}/file.txt" > "${TMP_DIR}/sed-file.txt"
paste "${TMP_DIR}/echo.txt" "${TMP_DIR}/sed-file.txt" > "${TMP_DIR}/run.sh"
sh "${TMP_DIR}/run.sh" > "${BASE_DIR}/examples/SemaObjC.txt"

View File

@ -0,0 +1,16 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s
// expected-no-diagnostics
// rdar://10565506
@protocol P @end
@interface I
@property Class<P> MyClass;
@property Class MyClass1;
@property void * VOIDSTAR;
@end
@implementation I
@synthesize MyClass, MyClass1, VOIDSTAR;
@end

View File

@ -0,0 +1,39 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
// expected-no-diagnostics
@interface MyObject {
int _foo;
}
@end
@interface MyObject(whatever)
@property (assign) int foo;
@end
@interface MyObject()
@property (assign) int foo;
@end
@implementation MyObject
@synthesize foo = _foo;
@end
// rdar://10666594
@interface MPMediaItem
@end
@class MPMediaItem;
@interface MPMediaItem ()
@property (nonatomic, readonly) id title;
@end
@interface PodcastEpisodesViewController
@end
@implementation PodcastEpisodesViewController
- (id) Meth {
MPMediaItem *episode;
return episode.title;
}
@end

View File

@ -0,0 +1,19 @@
// RUN: %clang_cc1 -Wduplicate-method-match -fsyntax-only -verify -Wno-objc-root-class %s
@interface Subclass
{
int ivar;
}
- (void) method; // expected-note {{previous declaration is here}}
- (void) method; // expected-warning {{multiple declarations of method 'method' found and ignored}}
@end
@implementation Subclass
- (void) method {;} // expected-note {{previous declaration is here}}
- (void) method {;} // expected-error {{duplicate declaration of method 'method'}}
@end
int main (void) {
return 0;
}

View File

@ -0,0 +1,57 @@
static inline void *test0(id x) {
return x;
}
static inline void **test1(__strong id* x) {
return (void**) x;
}
struct Test3 {
id *field;
};
@interface Test4 {
@public
id *field1;
__strong id *field2;
}
@end
struct Test5 {
id field;
};
extern struct Test6 *const kMagicConstant;
@interface Test7
@property id *prop;
@end
static inline void *test8(id ptr) {
return (__bridge_retain void*) ptr;
}
typedef struct {
const char *name;
id field;
} Test9;

View File

@ -0,0 +1 @@
struct S { int x; };

View File

@ -0,0 +1,3 @@
module empty {
header "empty.h"
}

View File

@ -0,0 +1,19 @@
// For backward compatibility, fields of C unions declared in system headers
// that have non-trivial ObjC ownership qualifications are marked as unavailable
// unless the qualifier is explicit and __strong.
#pragma clang system_header
typedef __strong id StrongID;
typedef union {
id f0;
_Nonnull id f1;
__weak id f2;
StrongID f3;
} U0_SystemHeader;
typedef union { // expected-note {{'U1_SystemHeader' has subobjects that are non-trivial to destruct}} expected-note {{'U1_SystemHeader' has subobjects that are non-trivial to copy}}
__strong id f0; // expected-note {{f0 has type '__strong id' that is non-trivial to destruct}} expected-note {{f0 has type '__strong id' that is non-trivial to copy}}
_Nonnull id f1;
} U1_SystemHeader;

View File

@ -0,0 +1,10 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -verify %s
// rdar://10907410
void test(id pid, Class pclass) {
void (^block)(void) = @"help"; // expected-error {{initializing 'void (^)(void)' with an expression of incompatible type 'NSString *'}}
void (^block1)(void) = pid;
void (^block2)(void) = @"help"; // expected-error {{initializing 'void (^)(void)' with an expression of incompatible type 'NSString *'}}
void (^block3)(void) = @"help"; // expected-error {{initializing 'void (^)(void)' with an expression of incompatible type 'NSString *'}}
}

View File

@ -0,0 +1,24 @@
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s
// Check that we don't abort when SVE types are made nullable. This
// interface is invalid anyway, but we won't diagnose that until the
// sizeless type extension is added.
@interface foo
@property(nullable) __SVInt8_t s8; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVInt16_t s16; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVInt32_t s32; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVInt64_t s64; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVUint8_t u8; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVUint16_t u16; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVUint32_t u32; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVUint64_t u64; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVFloat16_t f16; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVFloat32_t f32; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVFloat64_t f64; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVBFloat16_t bf16; // expected-error {{cannot be applied to non-pointer type}}
@property(nullable) __SVBool_t b8; // expected-error {{cannot be applied to non-pointer type}}
@end

View File

@ -0,0 +1,17 @@
// RUN: %clang_cc1 -verify %s
@protocol Protocol
- (oneway void) method;
@end
void accessMethodViaPropertySyntaxAndTriggerWarning(id<Protocol> object) {
object.method; // expected-warning {{property access result unused - getters should not be used for side effects}}
}
// rdar://19137815
#pragma clang diagnostic ignored "-Wunused-getter-return-value"
void accessMethodViaPropertySyntaxWhenWarningIsIgnoredDoesNotTriggerWarning(id<Protocol> object) {
object.method;
}

View File

@ -0,0 +1,31 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
@compatibility_alias alias4 foo; // expected-warning {{cannot find interface declaration for 'foo'}}
@class class2; // expected-note {{previous declaration is here}}
@class class3;
typedef int I; // expected-note {{previous declaration is here}}
@compatibility_alias alias1 I; // expected-warning {{cannot find interface declaration for 'I'}}
@compatibility_alias alias class2;
@compatibility_alias alias class3; // expected-error {{conflicting types for alias 'alias'}}
typedef int alias2; // expected-note {{previous declaration is here}}
@compatibility_alias alias2 class3; // expected-error {{conflicting types for alias 'alias2'}}
alias *p;
class2 *p2;
int foo ()
{
if (p == p2) {
int alias = 1;
}
alias *p3;
return p3 == p2;
}

View File

@ -0,0 +1,17 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
// Note: GCC doesn't produce any of the following errors.
@interface Super @end // expected-note {{previous definition is here}}
@interface MyWpModule @end // expected-note {{previous definition is here}}
@compatibility_alias MyAlias MyWpModule;
@compatibility_alias AliasForSuper Super;
@implementation MyAlias : AliasForSuper // expected-error {{conflicting super class name 'Super'}}
@end
@interface MyAlias : AliasForSuper // expected-error {{duplicate interface definition for class 'MyWpModule'}}
@end

View File

@ -0,0 +1,91 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify %s
// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
typedef const void *CFTypeRef;
CFTypeRef CFBridgingRetain(id X);
id CFBridgingRelease(CFTypeRef);
typedef const struct __CFString *CFStringRef;
@interface NSString
@end
CFTypeRef CFCreateSomething();
CFStringRef CFCreateString();
CFTypeRef CFGetSomething();
CFStringRef CFGetString();
id CreateSomething();
NSString *CreateNSString();
void from_cf() {
id obj1 = (__bridge_transfer id)CFCreateSomething();
id obj2 = (__bridge_transfer NSString*)CFCreateString();
(__bridge int*)CFCreateSomething(); // expected-error{{incompatible types casting 'CFTypeRef' (aka 'const void *') to 'int *' with a __bridge cast}}
id obj3 = (__bridge id)CFGetSomething();
id obj4 = (__bridge NSString*)CFGetString();
}
void to_cf(id obj) {
CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething();
CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString();
CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething();
CFStringRef cf4 = (__bridge CFStringRef)CreateNSString();
// rdar://problem/9629566 - temporary workaround
CFTypeRef cf5 = (__bridge_retain CFTypeRef)CreateSomething(); // expected-error {{unknown cast annotation __bridge_retain; did you mean __bridge_retained?}}
// CHECK: fix-it:"{{.*}}":{35:20-35:35}:"__bridge_retained"
}
CFTypeRef fixits() {
id obj1 = (id)CFCreateSomething(); // expected-error{{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \
// expected-note{{use __bridge to convert directly (no change in ownership)}} expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}}
// CHECK: fix-it:"{{.*}}":{40:17-40:17}:"CFBridgingRelease("
// CHECK: fix-it:"{{.*}}":{40:36-40:36}:")"
CFTypeRef cf1 = (CFTypeRef)CreateSomething(); // expected-error{{cast of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \
// expected-note{{use __bridge to convert directly (no change in ownership)}} \
// expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}}
// CHECK: fix-it:"{{.*}}":{45:30-45:30}:"CFBridgingRetain("
// CHECK: fix-it:"{{.*}}":{45:47-45:47}:")"
return (obj1); // expected-error{{implicit conversion of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \
// expected-note{{use __bridge to convert directly (no change in ownership)}} \
// expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}}
// CHECK: fix-it:"{{.*}}":{51:10-51:10}:"(__bridge CFTypeRef)"
// CHECK: fix-it:"{{.*}}":{51:10-51:10}:"CFBridgingRetain"
}
CFTypeRef fixitsWithSpace(id obj) {
return(obj); // expected-error{{implicit conversion of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \
// expected-note{{use __bridge to convert directly (no change in ownership)}} \
// expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}}
// CHECK: fix-it:"{{.*}}":{59:9-59:9}:"(__bridge CFTypeRef)"
// CHECK: fix-it:"{{.*}}":{59:9-59:9}:" CFBridgingRetain"
}
// rdar://problem/20107345
typedef const struct __attribute__((objc_bridge(id))) __CFAnnotatedObject *CFAnnotatedObjectRef;
CFAnnotatedObjectRef CFGetAnnotated();
void testObjCBridgeId() {
id obj;
obj = (__bridge id)CFGetAnnotated();
obj = (__bridge NSString*)CFGetAnnotated();
obj = (__bridge_transfer id)CFGetAnnotated();
obj = (__bridge_transfer NSString*)CFGetAnnotated();
CFAnnotatedObjectRef ref;
ref = (__bridge CFAnnotatedObjectRef) CreateSomething();
ref = (__bridge CFAnnotatedObjectRef) CreateNSString();
ref = (__bridge_retained CFAnnotatedObjectRef) CreateSomething();
ref = (__bridge_retained CFAnnotatedObjectRef) CreateNSString();
}
// rdar://20113785
typedef const struct __attribute__((objc_bridge(UIFont))) __CTFont * CTFontRef;
id testObjCBridgeUnknownTypeToId(CTFontRef font) {
id x = (__bridge id)font;
return x;
}

View File

@ -0,0 +1,59 @@
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify %s
#if __has_feature(arc_cf_code_audited)
char _global[-1]; // expected-error {{declared as an array with a negative size}}
#endif
typedef const void *CFTypeRef;
CFTypeRef CFBridgingRetain(id X);
id CFBridgingRelease(CFTypeRef);
typedef const struct __CFString *CFStringRef;
extern CFStringRef CFMakeString0(void);
#pragma clang arc_cf_code_audited begin
extern CFStringRef CFCreateString0(void);
#pragma clang arc_cf_code_audited end
void test0() {
id x;
x = (id) CFMakeString0(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}}
x = (id) CFCreateString0(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
}
extern CFStringRef CFMakeString1(void) __attribute__((cf_returns_not_retained));
extern CFStringRef CFCreateString1(void) __attribute__((cf_returns_retained));
void test1() {
id x;
x = (id) CFMakeString1();
x = (id) CFCreateString1(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
}
#define CF_AUDIT_BEGIN _Pragma("clang arc_cf_code_audited begin")
#define CF_AUDIT_END _Pragma("clang arc_cf_code_audited end")
#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
CF_AUDIT_BEGIN
extern CFStringRef CFMakeString2(void);
extern CFStringRef CFCreateString2(void) CF_RETURNS_NOT_RETAINED;
extern CFStringRef CFMakeString3(void) CF_RETURNS_RETAINED;
extern CFStringRef CFCreateString3(void);
CF_AUDIT_END
void test2() {
id x;
x = (id) CFMakeString2();
x = (id) CFCreateString2();
x = (id) CFMakeString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
x = (id) CFCreateString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
}
// rdar://14569171
@interface NSString @end
typedef signed int SInt32;
#pragma clang arc_cf_code_audited begin
extern SInt32 CFStringGetIntValue(CFStringRef str); // expected-note {{passing argument to parameter 'str' here}}
#pragma clang arc_cf_code_audited end
void test3() {
NSString* answer = @"42";
int ans = CFStringGetIntValue(answer); // expected-error {{incompatible pointer types passing retainable parameter of type 'NSString *__strong'to a CF function expecting 'CFStringRef'}}
}

View File

@ -0,0 +1,190 @@
// RUN: %clang_cc1 -fsyntax-only -fblocks -fobjc-arc -verify -Wno-objc-root-class %s
// rdar://8843524
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
// rdar://10260525
struct r10260525 {
id (^block) ();
};
struct S {
id __attribute__((objc_ownership(none))) i;
void * vp;
int i1;
};
// rdar://9046528
@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()
{
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}}
}
// rdar://9157348
// rdar://15757510
@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
// rdar://10187884
@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));
// rdar://12173491
@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
// rdar://15304886
@interface NSObject @end
@interface ControllerClass : NSObject @end
@interface SomeClassOwnedByController
@property (readonly) ControllerClass *controller; // expected-note {{property declared here}}
// rdar://15465916
@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

View File

@ -0,0 +1,39 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s
// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// rdar://11913153
typedef const struct __CFString * CFStringRef;
typedef struct __CFString * CFMutableStringRef;
typedef signed long CFIndex;
typedef const struct __CFAllocator * CFAllocatorRef;
extern const CFStringRef kCFBundleNameKey;
@protocol NSCopying @end
@interface NSDictionary
- (id)objectForKeyedSubscript:(id<NSCopying>)key;
@end
#pragma clang arc_cf_code_audited begin
extern
CFMutableStringRef CFStringCreateMutable(CFAllocatorRef alloc, CFIndex maxLength);
#pragma clang arc_cf_code_audited end
typedef const void * CFTypeRef;
id CFBridgingRelease(CFTypeRef __attribute__((cf_consumed)) X);
@interface NSMutableString @end
NSMutableString *test() {
NSDictionary *infoDictionary;
infoDictionary[kCFBundleNameKey] = 0; // expected-error {{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}}
return infoDictionary[CFStringCreateMutable(((void*)0), 100)]; // expected-error {{indexing expression is invalid because subscript type 'CFMutableStringRef' (aka 'struct __CFString *') is not an integral or Objective-C pointer type}} \
// expected-error {{implicit conversion of C pointer type 'CFMutableStringRef' (aka 'struct __CFString *') to Objective-C pointer type '__strong id<NSCopying>' requires a bridged cast}} \
// expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFMutableStringRef' (aka 'struct __CFString *') into ARC}}
}
// CHECK: fix-it:"{{.*}}":{32:25-32:25}:"CFBridgingRelease("
// CHECK: fix-it:"{{.*}}":{32:63-32:63}:")"

View File

@ -0,0 +1,44 @@
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fblocks -Wno-objc-root-class -verify %s
// rdar://problem/10982793
// [p foo] in ARC creates a cleanup.
// The plus is invalid and causes the cleanup to go unbound.
// Don't crash.
@interface A
- (id) foo;
@end
void takeBlock(void (^)(void));
void test0(id p) {
takeBlock(^{ [p foo] + p; }); // expected-error {{invalid operands to binary expression}}
}
void test1(void) {
__autoreleasing id p; // expected-note {{'p' declared here}}
takeBlock(^{ (void) p; }); // expected-error {{cannot capture __autoreleasing variable in a block}}
}
// rdar://17024681
@class WebFrame;
@interface WebView // expected-note {{previous definition is here}}
- (WebFrame *)mainFrame;
@end
@interface WebView // expected-error {{duplicate interface definition for class 'WebView'}}
@property (nonatomic, readonly, strong) WebFrame *mainFrame;
@end
@interface UIWebDocumentView
- (WebView *)webView;
@end
@interface UIWebBrowserView : UIWebDocumentView
@end
@interface StoreBanner @end
@implementation StoreBanner
+ (void)readMetaTagContentForUIWebBrowserView:(UIWebBrowserView *)browserView
{
[[browserView webView] mainFrame];
}
@end

View File

@ -0,0 +1,97 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s
// rdar://9535237
typedef struct dispatch_queue_s *dispatch_queue_t;
typedef void (^dispatch_block_t)(void);
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
extern __attribute__((visibility("default"))) struct dispatch_queue_s _dispatch_main_q;
@interface SwitchBlockCrashAppDelegate
- (void)pageLeft;
- (void)pageRight;;
@end
@implementation SwitchBlockCrashAppDelegate
- (void)choose:(int)button {
switch (button) {
case 0:
dispatch_async((&_dispatch_main_q), ^{ [self pageLeft]; }); // expected-note 3 {{jump enters lifetime of block which strongly captures a variable}}
break;
case 2: // expected-error {{cannot jump}}
dispatch_async((&_dispatch_main_q), ^{ [self pageRight]; }); // expected-note 2 {{jump enters lifetime of block which strongly captures a variable}}
break;
case 3: // expected-error {{cannot jump}}
{
dispatch_async((&_dispatch_main_q), ^{ [self pageRight]; });
break;
}
case 4: // expected-error {{cannot jump}}
break;
}
__block SwitchBlockCrashAppDelegate *captured_block_obj;
switch (button) {
case 10:
{
dispatch_async((&_dispatch_main_q), ^{ [self pageLeft]; });
break;
}
case 12:
if (button)
dispatch_async((&_dispatch_main_q), ^{ [captured_block_obj pageRight]; });
break;
case 13:
while (button)
dispatch_async((&_dispatch_main_q), ^{ [self pageRight]; });
break;
case 14:
break;
}
switch (button) {
case 10:
{
dispatch_async((&_dispatch_main_q), ^{ [self pageLeft]; });
break;
}
case 12:
if (button)
dispatch_async((&_dispatch_main_q), ^{ [self pageRight]; });
switch (button) {
case 0:
{
dispatch_async((&_dispatch_main_q), ^{ [self pageLeft]; });
break;
}
case 4:
break;
}
break;
case 13:
while (button)
dispatch_async((&_dispatch_main_q), ^{ [self pageRight]; });
break;
case 14:
break;
}
}
- (void)pageLeft {}
- (void)pageRight {}
@end
// Test 2. rdar://problem/11150919
int test2(id obj, int state) { // expected-note {{jump enters lifetime of block}} FIXME: weird location
switch (state) {
case 0:
(void) ^{ (void) obj; };
return 0;
default: // expected-error {{cannot jump}}
return 1;
}
}

View File

@ -0,0 +1,16 @@
// RUN: %clang_cc1 -fobjc-arc -verify -Wno-objc-root-class %s
// rdar://problem/9150784
void test(void) {
__weak id x; // expected-error {{cannot create __weak reference because the current deployment target does not support weak references}}
__weak void *v; // expected-warning {{'__weak' only applies to Objective-C object or block pointer types}}
}
@interface A
@property (weak) id testObjectWeakProperty; // expected-note {{declared here}}
@end
@implementation A
// rdar://9605088
@synthesize testObjectWeakProperty; // expected-error {{cannot synthesize weak property because the current deployment target does not support weak references}}
@end

View File

@ -0,0 +1,63 @@
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
#ifdef __cplusplus
extern "C" {
#endif
void *memset(void *, int, __SIZE_TYPE__);
void *memmove(void *s1, const void *s2, __SIZE_TYPE__ n);
void *memcpy(void *s1, const void *s2, __SIZE_TYPE__ n);
#ifdef __cplusplus
}
#endif
void test(id __strong *sip, id __weak *wip, id __autoreleasing *aip,
id __unsafe_unretained *uip, void *ptr) {
// All okay.
memset(sip, 0, 17);
memset(wip, 0, 17);
memset(aip, 0, 17);
memset(uip, 0, 17);
memcpy(sip, ptr, 17); // expected-warning{{destination for this 'memcpy' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memcpy(wip, ptr, 17); // expected-warning{{destination for this 'memcpy' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memcpy(aip, ptr, 17); // expected-warning{{destination for this 'memcpy' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memcpy(uip, ptr, 17);
memcpy(ptr, sip, 17); // expected-warning{{source of this 'memcpy' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memcpy(ptr, wip, 17); // expected-warning{{source of this 'memcpy' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memcpy(ptr, aip, 17); // expected-warning{{source of this 'memcpy' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memcpy(ptr, uip, 17);
memmove(sip, ptr, 17); // expected-warning{{destination for this 'memmove' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memmove(wip, ptr, 17); // expected-warning{{destination for this 'memmove' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memmove(aip, ptr, 17); // expected-warning{{destination for this 'memmove' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memmove(uip, ptr, 17);
memmove(ptr, sip, 17); // expected-warning{{source of this 'memmove' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memmove(ptr, wip, 17); // expected-warning{{source of this 'memmove' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memmove(ptr, aip, 17); // expected-warning{{source of this 'memmove' call is a pointer to ownership-qualified type}} \
// expected-note{{explicitly cast the pointer to silence this warning}}
memmove(ptr, uip, 17);
}
void rdar9772982(int i, ...) {
__builtin_va_list ap;
__builtin_va_start(ap, i);
__builtin_va_arg(ap, __strong id); // expected-error{{second argument to 'va_arg' is of ARC ownership-qualified type '__strong id'}}
__builtin_va_end(ap);
}

View File

@ -0,0 +1,31 @@
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -fblocks -triple x86_64-apple-darwin10.0.0 -DOBJCARC %s
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
// rdar://10187884
#ifdef OBJCARC
typedef void (^blk)(id arg1, __attribute((ns_consumed)) id arg2);
typedef void (^blk1)(__attribute((ns_consumed))id arg1, __attribute((ns_consumed)) id arg2);
blk a = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}}
blk b = ^void (id arg1, __attribute((ns_consumed)) id arg2){};
blk c = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}}
blk d = ^void (id arg1, id arg2) {}; // expected-error {{incompatible block pointer types initializing}}
blk1 a1 = ^void (__attribute((ns_consumed)) id arg1, id arg2){}; // expected-error {{incompatible block pointer types initializing}}
blk1 b2 = ^void (id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}}
blk1 c3 = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){};
blk1 d4 = ^void (id arg1, id arg2) {}; // expected-error {{incompatible block pointer types initializing}}
#else
@interface Sub
-(void) m:(id)p; // expected-note {{parameter declared here}}
@end
@interface Super : Sub
-(void) m:(__attribute__((ns_consumed)) id)p; // expected-warning {{overriding method has mismatched ns_consumed attribute on its parameter}}
@end
#endif

View File

@ -0,0 +1,32 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-arc -fobjc-runtime-has-weak %s -emit-llvm -o - | FileCheck %s
// CHECK: bitcast {{.*}} %self_weak_s_w_s
// CHECK-NEXT: llvm.objc.destroyWeak
// CHECK-NEXT: bitcast {{.*}} %self_strong_w_s
// CHECK-NEXT: llvm.objc.storeStrong
// CHECK-NEXT: bitcast {{.*}} %self_weak_s
// CHECK-NEXT: llvm.objc.destroyWeak
// CHECK-NEXT: bitcast {{.*}} %self_weak_s3
// CHECK-NEXT: llvm.objc.destroyWeak
// CHECK-NEXT: bitcast {{.*}} %self_strong3
// CHECK-NEXT: llvm.objc.storeStrong
// CHECK-NEXT: bitcast {{.*}} %self_strong2
// CHECK-NEXT: llvm.objc.storeStrong
// CHECK-NEXT: bitcast {{.*}} %self_strong
// CHECK-NEXT: llvm.objc.storeStrong
@interface NSObject
@end
@interface A : NSObject
@end
@implementation A
- (void)test {
__attribute__((objc_ownership(strong))) __typeof__(self) self_strong;
__attribute__((objc_ownership(strong))) __typeof__(self_strong) self_strong2;
__attribute__((objc_ownership(strong))) __typeof__(self_strong2) self_strong3;
__attribute__((objc_ownership(weak))) __typeof__(self_strong3) self_weak_s3;
__attribute__((objc_ownership(weak))) __typeof__(self_strong) self_weak_s;
__attribute__((objc_ownership(strong))) __typeof__(self_weak_s) self_strong_w_s;
__attribute__((objc_ownership(weak))) __typeof__(self_strong_w_s) self_weak_s_w_s;
}
@end

View File

@ -0,0 +1,127 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -fobjc-runtime-has-weak -Wexplicit-ownership-type -verify -Wno-objc-root-class %s
// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -fobjc-runtime-has-weak -Wexplicit-ownership-type -verify -Wno-objc-root-class %s
// rdar://10244607
typedef const struct __CFString * CFStringRef;
@class NSString;
NSString *CFBridgingRelease();
typedef NSString * PNSString;
typedef __autoreleasing NSString * AUTORELEASEPNSString;
@interface I @end
@implementation I
- (CFStringRef)myString
{
CFStringRef myString =
(__bridge CFStringRef) (__strong NSString *)CFBridgingRelease(); // expected-error {{explicit ownership qualifier on cast result has no effect}}
myString =
(__bridge CFStringRef) (__autoreleasing PNSString) CFBridgingRelease(); // expected-error {{explicit ownership qualifier on cast result has no effect}}
myString =
(__bridge CFStringRef) (AUTORELEASEPNSString) CFBridgingRelease(); // OK
myString =
(__bridge CFStringRef) (typeof(__strong NSString *)) CFBridgingRelease(); // expected-error {{explicit ownership qualifier on cast result has no effect}}
return myString;
}
- (void)decodeValueOfObjCType:(const char *)type at:(void *)addr {
__autoreleasing id *stuff = (__autoreleasing id *)addr;
}
@end
// rdar://problem/10711456
__strong I *__strong test1; // expected-error {{the type 'I *__strong' is already explicitly ownership-qualified}}
__strong I *(__strong test2); // expected-error {{the type 'I *__strong' is already explicitly ownership-qualified}}
__strong I *(__strong (test3)); // expected-error {{the type 'I *__strong' is already explicitly ownership-qualified}}
__unsafe_unretained __typeof__(test3) test4;
typedef __strong I *strong_I;
__unsafe_unretained strong_I test5;
// rdar://10907090
typedef void (^T) ();
@interface NSObject @end
@protocol P;
@interface Radar10907090 @end
@implementation Radar10907090
- (void) MMM : (NSObject*) arg0 : (NSObject<P>**)arg : (id) arg1 : (id<P>*) arg2 {} // expected-warning {{method parameter of type 'NSObject<P> *__autoreleasing *' with no explicit ownership}} \
// expected-warning {{method parameter of type '__autoreleasing id<P> *' with no explicit ownership}}
- (void) MM : (NSObject*) arg0 : (__strong NSObject**)arg : (id) arg1 : (__strong id*) arg2 {}
- (void) M : (NSObject**)arg0 : (id*)arg {} // expected-warning {{method parameter of type 'NSObject *__autoreleasing *' with no explicit ownership}} \
// expected-warning {{method parameter of type '__autoreleasing id *' with no explicit ownership}}
- (void) N : (__strong NSObject***) arg0 : (__strong NSObject<P>***)arg : (float**) arg1 : (double) arg2 {}
- (void) BLOCK : (T*) arg0 : (T)arg : (__strong T*) arg1 {} // expected-warning {{method parameter of type '__autoreleasing T *' (aka 'void (^__autoreleasing *)()') with no explicit ownership}}
@end
// rdar://12280826
@class NSMutableDictionary, NSError;
@interface Radar12280826
- (void)createInferiorTransportAndSetEnvironment:(NSMutableDictionary*)environment error:(__autoreleasing NSError**)error;
@end
@implementation Radar12280826
- (void)createInferiorTransportAndSetEnvironment:(NSMutableDictionary*)environment error:(__autoreleasing NSError**)error {}
@end
// <rdar://problem/12367446>
typedef __strong id strong_id;
typedef NSObject *NSObject_ptr;
typedef __strong NSObject *strong_NSObject_ptr;
// Warn
__strong id f1(); // expected-warning{{ARC __strong lifetime qualifier on return type is ignored}}
NSObject __unsafe_unretained *f2(int); // expected-warning{{ARC __unsafe_unretained lifetime qualifier on return type is ignored}}
__autoreleasing NSObject *f3(void); // expected-warning{{ARC __autoreleasing lifetime qualifier on return type is ignored}}
NSObject * __strong f4(void); // expected-warning{{ARC __strong lifetime qualifier on return type is ignored}}
NSObject_ptr __strong f5(); // expected-warning{{ARC __strong lifetime qualifier on return type is ignored}}
typedef __strong id (*fptr)(int); // expected-warning{{ARC __strong lifetime qualifier on return type is ignored}}
// Don't warn
strong_id f6();
strong_NSObject_ptr f7();
typedef __strong id (^block_ptr)(int);
// rdar://10127067
void test8_a() {
__weak id *(^myBlock)(void);
__weak id *var = myBlock();
(void) (__strong id *) &myBlock;
(void) (__weak id *) &myBlock; // expected-error {{cast}}
}
void test8_b() {
__weak id (^myBlock)(void);
(void) (__weak id *) &myBlock;
(void) (__strong id *) &myBlock; // expected-error {{cast}}
}
void test8_c() {
__weak id (^*(^myBlock)(void))(void);
(void) (__weak id*) myBlock();
(void) (__strong id*) myBlock(); // expected-error {{cast}}
(void) (__weak id*) &myBlock; // expected-error {{cast}}
(void) (__strong id*) &myBlock;
}
@class Test9;
void test9_a() {
__weak Test9 **(^myBlock)(void);
__weak Test9 **var = myBlock();
(void) (__strong Test9 **) &myBlock;
(void) (__weak Test9 **) &myBlock; // expected-error {{cast}}
}
void test9_b() {
__weak Test9 *(^myBlock)(void);
(void) (__weak Test9**) &myBlock;
(void) (__strong Test9**) &myBlock; // expected-error {{cast}}
}
void test9_c() {
__weak Test9 *(^*(^myBlock)(void))(void);
(void) (__weak Test9 **) myBlock();
(void) (__strong Test9 **) myBlock(); // expected-error {{cast}}
(void) (__weak Test9 **) &myBlock; // expected-error {{cast}}
(void) (__strong Test9 **) &myBlock;
}

View File

@ -0,0 +1,41 @@
// RUN: %clang_cc1 -fsyntax-only -x objective-c -fobjc-arc -verify -Wno-objc-root-class %s
// rdar://15499111
typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef; // expected-note 5 {{declared here}}
typedef struct __attribute__((objc_bridge_related(NSColor,,CGColor1))) CGColor1 *CGColorRef1;
typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColorRef2;
@interface NSColor // expected-note 5 {{declared here}}
+ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
- (CGColorRef)CGColor;
- (CGColorRef1)CGColor1;
@end
@interface NSTextField
- (void)setBackgroundColor:(NSColor *)color;
- (NSColor *)backgroundColor;
@end
void foo(NSColor*); // expected-note {{passing argument to parameter here}}
NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *__strong'; use '+colorWithCGColor:' method for this conversion}}
return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
}
NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) {
foo(newColor); // expected-warning {{incompatible pointer types passing 'CGColorRef1' (aka 'struct CGColor1 *') to parameter of type 'NSColor *'}}
textField.backgroundColor = newColor; // expected-warning {{incompatible pointer types assigning to 'NSColor *__strong' from 'CGColorRef1' (aka 'struct CGColor1 *')}}
return newColor; // expected-warning {{incompatible pointer types returning 'CGColorRef1' (aka 'struct CGColor1 *') from a function with result type 'NSColor *'}}
}
CGColorRef Test3(NSTextField *textField, CGColorRef newColor) {
newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
}
CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) {
newColor = textField.backgroundColor; // expected-warning {{incompatible pointer types assigning}}
return textField.backgroundColor; // expected-warning {{incompatible pointer types returning}}
}

View File

@ -0,0 +1,50 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s
// rdar://9659270
@interface NSObject
- (id)copy; // expected-note {{method 'copy' declared here}}
- (id) test __attribute__((ns_returns_retained)); // expected-note {{method 'test' declared here}}
+ (id) new ; // expected-note {{method 'new' declared here}}
- (id) init __attribute__((ns_returns_not_retained));
- (id)PlusZero;
- (id)PlusOne __attribute__((ns_returns_retained)); // expected-note {{method 'PlusOne' declared here}}
- (id)self;
@end
@interface I : NSObject
{
SEL sel1;
}
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(double)delay inModes:(I *)modes;
@end
@implementation I
- (id) Meth {
return [self performSelector : @selector(copy)]; // expected-error {{performSelector names a selector which retains the object}}
return [self performSelector : @selector(test)]; // expected-error {{performSelector names a selector which retains the object}}
return [self performSelector : @selector(new)]; // expected-error {{performSelector names a selector which retains the object}}
return [self performSelector : @selector(init)];
return [self performSelector : sel1]; // expected-warning {{performSelector may cause a leak because its selector is unknown}} \
// expected-note {{used here}}
return [self performSelector: (@selector(PlusZero))];
return [self performSelector : @selector(PlusZero)];
return [self performSelector : @selector(PlusOne)]; // expected-error {{performSelector names a selector which retains the object}}
// Avoid the unknown selector warning for more complicated performSelector
// variations because it produces too many false positives.
[self performSelector: sel1 withObject:0 afterDelay:0 inModes:0];
return [self performSelector: @selector(self)]; // No error, -self is not +1!
}
- (id)performSelector:(SEL)aSelector { return 0; }
- (id)performSelector:(SEL)aSelector withObject:(id)object { return 0; }
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2 { return 0; }
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(double)delay inModes:(I *)modes { }
@end

View File

@ -0,0 +1,293 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify %s
// rdar://9340606
@interface Foo {
@public
id __unsafe_unretained x;
id __weak y;
id __autoreleasing z; // expected-error {{instance variables cannot have __autoreleasing ownership}}
}
@property(strong) id x;
@property(strong) id y;
@property(strong) id z;
@end
@interface Bar {
@public
id __unsafe_unretained x;
id __weak y;
id __autoreleasing z; // expected-error {{instance variables cannot have __autoreleasing ownership}}
}
@property(retain) id x;
@property(retain) id y;
@property(retain) id z;
@end
@interface Bas {
@public
id __unsafe_unretained x;
id __weak y;
id __autoreleasing z; // expected-error {{instance variables cannot have __autoreleasing ownership}}
}
@property(copy) id x;
@property(copy) id y;
@property(copy) id z;
@end
// Errors should start about here :-)
@interface Bat
@property(strong) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
@property(strong) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}}
@property(strong) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
@end
@interface Bau
@property(retain) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
@property(retain) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}}
@property(retain) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
@end
@interface Bav
@property(copy) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
@property(copy) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}}
@property(copy) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
@end
@interface Bingo
@property(assign) __unsafe_unretained id x;
@property(assign) __weak id y; // expected-error {{unsafe_unretained property 'y' may not also be declared __weak}}
@property(assign) __autoreleasing id z; // expected-error {{unsafe_unretained property 'z' may not also be declared __autoreleasing}}
@end
@interface Batman
@property(unsafe_unretained) __unsafe_unretained id x;
@property(unsafe_unretained) __weak id y; // expected-error {{unsafe_unretained property 'y' may not also be declared __weak}}
@property(unsafe_unretained) __autoreleasing id z; // expected-error {{unsafe_unretained property 'z' may not also be declared __autoreleasing}}
@end
// rdar://9396329
@interface Super
@property (readonly, retain) id foo;
@property (readonly, weak) id fee;
@property (readonly, strong) id frr;
@end
@interface Bugg : Super
@property (readwrite) id foo;
@property (readwrite) id fee;
@property (readwrite) id frr;
@end
// rdar://20152386
// rdar://20383235
@interface NSObject @end
#pragma clang assume_nonnull begin
@interface I: NSObject
@property(nonatomic, weak) id delegate; // Do not warn, nullable is inferred.
@property(nonatomic, weak, readonly) id ROdelegate; // Do not warn, nullable is inferred.
@property(nonatomic, weak, nonnull) id NonNulldelete; // expected-error {{property attributes 'nonnull' and 'weak' are mutually exclusive}}
@property(nonatomic, weak, nullable) id Nullabledelete; // do not warn
// strong cases.
@property(nonatomic, strong) id stdelegate; // Do not warn
@property(nonatomic, readonly) id stROdelegate; // Do not warn
@property(nonatomic, strong, nonnull) id stNonNulldelete; // Do not warn
@property(nonatomic, nullable) id stNullabledelete; // do not warn
@end
#pragma clang assume_nonnull end
@interface J: NSObject
@property(nonatomic, weak) id ddd; // Do not warn, nullable is inferred.
@property(nonatomic, weak, nonnull) id delegate; // expected-error {{property attributes 'nonnull' and 'weak' are mutually exclusive}}
@property(nonatomic, weak, nonnull, readonly) id ROdelegate; // expected-error {{property attributes 'nonnull' and 'weak' are mutually exclusive}}
@end
// rdar://problem/23931441
@protocol P
@property(readonly, retain) id prop;
@end
__attribute__((objc_root_class))
@interface I2<P>
@end
@interface I2()
@property (readwrite) id prop;
@end
@implementation I2
@synthesize prop;
@end
// rdar://31579994
// Verify that the all of the property declarations in inherited protocols are
// compatible when synthesing a property from a protocol.
@protocol CopyVsAssign1
@property (copy, nonatomic, readonly) id prop; // expected-error {{property with attribute 'copy' was selected for synthesis}}
@end
@protocol CopyVsAssign2
@property (assign, nonatomic, readonly) id prop; // expected-note {{it could also be property without attribute 'copy' declared here}}
@end
@interface CopyVsAssign: Foo <CopyVsAssign1, CopyVsAssign2>
@end
@implementation CopyVsAssign
@synthesize prop; // expected-note {{property synthesized here}}
@end
@protocol RetainVsNonRetain1
@property (readonly) id prop; // expected-error {{property without attribute 'retain (or strong)' was selected for synthesis}}
@end
@protocol RetainVsNonRetain2
@property (retain, readonly) id prop; // expected-note {{it could also be property with attribute 'retain (or strong)' declared here}}
@end
@interface RetainVsNonRetain: Foo <RetainVsNonRetain1, RetainVsNonRetain2>
@end
@implementation RetainVsNonRetain
@synthesize prop; // expected-note {{property synthesized here}}
@end
@protocol AtomicVsNonatomic1
@property (copy, nonatomic, readonly) id prop; // expected-error {{property without attribute 'atomic' was selected for synthesis}}
@end
@protocol AtomicVsNonatomic2
@property (copy, atomic, readonly) id prop; // expected-note {{it could also be property with attribute 'atomic' declared here}}
@end
@interface AtomicVsNonAtomic: Foo <AtomicVsNonatomic1, AtomicVsNonatomic2>
@end
@implementation AtomicVsNonAtomic
@synthesize prop; // expected-note {{property synthesized here}}
@end
@protocol Getter1
@property (copy, readonly) id prop; // expected-error {{property with getter 'prop' was selected for synthesis}}
@end
@protocol Getter2
@property (copy, getter=x, readonly) id prop; // expected-note {{it could also be property with getter 'x' declared here}}
@end
@interface GetterVsGetter: Foo <Getter1, Getter2>
@end
@implementation GetterVsGetter
@synthesize prop; // expected-note {{property synthesized here}}
@end
@protocol Setter1
@property (copy, readonly) id prop;
@end
@protocol Setter2
@property (copy, setter=setp:, readwrite) id prop; // expected-error {{property with setter 'setp:' was selected for synthesis}}
@end
@protocol Setter3
@property (copy, readwrite) id prop; // expected-note {{it could also be property with setter 'setProp:' declared here}}
@end
@interface SetterVsSetter: Foo <Setter1, Setter2, Setter3>
@end
@implementation SetterVsSetter
@synthesize prop; // expected-note {{property synthesized here}}
@end
@protocol TypeVsAttribute1
@property (assign, atomic, readonly) int prop; // expected-error {{property of type 'int' was selected for synthesis}}
@end
@protocol TypeVsAttribute2
@property (assign, atomic, readonly) id prop; // expected-note {{it could also be property of type 'id' declared here}}
@end
@protocol TypeVsAttribute3
@property (copy, readonly) id prop; // expected-note {{it could also be property with attribute 'copy' declared here}}
@end
@interface TypeVsAttribute: Foo <TypeVsAttribute1, TypeVsAttribute2, TypeVsAttribute3>
@end
@implementation TypeVsAttribute
@synthesize prop; // expected-note {{property synthesized here}}
@end
@protocol TypeVsSetter1
@property (assign, nonatomic, readonly) int prop; // expected-note {{it could also be property of type 'int' declared here}}
@end
@protocol TypeVsSetter2
@property (assign, nonatomic, readonly) id prop; // ok
@end
@protocol TypeVsSetter3
@property (assign, nonatomic, readwrite) id prop; // expected-error {{property of type 'id' was selected for synthesis}}
@end
@interface TypeVsSetter: Foo <TypeVsSetter1, TypeVsSetter2, TypeVsSetter3>
@end
@implementation TypeVsSetter
@synthesize prop; // expected-note {{property synthesized here}}
@end
@protocol AutoStrongProp
@property (nonatomic, readonly) NSObject *prop;
@end
@protocol AutoStrongProp_Internal <AutoStrongProp>
// This property gets the 'strong' attribute automatically.
@property (nonatomic, readwrite) NSObject *prop;
@end
@interface SynthesizeWithImplicitStrongNoError : NSObject <AutoStrongProp>
@end
@interface SynthesizeWithImplicitStrongNoError () <AutoStrongProp_Internal>
@end
@implementation SynthesizeWithImplicitStrongNoError
// no error, 'strong' is implicit in the 'readwrite' property.
@synthesize prop = _prop;
@end
// rdar://39024725
// Allow strong readwrite property and a readonly one.
@protocol StrongCollision
@property(strong) NSObject *p;
@property(copy) NSObject *p2;
// expected-error@+1 {{property with attribute 'retain (or strong)' was selected for synthesis}}
@property(strong, readwrite) NSObject *collision;
@end
@protocol ReadonlyCollision
@property(readonly) NSObject *p;
@property(readonly) NSObject *p2;
// expected-note@+1 {{it could also be property without attribute 'retain (or strong)' declared here}}
@property(readonly, weak) NSObject *collision;
@end
@interface StrongReadonlyCollision : NSObject <StrongCollision, ReadonlyCollision>
@end
@implementation StrongReadonlyCollision
// no error
@synthesize p = _p;
@synthesize p2 = _p2;
@synthesize collision = _collision; // expected-note {{property synthesized here}}
@end
// This used to crash because we'd temporarly store the weak attribute on the
// declaration specifier, then deallocate it when clearing the declarator.
id i1, __weak i2, i3;

View File

@ -0,0 +1,212 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s
// rdar://9340606
@interface Foo {
@public
id __unsafe_unretained x; // expected-error {{existing instance variable 'x' for strong property 'x' may not be __unsafe_unretained}}
id __weak y; // expected-error {{existing instance variable 'y' for strong property 'y' may not be __weak}}
id __autoreleasing z; // expected-error {{instance variables cannot have __autoreleasing ownership}}
}
@property(strong) id x; // expected-note {{property declared here}}
@property(strong) id y; // expected-note {{property declared here}}
@property(strong) id z;
@end
@implementation Foo
@synthesize x; // expected-note {{property synthesized here}}
@synthesize y; // expected-note {{property synthesized here}}
@synthesize z; // suppressed
@end
@interface Bar {
@public
id __unsafe_unretained x; // expected-error {{existing instance variable 'x' for strong property 'x' may not be __unsafe_unretained}}
id __weak y; // expected-error {{existing instance variable 'y' for strong property 'y' may not be __weak}}
id __autoreleasing z; // expected-error {{instance variables cannot have __autoreleasing ownership}}
}
@property(retain) id x; // expected-note {{property declared here}}
@property(retain) id y; // expected-note {{property declared here}}
@property(retain) id z;
@end
@implementation Bar
@synthesize x; // expected-note {{property synthesized here}}
@synthesize y; // expected-note {{property synthesized here}}
@synthesize z; // suppressed
@end
@interface Bas {
@public
id __unsafe_unretained x; // expected-error {{existing instance variable 'x' for strong property 'x' may not be __unsafe_unretained}}
id __weak y; // expected-error {{existing instance variable 'y' for strong property 'y' may not be __weak}}
id __autoreleasing z; // expected-error {{instance variables cannot have __autoreleasing ownership}}
}
@property(copy) id x; // expected-note {{property declared here}}
@property(copy) id y; // expected-note {{property declared here}}
@property(copy) id z;
@end
@implementation Bas
@synthesize x; // expected-note {{property synthesized here}}
@synthesize y; // expected-note {{property synthesized here}}
@synthesize z; // suppressed
@end
@interface Bat
@property(strong) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
@property(strong) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
@end
@interface Bau
@property(retain) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
@property(retain) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
@end
@interface Bav
@property(copy) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
@property(copy) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
@end
// rdar://9341593
@interface Gorf {
id __unsafe_unretained x;
id y; // expected-error {{existing instance variable 'y' for property 'y' with assign attribute must be __unsafe_unretained}}
}
@property(assign) id __unsafe_unretained x;
@property(assign) id y; // expected-note {{property declared here}}
@property(assign) id z;
@end
@implementation Gorf
@synthesize x;
@synthesize y; // expected-note {{property synthesized here}}
@synthesize z;
@end
@interface Gorf2 {
id __unsafe_unretained x;
id y; // expected-error {{existing instance variable 'y' for property 'y' with unsafe_unretained attribute must be __unsafe_unretained}}
}
@property(unsafe_unretained) id __unsafe_unretained x;
@property(unsafe_unretained) id y; // expected-note {{property declared here}}
@property(unsafe_unretained) id z;
@end
@implementation Gorf2
@synthesize x;
@synthesize y; // expected-note {{property synthesized here}}
@synthesize z;
@end
// rdar://9355230
@interface I {
char _isAutosaving;
}
@property char isAutosaving;
@end
@implementation I
@synthesize isAutosaving = _isAutosaving;
@end
// rdar://10239594
// Test for 'Class' properties being unretained.
@interface MyClass {
@private
Class _controllerClass;
id _controllerId;
}
@property (copy) Class controllerClass;
@property (copy) id controllerId;
@end
@implementation MyClass
@synthesize controllerClass = _controllerClass;
@synthesize controllerId = _controllerId;
@end
// rdar://10630891
@interface UIView @end
@class UIColor;
@interface UIView(UIViewRendering)
@property(nonatomic,copy) UIColor *backgroundColor;
@end
@interface UILabel : UIView
@end
@interface MyView
@property (strong) UILabel *label;
@end
@interface MyView2 : MyView @end
@implementation MyView2
- (void)foo {
super.label.backgroundColor = 0;
}
@end
// rdar://10694932
@interface Baz
@property id prop;
@property __strong id strong_prop;
@property (strong) id strong_attr_prop;
@property (strong) __strong id really_strong_attr_prop;
+ (id) alloc;
- (id) init;
- (id) implicit;
- (void) setImplicit : (id) arg;
@end
void foo(Baz *f) {
f.prop = [[Baz alloc] init];
f.strong_prop = [[Baz alloc] init];
f.strong_attr_prop = [[Baz alloc] init];
f.really_strong_attr_prop = [[Baz alloc] init];
f.implicit = [[Baz alloc] init];
}
// rdar://11253688
@interface Boom
{
const void * innerPointerIvar __attribute__((objc_returns_inner_pointer)); // expected-error {{'objc_returns_inner_pointer' attribute only applies to Objective-C methods and Objective-C properties}}
}
@property (readonly) Boom * NotInnerPointer __attribute__((objc_returns_inner_pointer)); // expected-warning {{'objc_returns_inner_pointer' attribute only applies to properties that return a non-retainable pointer}}
- (Boom *) NotInnerPointerMethod __attribute__((objc_returns_inner_pointer)); // expected-warning {{'objc_returns_inner_pointer' attribute only applies to methods that return a non-retainable pointer}}
@property (readonly) const void * innerPointer __attribute__((objc_returns_inner_pointer));
@end
@interface Foo2 {
id _prop; // expected-error {{existing instance variable '_prop' for property 'prop' with assign attribute must be __unsafe_unretained}}
}
@property (nonatomic, assign) id prop; // expected-note {{property declared here}}
@end
@implementation Foo2
@end
// rdar://13885083
@interface NSObject
-(id)init;
@end
typedef char BOOL;
@interface Test13885083 : NSObject
@property (nonatomic, assign) BOOL retain; // expected-error {{ARC forbids synthesis of 'retain'}}
-(id)init;
@end
@implementation Test13885083
-(id) init
{
self = [super init];
return self;
}
@end

View File

@ -0,0 +1,65 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -fobjc-exceptions -verify -Wno-objc-root-class %s
// rdar://9309489
@interface MyClass {
id __weak myString; // expected-error {{existing instance variable 'myString' for strong property 'myString' may not be __weak}}
id StrongIvar;
id __weak myString2; // expected-error {{existing instance variable 'myString2' for strong property 'myString2' may not be __weak}}
id __weak myString3;
id StrongIvar5; // expected-error {{existing instance variable 'StrongIvar5' for __weak property 'myString5' must be __weak}}
}
@property (strong) id myString; // expected-note {{property declared here}}
@property (strong) id myString1;
@property (retain) id myString2; // expected-note {{property declared here}}
//
@property (weak) id myString3;
@property (weak) id myString4;
@property __weak id myString5; // expected-note {{property declared here}}
@end
@implementation MyClass
@synthesize myString; // expected-note {{property synthesized here}}
@synthesize myString1 = StrongIvar; // OK
@synthesize myString2 = myString2; // expected-note {{property synthesized here}}
//
@synthesize myString3; // OK
@synthesize myString4; // OK
@synthesize myString5 = StrongIvar5; // expected-note {{property synthesized here}}
@end
// rdar://9340692
@interface Foo {
@public
id __unsafe_unretained x; // expected-error {{existing instance variable 'x' for __weak property 'x' must be __weak}}
id __strong y; // expected-error {{existing instance variable 'y' for __weak property 'y' must be __weak}}
id __autoreleasing z; // expected-error {{instance variables cannot have __autoreleasing ownership}}
}
@property(weak) id x; // expected-note {{property declared here}}
@property(weak) id y; // expected-note {{property declared here}}
@property(weak) id z;
@end
@implementation Foo
@synthesize x; // expected-note {{property synthesized here}}
@synthesize y; // expected-note {{property synthesized here}}
@synthesize z; // suppressed
@end
// rdar://problem/10904479
// Don't crash.
@interface Test2
// Minor FIXME: kill the redundant error
@property (strong) UndeclaredClass *test2; // expected-error {{unknown type name 'UndeclaredClass'}} expected-error {{must be of object type}}
@end
@implementation Test2
@synthesize test2;
@end
// rdar://problem/11144407
@interface Test3
@property (strong) id exception;
@end
void test3(Test3 *t3) {
@throw t3.exception;
}

View File

@ -0,0 +1,30 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s
// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s
// expected-no-diagnostics
// rdar:// 10558871
@interface PP
@property (readonly) id ReadOnlyPropertyNoBackingIvar;
@property (readonly) id ReadOnlyProperty;
@property (readonly) id ReadOnlyPropertyX;
@end
@implementation PP {
__weak id _ReadOnlyProperty;
}
@synthesize ReadOnlyPropertyNoBackingIvar;
@synthesize ReadOnlyProperty = _ReadOnlyProperty;
@synthesize ReadOnlyPropertyX = _ReadOnlyPropertyX;
@end
@interface DD
@property (readonly) id ReadOnlyProperty;
@property (readonly) id ReadOnlyPropertyStrong;
@property (readonly) id ReadOnlyPropertyNoBackingIvar;
@end
@implementation DD {
__weak id _ReadOnlyProperty;
__strong id _ReadOnlyPropertyStrong;
}
@end

View File

@ -0,0 +1,17 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s
// expected-no-diagnostics
// rdar:// 10558871
@interface PP
@property (readonly) id ReadOnlyPropertyNoBackingIvar;
@property (readonly) id ReadOnlyProperty;
@property (readonly) id ReadOnlyPropertyX;
@end
@implementation PP {
__weak id _ReadOnlyProperty;
}
@synthesize ReadOnlyPropertyNoBackingIvar;
@synthesize ReadOnlyProperty = _ReadOnlyProperty;
@synthesize ReadOnlyPropertyX = _ReadOnlyPropertyX;
@end

View File

@ -0,0 +1,501 @@
// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
@interface Test {
@public
Test *ivar;
__weak id weakIvar;
}
@property(weak) Test *weakProp;
@property(strong) Test *strongProp;
- (__weak id)implicitProp;
+ (__weak id)weakProp;
@end
extern void use(id);
extern id get();
extern bool condition();
#define nil ((id)0)
void sanity(Test *a) {
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
use(a.weakProp); // expected-note{{also accessed here}}
use(a.strongProp);
use(a.strongProp); // no-warning
use(a.weakProp); // expected-note{{also accessed here}}
}
void singleUse(Test *a) {
use(a.weakProp); // no-warning
use(a.strongProp); // no-warning
}
void assignsOnly(Test *a) {
a.weakProp = get(); // no-warning
id next = get();
if (next)
a.weakProp = next; // no-warning
a->weakIvar = get(); // no-warning
next = get();
if (next)
a->weakIvar = next; // no-warning
extern __weak id x;
x = get(); // no-warning
next = get();
if (next)
x = next; // no-warning
}
void assignThenRead(Test *a) {
a.weakProp = get(); // expected-note{{also accessed here}}
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
}
void twoVariables(Test *a, Test *b) {
use(a.weakProp); // no-warning
use(b.weakProp); // no-warning
}
void doubleLevelAccess(Test *a) {
use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times in this function and may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
use(a.strongProp.weakProp); // expected-note{{also accessed here}}
}
void doubleLevelAccessIvar(Test *a) {
use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
use(a.strongProp.weakProp); // expected-note{{also accessed here}}
}
void implicitProperties(Test *a) {
use(a.implicitProp); // expected-warning{{weak implicit property 'implicitProp' is accessed multiple times}}
use(a.implicitProp); // expected-note{{also accessed here}}
}
void classProperties() {
use(Test.weakProp); // expected-warning{{weak implicit property 'weakProp' is accessed multiple times}}
use(Test.weakProp); // expected-note{{also accessed here}}
}
void classPropertiesAreDifferent(Test *a) {
use(Test.weakProp); // no-warning
use(a.weakProp); // no-warning
use(a.strongProp.weakProp); // no-warning
}
void ivars(Test *a) {
use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
use(a->weakIvar); // expected-note{{also accessed here}}
}
void globals() {
extern __weak id a;
use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}
use(a); // expected-note{{also accessed here}}
}
void messageGetter(Test *a) {
use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
use([a weakProp]); // expected-note{{also accessed here}}
}
void messageSetter(Test *a) {
[a setWeakProp:get()]; // no-warning
[a setWeakProp:get()]; // no-warning
}
void messageSetterAndGetter(Test *a) {
[a setWeakProp:get()]; // expected-note{{also accessed here}}
use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
}
void mixDotAndMessageSend(Test *a, Test *b) {
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
use([a weakProp]); // expected-note{{also accessed here}}
use([b weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
use(b.weakProp); // expected-note{{also accessed here}}
}
void assignToStrongWrongInit(Test *a) {
id val = a.weakProp; // expected-note{{also accessed here}}
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
}
void assignToStrongWrong(Test *a) {
id val;
val = a.weakProp; // expected-note{{also accessed here}}
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
}
void assignToIvarWrong(Test *a) {
a->weakIvar = get(); // expected-note{{also accessed here}}
use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
}
void assignToGlobalWrong() {
extern __weak id a;
a = get(); // expected-note{{also accessed here}}
use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}
}
void assignToStrongOK(Test *a) {
if (condition()) {
id val = a.weakProp; // no-warning
(void)val;
} else {
id val;
val = a.weakProp; // no-warning
(void)val;
}
}
void assignToStrongConditional(Test *a) {
id val = (condition() ? a.weakProp : a.weakProp); // no-warning
id val2 = a.implicitProp ?: a.implicitProp; // no-warning
}
void testBlock(Test *a) {
use(a.weakProp); // no-warning
use(^{
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this block}}
use(a.weakProp); // expected-note{{also accessed here}}
});
}
void assignToStrongWithCasts(Test *a) {
if (condition()) {
Test *val = (Test *)a.weakProp; // no-warning
(void)val;
} else {
id val;
val = (Test *)a.weakProp; // no-warning
(void)val;
}
}
void assignToStrongWithMessages(Test *a) {
if (condition()) {
id val = [a weakProp]; // no-warning
(void)val;
} else {
id val;
val = [a weakProp]; // no-warning
(void)val;
}
}
void assignAfterRead(Test *a) {
// Special exception for a single read before any writes.
if (!a.weakProp) // no-warning
a.weakProp = get(); // no-warning
}
void readOnceWriteMany(Test *a) {
if (!a.weakProp) { // no-warning
a.weakProp = get(); // no-warning
a.weakProp = get(); // no-warning
}
}
void readOnceAfterWrite(Test *a) {
a.weakProp = get(); // expected-note{{also accessed here}}
if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
a.weakProp = get(); // expected-note{{also accessed here}}
}
}
void readOnceWriteManyLoops(Test *a, Test *b, Test *c, Test *d, Test *e) {
while (condition()) {
if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
a.weakProp = get(); // expected-note{{also accessed here}}
a.weakProp = get(); // expected-note{{also accessed here}}
}
}
do {
if (!b.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
b.weakProp = get(); // expected-note{{also accessed here}}
b.weakProp = get(); // expected-note{{also accessed here}}
}
} while (condition());
for (id x = get(); x; x = get()) {
if (!c.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
c.weakProp = get(); // expected-note{{also accessed here}}
c.weakProp = get(); // expected-note{{also accessed here}}
}
}
for (id x in get()) {
if (!d.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
d.weakProp = get(); // expected-note{{also accessed here}}
d.weakProp = get(); // expected-note{{also accessed here}}
}
}
int array[] = { 1, 2, 3 };
for (int i : array) {
if (!e.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
e.weakProp = get(); // expected-note{{also accessed here}}
e.weakProp = get(); // expected-note{{also accessed here}}
}
}
}
void readOnlyLoop(Test *a) {
while (condition()) {
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
}
}
void readInIterationLoop() {
for (Test *a in get())
use(a.weakProp); // no-warning
}
void readDoubleLevelAccessInLoop() {
for (Test *a in get()) {
use(a.strongProp.weakProp); // no-warning
}
}
void readParameterInLoop(Test *a) {
for (id unused in get()) {
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
(void)unused;
}
}
void readGlobalInLoop() {
static __weak id a;
for (id unused in get()) {
use(a); // expected-warning{{weak variable 'a' is accessed multiple times in this function}}
(void)unused;
}
}
void doWhileLoop(Test *a) {
do {
use(a.weakProp); // no-warning
} while(0);
}
@interface Test (Methods)
@end
@implementation Test (Methods)
- (void)sanity {
use(self.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this method but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
use(self.weakProp); // expected-note{{also accessed here}}
}
- (void)ivars {
use(weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times in this method but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
use(weakIvar); // expected-note{{also accessed here}}
}
- (void)doubleLevelAccessForSelf {
use(self.strongProp.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
use(self.strongProp.weakProp); // expected-note{{also accessed here}}
use(self->ivar.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
use(self->ivar.weakProp); // expected-note{{also accessed here}}
use(self->ivar->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
use(self->ivar->weakIvar); // expected-note{{also accessed here}}
}
- (void)distinctFromOther:(Test *)other {
use(self.strongProp.weakProp); // no-warning
use(other.strongProp.weakProp); // no-warning
use(self->ivar.weakProp); // no-warning
use(other->ivar.weakProp); // no-warning
use(self.strongProp->weakIvar); // no-warning
use(other.strongProp->weakIvar); // no-warning
}
@end
@interface Base1
@end
@interface Sub1 : Base1
@end
@interface Sub1(cat)
-(id)prop;
@end
void test1(Sub1 *s) {
use([s prop]);
use([s prop]);
}
@interface Base1(cat)
@property (weak) id prop;
@end
void test2(Sub1 *s) {
// This does not warn because the "prop" in "Base1(cat)" was introduced
// after the method declaration and we don't find it as overridden.
// Always looking for overridden methods after the method declaration is expensive
// and it's not clear it is worth it currently.
use([s prop]);
use([s prop]);
}
class Wrapper {
Test *a;
public:
void fields() {
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
use(a.weakProp); // expected-note{{also accessed here}}
}
void distinctFromOther(Test *b, const Wrapper &w) {
use(a.weakProp); // no-warning
use(b.weakProp); // no-warning
use(w.a.weakProp); // no-warning
}
static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) {
use(x.a.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
use(y.a.weakProp); // expected-note{{also accessed here}}
}
};
// -----------------------
// False positives
// -----------------------
// Most of these would require flow-sensitive analysis to silence correctly.
void assignNil(Test *a) {
if (condition())
a.weakProp = nil; // expected-note{{also accessed here}}
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
}
void branch(Test *a) {
if (condition())
use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
else
use(a.weakProp); // expected-note{{also accessed here}}
}
void doubleLevelAccess(Test *a, Test *b) {
use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
use(b.strongProp.weakProp); // expected-note{{also accessed here}}
use(a.weakProp.weakProp); // no-warning
}
void doubleLevelAccessIvar(Test *a, Test *b) {
use(a->ivar.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
use(b->ivar.weakProp); // expected-note{{also accessed here}}
use(a.strongProp.weakProp); // no-warning
}
// rdar://13942025
@interface X
@end
@implementation X
- (int) warningAboutWeakVariableInsideTypeof {
__typeof__(self) __weak weakSelf = self;
^(){
__typeof__(weakSelf) blockSelf = weakSelf;
use(blockSelf);
}();
return sizeof(weakSelf);
}
@end
// rdar://19053620
@interface NSNull
+ (NSNull *)null;
@end
@interface INTF @end
@implementation INTF
- (void) Meth : (id) data
{
data = data ?: NSNull.null;
}
@end
// This used to crash in WeakObjectProfileTy::getBaseInfo when getBase() was
// called on an ObjCPropertyRefExpr object whose receiver was an interface.
@class NSString;
@interface NSBundle
+(NSBundle *)foo;
@property (class, strong) NSBundle *foo2;
@property (strong) NSString *prop;
@property(weak) NSString *weakProp;
@end
@interface NSBundle2 : NSBundle
@end
void foo() {
NSString * t = NSBundle.foo.prop;
use(NSBundle.foo.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
use(NSBundle2.foo.weakProp); // expected-note{{also accessed here}}
NSString * t2 = NSBundle.foo2.prop;
use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}}
decltype([NSBundle2.foo2 weakProp]) t3;
decltype(NSBundle2.foo2.weakProp) t4;
__typeof__(NSBundle2.foo2.weakProp) t5;
}
// This used to crash in the constructor of WeakObjectProfileTy when a
// DeclRefExpr was passed that didn't reference a VarDecl.
typedef INTF * INTFPtrTy;
enum E {
e1
};
void foo1() {
INTFPtrTy tmp = (INTFPtrTy)e1;
#if __has_feature(objc_arc)
// expected-error@-2{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}}
#endif
}
@class NSString;
static NSString* const kGlobal = @"";
@interface NSDictionary
- (id)objectForKeyedSubscript:(id)key;
@end
@interface WeakProp
@property (weak) NSDictionary *nd;
@end
@implementation WeakProp
-(void)m {
(void)self.nd[@""]; // no warning
}
@end

View File

@ -0,0 +1,36 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s
// expected-no-diagnostics
// rdar://10156674
@class NSArray;
@interface MyClass2 {
@private
NSArray *_names1;
NSArray *_names2;
NSArray *_names3;
NSArray *_names4;
}
@property (readwrite, strong) NSArray *names1; // <-- warning: Type of property....
- (void)setNames1:(NSArray *)names;
@property (readwrite, strong) __strong NSArray *names2; // <-- warning: Type of property....
- (void)setNames2:(NSArray *)names;
@property (readwrite, strong) __strong NSArray *names3; // <-- OK
- (void)setNames3:(__strong NSArray *)names;
@property (readwrite, strong) NSArray *names4; // <-- warning: Type of property....
- (void)setNames4:(__strong NSArray *)names;
@end
@implementation MyClass2
- (NSArray *)names1 { return _names1; }
- (void)setNames1:(NSArray *)names {}
- (NSArray *)names2 { return _names2; }
- (void)setNames2:(NSArray *)names {}
- (NSArray *)names3 { return _names3; }
- (void)setNames3:(__strong NSArray *)names {}
- (NSArray *)names4 { return _names4; }
- (void)setNames4:(__strong NSArray *)names {}
@end

View File

@ -0,0 +1,56 @@
// RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -DNO_USE
// RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -verify
#include <arc-system-header.h>
#ifndef NO_USE
void test(id op, void *cp) {
cp = test0(op); // expected-error {{'test0' is unavailable in ARC}}
cp = *test1(&op); // expected-error {{'test1' is unavailable in ARC}}
// expected-note@arc-system-header.h:1 {{inline function performs a conversion which is forbidden in ARC}}
// expected-note@arc-system-header.h:5 {{inline function performs a conversion which is forbidden in ARC}}
}
void test3(struct Test3 *p) {
p->field = 0; // expected-error {{'field' is unavailable in ARC}}
// expected-note@arc-system-header.h:14 {{declaration uses type that is ill-formed in ARC}}
}
void test4(Test4 *p) {
p->field1 = 0; // expected-error {{'field1' is unavailable in ARC}}
// expected-note@arc-system-header.h:19 {{declaration uses type that is ill-formed in ARC}}
p->field2 = 0;
}
void test5(struct Test5 *p) {
p->field = 0;
}
id test6() {
// This is actually okay to use if declared in a system header.
id x;
x = (id) kMagicConstant;
x = (id) (x ? kMagicConstant : kMagicConstant);
x = (id) (x ? kMagicConstant : (void*) 0);
extern void test6_helper();
x = (id) (test6_helper(), kMagicConstant);
}
void test7(Test7 *p) {
*p.prop = 0; // expected-error {{'prop' is unavailable in ARC}}
p.prop = 0; // expected-error {{'prop' is unavailable in ARC}}
*[p prop] = 0; // expected-error {{'prop' is unavailable in ARC}}
[p setProp: 0]; // expected-error {{'setProp:' is unavailable in ARC}}
// expected-note@arc-system-header.h:41 4 {{declaration uses type that is ill-formed in ARC}}
// expected-note@arc-system-header.h:41 2 {{property 'prop' is declared unavailable here}}
}
extern void doSomething(Test9 arg);
void test9() {
Test9 foo2 = {0, 0};
doSomething(foo2);
}
#endif
// test8 in header

View File

@ -0,0 +1,98 @@
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -fblocks %s
typedef const void * CFTypeRef;
CFTypeRef CFBridgingRetain(id X);
id CFBridgingRelease(CFTypeRef);
void * cvt(id arg)
{
void* voidp_val;
(void)(int*)arg; // expected-error {{cast of an Objective-C pointer to 'int *' is disallowed with ARC}}
(void)(id)arg;
(void)(__autoreleasing id*)arg; // expected-error {{cast of an Objective-C pointer to '__autoreleasing id *' is disallowed with ARC}}
(void)(id*)arg; // expected-error {{cast of an Objective-C pointer to '__strong id *' is disallowed with ARC}}
(void)(__autoreleasing id**)voidp_val;
(void)(void*)voidp_val;
(void)(void**)arg; // expected-error {{cast of an Objective-C pointer to 'void **' is disallowed with ARC}}
cvt((void*)arg); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} \
// expected-error {{implicit conversion of C pointer type 'void *' to Objective-C pointer type 'id' requires a bridged cast}} \
// expected-note 2 {{use __bridge to convert directly (no change in ownership)}} \
// expected-note {{use CFBridgingRetain call to make an ARC object available as a +1 'void *'}} \
// expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'void *' into ARC}}
cvt(0);
(void)(__strong id**)(0);
return arg; // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
// expected-note {{use CFBridgingRetain call to make an ARC object available as a +1 'void *'}}
}
void to_void(__strong id *sip, __weak id *wip,
__autoreleasing id *aip,
__unsafe_unretained id *uip) {
void *vp1 = sip;
void *vp2 = wip;
void *vp3 = aip;
void *vp4 = uip;
(void)(void*)sip;
(void)(void*)wip;
(void)(void*)aip;
(void)(void*)uip;
(void)(void*)&sip;
(void)(void*)&wip;
(void)(void*)&aip;
(void)(void*)&uip;
}
void from_void(void *vp) {
__strong id *sip = (__strong id *)vp;
__weak id *wip = (__weak id *)vp;
__autoreleasing id *aip = (__autoreleasing id *)vp;
__unsafe_unretained id *uip = (__unsafe_unretained id *)vp;
__strong id **sipp = (__strong id **)vp;
__weak id **wipp = (__weak id **)vp;
__autoreleasing id **aipp = (__autoreleasing id **)vp;
__unsafe_unretained id **uipp = (__unsafe_unretained id **)vp;
sip = vp; // expected-error{{implicit conversion of a non-Objective-C pointer type 'void *' to '__strong id *' is disallowed with ARC}}
wip = vp; // expected-error{{implicit conversion of a non-Objective-C pointer type 'void *' to '__weak id *' is disallowed with ARC}}
aip = vp; // expected-error{{implicit conversion of a non-Objective-C pointer type 'void *' to '__autoreleasing id *' is disallowed with ARC}}
uip = vp; // expected-error{{implicit conversion of a non-Objective-C pointer type 'void *' to '__unsafe_unretained id *' is disallowed with ARC}}
}
typedef void (^Block)();
typedef void (^Block_strong)() __strong;
typedef void (^Block_autoreleasing)() __autoreleasing;
@class NSString;
void ownership_transfer_in_cast(void *vp, Block *pblk) {
__strong NSString **sip = (NSString**)(__strong id *)vp;
__weak NSString **wip = (NSString**)(__weak id *)vp;
__autoreleasing id *aip = (id*)(__autoreleasing id *)vp;
__unsafe_unretained id *uip = (id*)(__unsafe_unretained id *)vp;
__strong id **sipp = (id**)(__strong id **)vp;
__weak id **wipp = (id**)(__weak id **)vp;
__autoreleasing id **aipp = (id**)(__autoreleasing id **)vp;
__unsafe_unretained id **uipp = (id**)(__unsafe_unretained id **)vp;
Block_strong blk_strong1;
Block_strong blk_strong2 = (Block)blk_strong1;
Block_autoreleasing *blk_auto = (Block*)pblk;
id lv;
(void)(id)&lv; // expected-error {{cast of an indirect pointer to an Objective-C pointer to 'id'}}
(void)(id*)lv; // expected-error {{cast of an Objective-C pointer to '__strong id *'}}
(void)(NSString*)&lv; // expected-error {{cast of an indirect pointer to an Objective-C pointer to 'NSString *'}}
(void)(NSString**)lv; // expected-error {{cast of an Objective-C pointer to 'NSString *__strong *'}}
(void)(Block)&lv; // expected-error {{cast of an indirect pointer to an Objective-C pointer to 'Block'}}
(void)(Block*)lv; // expected-error {{cast of an Objective-C pointer to '__strong Block *'}}
}
// <rdar://problem/10486347>
void conversion_in_conditional(id a, void* b) {
id c = 1 ? a : b; // expected-error {{operands to conditional of types 'id' and 'void *' are incompatible in ARC mode}}
id d = 1 ? b : a; // expected-error {{operands to conditional of types 'void *' and 'id' are incompatible in ARC mode}}
}

View File

@ -0,0 +1,95 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-weak -verify -Wno-objc-root-class %s
// rdar://9693477
__attribute__((objc_arc_weak_reference_unavailable))
@interface NSOptOut1072 // expected-note {{class is declared here}}
@end
@interface sub : NSOptOut1072 @end // expected-note 2 {{class is declared here}}
int main() {
__weak sub *w2; // expected-error {{class is incompatible with __weak references}}
__weak NSOptOut1072 *ns1; // expected-error {{class is incompatible with __weak references}}
id obj;
ns1 = (__weak sub *)obj; // expected-error {{assignment of a weak-unavailable object to a __weak object}} \
// expected-error {{class is incompatible with __weak references}} \
// expected-error {{explicit ownership qualifier on cast result has no effect}}
}
// rdar://9732636
__attribute__((objc_arc_weak_reference_unavailable))
@interface NOWEAK
+ (id) new;
@end
NOWEAK * Test1() {
NOWEAK * strong1 = [NOWEAK new];
__weak id weak1;
weak1 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
__weak id weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
return (__weak id)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *' to a __weak object of type '__weak id'}} \
// expected-error {{explicit ownership qualifier on cast result has no effect}}
}
@protocol P @end
@protocol P1 @end
NOWEAK<P, P1> * Test2() {
NOWEAK<P, P1> * strong1 = 0;
__weak id<P> weak1;
weak1 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
__weak id<P> weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
return (__weak id<P>)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK<P,P1> *' to a __weak object of type '__weak id<P>'}} \
// expected-error {{explicit ownership qualifier on cast result has no effect}}
}
// rdar://10535245
__attribute__((objc_arc_weak_reference_unavailable))
@interface NSFont
@end
@interface I
{
}
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}}
@end
@implementation I // expected-note {{when implemented by class I}}
@synthesize font = _font;
@end
// rdar://13676793
@protocol MyProtocol
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}}
@end
@interface I1 <MyProtocol>
@end
@implementation I1 // expected-note {{when implemented by class I1}}
@synthesize font = _font;
@end
@interface Super
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}}
@end
@interface I2 : Super
@end
@implementation I2 // expected-note {{when implemented by class I2}}
@synthesize font = _font;
@end
__attribute__((objc_arc_weak_reference_unavailable(1))) // expected-error {{'objc_arc_weak_reference_unavailable' attribute takes no arguments}}
@interface I3
@end
int I4 __attribute__((objc_arc_weak_reference_unavailable)); // expected-error {{'objc_arc_weak_reference_unavailable' attribute only applies to Objective-C interfaces}}

View File

@ -0,0 +1,13 @@
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin11 -fobjc-arc -verify %s
// rdar://10186625
# 1 "<command line>"
# 1 "/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h" 1 3
id * foo(); // expected-note {{declaration uses type that is ill-formed in ARC}}
# 1 "arc-unavailable-system-function.m" 2
void ret() {
foo(); // expected-error {{'foo' is unavailable in ARC}}
}

View File

@ -0,0 +1,130 @@
// // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s
typedef const struct __CFString * CFStringRef;
typedef const void * CFTypeRef;
CFTypeRef CFBridgingRetain(id X);
id CFBridgingRelease(CFTypeRef);
@interface Object
@property CFStringRef property;
- (CFStringRef) implicitProperty;
- (CFStringRef) newString;
- (CFStringRef) makeString;
@end
extern Object *object;
// rdar://9744349
id test0(void) {
id p1 = (id)[object property];
id p2 = (__bridge_transfer id)[object property];
id p3 = (__bridge id)[object property];
return (id) object.property;
}
// rdar://10140692
CFStringRef unauditedString(void);
CFStringRef plusOneString(void) __attribute__((cf_returns_retained));
#pragma clang arc_cf_code_audited begin
CFStringRef auditedString(void);
CFStringRef auditedCreateString(void);
#pragma clang arc_cf_code_audited end
extern const CFStringRef kUserConst;
void test1(int cond) {
id x;
x = (id) auditedString();
x = (id) kUserConst;
x = (id) (cond ? auditedString() : (void*) 0);
x = (id) (cond ? (void*) 0 : auditedString());
x = (id) (cond ? (CFStringRef) @"help" : auditedString());
x = (id) (cond ? (CFStringRef) @"help" : kUserConst);
x = (id) unauditedString(); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
x = (id) (cond ? unauditedString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
x = (id) (cond ? unauditedString() : kUserConst); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
x = (id) (cond ? (void*) 0 : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
x = (id) (cond ? (CFStringRef) @"help" : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
x = (id) [object property];
x = (id) (cond ? [object property] : (void*) 0);
x = (id) (cond ? (void*) 0 : [object property]);
x = (id) (cond ? (CFStringRef) @"help" : [object property]);
x = (id) object.property;
x = (id) (cond ? object.property : (void*) 0);
x = (id) (cond ? (void*) 0 : object.property);
x = (id) (cond ? (CFStringRef) @"help" : object.property);
x = (id) object.implicitProperty;
x = (id) (cond ? object.implicitProperty : (void*) 0);
x = (id) (cond ? (void*) 0 : object.implicitProperty);
x = (id) (cond ? (CFStringRef) @"help" : object.implicitProperty);
x = (id) [object makeString];
x = (id) (cond ? [object makeString] : (void*) 0);
x = (id) (cond ? (void*) 0 : [object makeString]);
x = (id) (cond ? (CFStringRef) @"help" : [object makeString]);
x = (id) (cond ? kUserConst : [object makeString]);
x = (id) [object newString];
x = (id) (cond ? [object newString] : (void*) 0);
x = (id) (cond ? (void*) 0 : [object newString]);
x = (id) (cond ? (CFStringRef) @"help" : [object newString]); // a bit questionable
x = (id) (cond ? kUserConst : [object newString]); // expected-error{{requires a bridged cast}} expected-note{{use __bridge to}} expected-note{{use CFBridgingRelease call to}}
}
// rdar://problem/10246264
@interface CFTaker
- (void) takeOrdinary: (CFStringRef) arg;
- (void) takeVariadic: (int) n, ...;
- (void) takeConsumed: (CFStringRef __attribute__((cf_consumed))) arg;
@end
void testCFTaker(CFTaker *taker, id string) {
[taker takeOrdinary: (CFStringRef) string];
[taker takeVariadic: 1, (CFStringRef) string];
[taker takeConsumed: (CFStringRef) string]; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
}
void takeCFOrdinaryUnaudited(CFStringRef arg);
void takeCFVariadicUnaudited(int n, ...);
void takeCFConsumedUnaudited(CFStringRef __attribute__((cf_consumed)) arg);
#pragma clang arc_cf_code_audited begin
void takeCFOrdinaryAudited(CFStringRef arg);
void takeCFVariadicAudited(int n, ...);
void takeCFConsumedAudited(CFStringRef __attribute__((cf_consumed)) arg);
#pragma clang arc_cf_code_audited end
void testTakerFunctions(id string) {
takeCFOrdinaryUnaudited((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
takeCFVariadicUnaudited(1, (CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
takeCFConsumedUnaudited((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
void (*taker)(CFStringRef) = 0;
taker((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
takeCFOrdinaryAudited((CFStringRef) string);
takeCFVariadicAudited(1, (CFStringRef) string);
takeCFConsumedAudited((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
}
void testTakerFunctions_parens(id string) {
takeCFOrdinaryUnaudited(((CFStringRef) string)); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
takeCFVariadicUnaudited(1, ((CFStringRef) string)); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
takeCFConsumedUnaudited(((CFStringRef) string)); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
void (*taker)(CFStringRef) = 0;
taker(((CFStringRef) string)); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
takeCFOrdinaryAudited(((CFStringRef) string));
takeCFVariadicAudited(1, ((CFStringRef) string));
takeCFConsumedAudited(((CFStringRef) string)); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
}

View File

@ -0,0 +1,41 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s
// rdar://9495837
@interface Foo {
__unsafe_unretained id unsafe_ivar;
}
@property (assign,nonatomic) id unsafe_prop;
- (id)init;
+ (id)new;
+ (id)alloc;
-(void)Meth;
@end
@implementation Foo
@synthesize unsafe_prop;
-(id)init { return self; }
+(id)new { return 0; }
+(id)alloc { return 0; }
-(void)Meth {
self.unsafe_prop = [Foo new]; // expected-warning {{assigning retained object to unsafe property}}
self->unsafe_ivar = [Foo new]; // expected-warning {{assigning retained object to unsafe_unretained}}
self.unsafe_prop = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe property}}
self->unsafe_ivar = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe_unretained}}
__unsafe_unretained id unsafe_var;
unsafe_var = [Foo new]; // expected-warning {{assigning retained object to unsafe_unretained}}
unsafe_var = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe_unretained}}
}
@end
void bar(Foo *f) {
f.unsafe_prop = [Foo new]; // expected-warning {{assigning retained object to unsafe property}}
__unsafe_unretained id unsafe_var;
unsafe_var = [Foo new]; // expected-warning {{assigning retained object to unsafe_unretained}}
unsafe_var = [[Foo alloc] init]; // expected-warning {{assigning retained object to unsafe_unretained}}
}

View File

@ -0,0 +1,13 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks %s
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fobjc-arc %s
// expected-no-diagnostics
struct X {
__unsafe_unretained id object;
int (^ __unsafe_unretained block)(int, int);
};
void f(struct X x) {
x.object = 0;
x.block = ^(int x, int y) { return x + y; };
}

853
examples/SemaObjC/arc.m Normal file
View File

@ -0,0 +1,853 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-pointer-to-int-cast -Wno-objc-root-class %s
// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -Wno-pointer-to-int-cast -Wno-objc-root-class -fdiagnostics-parseable-fixits %s 2>&1
typedef unsigned long NSUInteger;
typedef const void * CFTypeRef;
CFTypeRef CFBridgingRetain(id X);
id CFBridgingRelease(CFTypeRef);
@protocol NSCopying @end
@interface NSDictionary
+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
- (void)setObject:(id)object forKeyedSubscript:(id)key;
@end
@class NSFastEnumerationState;
@protocol NSFastEnumeration
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len;
@end
@interface NSNumber
+ (NSNumber *)numberWithInt:(int)value;
@end
@interface NSArray <NSFastEnumeration>
+ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
@end
void test0(void (*fn)(int), int val) {
fn(val);
}
@interface A
- (id)retain;
- (id)autorelease;
- (oneway void)release;
- (void)dealloc;
- (NSUInteger)retainCount;
@end
void test1(A *a) {
SEL s = @selector(retain); // expected-error {{ARC forbids use of 'retain' in a @selector}}
s = @selector(release); // expected-error {{ARC forbids use of 'release' in a @selector}}
s = @selector(autorelease); // expected-error {{ARC forbids use of 'autorelease' in a @selector}}
s = @selector(dealloc); // expected-error {{ARC forbids use of 'dealloc' in a @selector}}
[a dealloc]; // expected-error {{ARC forbids explicit message send of 'dealloc'}}
[a retain]; // expected-error {{ARC forbids explicit message send of 'retain'}}
[a retainCount]; // expected-error {{ARC forbids explicit message send of 'retainCount'}}
[a release]; // expected-error {{ARC forbids explicit message send of 'release'}}
[a autorelease]; // expected-error {{ARC forbids explicit message send of 'autorelease'}}
}
@interface Test2 : A
- (void) dealloc;
@end
@implementation Test2
- (void) dealloc {
// This should maybe just be ignored. We're just going to warn about it for now.
[super dealloc]; // expected-error {{ARC forbids explicit message send of 'dealloc'}}
}
@end
// rdar://8843638
@interface I
- (id)retain; // expected-note {{method 'retain' declared here}}
- (id)autorelease; // expected-note {{method 'autorelease' declared here}}
- (oneway void)release; // expected-note {{method 'release' declared here}}
- (NSUInteger)retainCount; // expected-note {{method 'retainCount' declared here}}
@end
@implementation I
- (id)retain{return 0;} // expected-error {{ARC forbids implementation of 'retain'}}
- (id)autorelease{return 0;} // expected-error {{ARC forbids implementation of 'autorelease'}}
- (oneway void)release{} // expected-error {{ARC forbids implementation of 'release'}}
- (NSUInteger)retainCount{ return 0; } // expected-error {{ARC forbids implementation of 'retainCount'}}
@end
@implementation I(CAT)
- (id)retain{return 0;} // expected-error {{ARC forbids implementation of 'retain'}} \
// expected-warning {{category is implementing a method which will also be implemented by its primary class}}
- (id)autorelease{return 0;} // expected-error {{ARC forbids implementation of 'autorelease'}} \
// expected-warning {{category is implementing a method which will also be implemented by its primary class}}
- (oneway void)release{} // expected-error {{ARC forbids implementation of 'release'}} \
// expected-warning {{category is implementing a method which will also be implemented by its primary class}}
- (NSUInteger)retainCount{ return 0; } // expected-error {{ARC forbids implementation of 'retainCount'}} \
// expected-warning {{category is implementing a method which will also be implemented by its primary class}}
@end
// rdar://8861761
@interface B
+ (id)alloc;
- (id)initWithInt: (int) i;
- (id)myInit __attribute__((objc_method_family(init)));
- (id)myBadInit __attribute__((objc_method_family(12))); // expected-error {{'objc_method_family' attribute requires parameter 1 to be an identifier}}
@end
void rdar8861761() {
B *o1 = [[B alloc] initWithInt:0];
B *o2 = [B alloc];
[o2 initWithInt:0]; // expected-warning {{expression result unused}}
B *o3 = [[B alloc] myInit];
[[B alloc] myInit]; // expected-warning {{expression result unused}}
}
// rdar://8925835
@interface rdar8925835
- (void)foo:(void (^)(unsigned captureCount, I * const capturedStrings[captureCount]))block;
@end
void test5() {
extern void test5_helper(__autoreleasing id *);
id x;
// Okay because of magic temporaries.
test5_helper(&x);
__autoreleasing id *a = &x; // expected-error {{initializing '__autoreleasing id *' with an expression of type '__strong id *' changes retain/release properties of pointer}}
__autoreleasing id *aa;
aa = &x; // expected-error {{assigning '__strong id *' to '__autoreleasing id *' changes retain/release properties of pointer}}
extern void test5_helper2(id const *);
test5_helper2(&x);
extern void test5_helper3(__weak id *); // expected-note {{passing argument to parameter here}}
test5_helper3(&x); // expected-error {{passing '__strong id *' to parameter of type '__weak id *' changes retain/release properties of pointer}}
}
// rdar://problem/8937869
void test6(unsigned cond) {
switch (cond) {
case 0:
;
id x; // expected-note {{jump bypasses initialization of __strong variable}}
case 1: // expected-error {{cannot jump}}
break;
}
}
void test6a(unsigned cond) {
switch (cond) {
case 0:
;
__weak id x; // expected-note {{jump bypasses initialization of __weak variable}}
case 1: // expected-error {{cannot jump}}
break;
}
}
@class NSError;
void test7(void) {
extern void test7_helper(NSError **);
NSError *err;
test7_helper(&err);
}
void test7_weak(void) {
extern void test7_helper(NSError **);
__weak NSError *err;
test7_helper(&err);
}
void test7_unsafe(void) {
extern void test7_helper(NSError **); // expected-note {{passing argument to parameter here}}
__unsafe_unretained NSError *err;
test7_helper(&err); // expected-error {{passing 'NSError *__unsafe_unretained *' to parameter of type 'NSError *__autoreleasing *' changes retain/release properties of pointer}}
}
@class Test8_incomplete;
@interface Test8_complete @end;
@interface Test8_super @end;
@interface Test8 : Test8_super
- (id) init00;
- (id) init01; // expected-note {{declaration in interface}} \
// expected-note{{overridden method}}
- (id) init02; // expected-note{{overridden method}}
- (id) init03; // covariance
- (id) init04; // covariance
- (id) init05; // expected-note{{overridden method}}
- (void) init10; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}}
- (void) init11;
- (void) init12;
- (void) init13; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}}
- (void) init14; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}}
- (void) init15;
// These should be invalid to actually call.
- (Test8_incomplete*) init20;
- (Test8_incomplete*) init21; // expected-note {{declaration in interface}}
- (Test8_incomplete*) init22;
- (Test8_incomplete*) init23;
- (Test8_incomplete*) init24;
- (Test8_incomplete*) init25;
- (Test8_super*) init30; // id exception to covariance
- (Test8_super*) init31; // expected-note {{declaration in interface}} \
// expected-note{{overridden method}}
- (Test8_super*) init32; // expected-note{{overridden method}}
- (Test8_super*) init33;
- (Test8_super*) init34; // covariance
- (Test8_super*) init35; // expected-note{{overridden method}}
- (Test8*) init40; // id exception to covariance
- (Test8*) init41; // expected-note {{declaration in interface}} \
// expected-note{{overridden method}}
- (Test8*) init42; // expected-note{{overridden method}}
- (Test8*) init43; // this should be a warning, but that's a general language thing, not an ARC thing
- (Test8*) init44;
- (Test8*) init45; // expected-note{{overridden method}}
- (Test8_complete*) init50; // expected-error {{init methods must return a type related to the receiver type}}
- (Test8_complete*) init51; // expected-error {{init methods must return a type related to the receiver type}}
- (Test8_complete*) init52; // expected-error {{init methods must return a type related to the receiver type}}
- (Test8_complete*) init53; // expected-error {{init methods must return a type related to the receiver type}}
- (Test8_complete*) init54; // expected-error {{init methods must return a type related to the receiver type}}
- (Test8_complete*) init55; // expected-error {{init methods must return a type related to the receiver type}}
@end
@implementation Test8
- (id) init00 { return 0; }
- (id) init10 { return 0; } // expected-error {{method implementation does not match its declaration}}
- (id) init20 { return 0; }
- (id) init30 { return 0; }
- (id) init40 { return 0; }
- (id) init50 { return 0; }
- (void) init01 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} \
// expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'void'}}
- (void) init11 {}
- (void) init21 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}}
- (void) init31 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} \
// expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'void'}}
- (void) init41 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} \
// expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'void'}}
- (void) init51 {}
- (Test8_incomplete*) init02 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \
// expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_incomplete *'}}
- (Test8_incomplete*) init12 { return 0; } // expected-error {{init methods must return a type related to the receiver type}}
- (Test8_incomplete*) init22 { return 0; } // expected-error {{init methods must return a type related to the receiver type}}
- (Test8_incomplete*) init32 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \
// expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_incomplete *'}}
- (Test8_incomplete*) init42 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \
// expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_incomplete *'}}
- (Test8_incomplete*) init52 { return 0; } // expected-error {{init methods must return a type related to the receiver type}}
- (Test8_super*) init03 { return 0; }
- (Test8_super*) init13 { return 0; } // expected-error {{method implementation does not match its declaration}}
- (Test8_super*) init23 { return 0; }
- (Test8_super*) init33 { return 0; }
- (Test8_super*) init43 { return 0; }
- (Test8_super*) init53 { return 0; }
- (Test8*) init04 { return 0; }
- (Test8*) init14 { return 0; } // expected-error {{method implementation does not match its declaration}}
- (Test8*) init24 { return 0; }
- (Test8*) init34 { return 0; }
- (Test8*) init44 { return 0; }
- (Test8*) init54 { return 0; }
- (Test8_complete*) init05 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \
// expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_complete *'}}
- (Test8_complete*) init15 { return 0; } // expected-error {{init methods must return a type related to the receiver type}}
- (Test8_complete*) init25 { return 0; } // expected-error {{init methods must return a type related to the receiver type}}
- (Test8_complete*) init35 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \
// expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_complete *'}}
- (Test8_complete*) init45 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \
// expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_complete *'}}
- (Test8_complete*) init55 { return 0; } // expected-error {{init methods must return a type related to the receiver type}}
@end
@class Test9_incomplete;
@interface Test9
- (Test9_incomplete*) init1; // expected-error {{init methods must return a type related to the receiver type}}
- (Test9_incomplete*) init2;
@end
id test9(Test9 *v) {
return [v init1];
}
// Test that the inference rules are different for fast enumeration variables.
void test10(id collection) {
for (id x in collection) {
__strong id *ptr = &x; // expected-warning {{initializing '__strong id *' with an expression of type 'const __strong id *' discards qualifiers}}
}
for (__strong id x in collection) {
__weak id *ptr = &x; // expected-error {{initializing '__weak id *' with an expression of type '__strong id *' changes retain/release properties of pointer}}
}
}
// rdar://problem/9078626
#define nil ((void*) 0)
void test11(id op, void *vp) {
_Bool b;
b = (op == nil);
b = (nil == op);
b = (vp == nil);
b = (nil == vp);
// FIXME: Shouldn't these be consistent?
b = (vp == op); // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}}
b = (op == vp);
}
void test12(id collection) {
for (id x in collection) {
x = 0; // expected-error {{fast enumeration variables cannot be modified in ARC by default; declare the variable __strong to allow this}}
}
for (const id x in collection) { // expected-note {{variable 'x' declared const here}}
x = 0; // expected-error {{cannot assign to variable 'x' with const-qualified type 'const __strong id'}}
}
for (__strong id x in collection) {
x = 0;
}
}
@interface Test13
- (id) init0;
- (void) noninit;
@end
@implementation Test13
- (id) init0 {
self = 0;
}
- (void) noninit {
self = 0; // expected-error {{cannot assign to 'self' outside of a method in the init family}}
}
@end
// <rdar://problem/10274056>
@interface Test13_B
- (id) consumesSelf __attribute__((ns_consumes_self));
@end
@implementation Test13_B
- (id) consumesSelf {
self = 0; // no-warning
}
@end
// rdar://problem/9172151
@class Test14A, Test14B;
void test14() {
extern void test14_consume(id *);
extern int test14_cond(void);
extern float test14_nowriteback(id __autoreleasing const *); // expected-note{{passing argument to parameter here}}
Test14A *a;
Test14B *b;
id i;
id cla[10];
id vla[test14_cond() + 10];
test14_consume((__strong id*) &a);
test14_consume((test14_cond() ? (__strong id*) &b : &i));
test14_consume(test14_cond() ? 0 : &a);
test14_consume(test14_cond() ? (void*) 0 : (&a));
test14_consume(cla); // expected-error {{passing address of non-scalar object to __autoreleasing parameter for write-back}}
test14_consume(vla); // expected-error {{passing address of non-scalar object to __autoreleasing parameter for write-back}}
test14_consume(&cla[5]); // expected-error {{passing address of non-scalar object to __autoreleasing parameter for write-back}}
__strong id *test14_indirect(void);
test14_consume(test14_indirect()); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}}
extern id test14_global;
test14_consume(&test14_global); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}}
extern __strong id *test14_global_ptr;
test14_consume(test14_global_ptr); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}}
static id static_local;
test14_consume(&static_local); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}}
__weak id* wip;
test14_nowriteback(&static_local); // okay, not a write-back.
test14_nowriteback(wip); // expected-error{{passing '__weak id *' to parameter of type '__autoreleasing id const *' changes retain/release properties of pointer}}
}
void test15() {
__block __autoreleasing id x; // expected-error {{__block variables cannot have __autoreleasing ownership}}
}
struct Test16;
@interface Test16a
- (void) test16_0: (int) x;
- (int) test16_1: (int) x; // expected-note {{one possibility}}
- (int) test16_2: (int) x; // expected-note {{one possibility}}
- (id) test16_3: (int) x __attribute__((ns_returns_retained)); // expected-note {{one possibility}}
- (void) test16_4: (int) x __attribute__((ns_consumes_self)); // expected-note {{one possibility}}
- (void) test16_5: (id) __attribute__((ns_consumed)) x; // expected-note {{one possibility}}
- (void) test16_6: (id) x;
@end
@interface Test16b
- (void) test16_0: (int) x;
- (int) test16_1: (char*) x; // expected-note {{also found}}
- (char*) test16_2: (int) x; // expected-note {{also found}}
- (id) test16_3: (int) x; // expected-note {{also found}}
- (void) test16_4: (int) x; // expected-note {{also found}}
- (void) test16_5: (id) x; // expected-note {{also found}}
- (void) test16_6: (struct Test16 *) x;
@end
void test16(void) {
id v;
[v test16_0: 0];
[v test16_1: 0]; // expected-error {{multiple methods named 'test16_1:' found with mismatched result, parameter type or attributes}}
[v test16_2: 0]; // expected-error {{multiple methods named}}
[v test16_3: 0]; // expected-error {{multiple methods named}}
[v test16_4: 0]; // expected-error {{multiple methods named}}
[v test16_5: 0]; // expected-error {{multiple methods named}}
[v test16_6: 0];
}
@class Test17; // expected-note 3{{forward declaration of class here}}
@protocol Test17p
- (void) test17;
+ (void) test17;
@end
void test17(void) {
Test17 *v0;
[v0 test17]; // expected-error {{receiver type 'Test17' for instance message is a forward declaration}}
Test17<Test17p> *v1;
[v1 test17]; // expected-error {{receiver type 'Test17<Test17p>' for instance message is a forward declaration}}
[Test17 test17]; // expected-error {{receiver 'Test17' for class message is a forward declaration}}
}
void test18(void) {
id x;
[x test18]; // expected-error {{instance method 'test18' not found ; did you mean 'test17'?}}
}
extern struct Test19 *test19a;
struct Test19 *const test19b = 0;
void test19(void) {
id x;
x = (id) test19a; // expected-error {{bridged cast}} \
// expected-note{{use __bridge to convert directly (no change in ownership)}} \
// expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'struct Test19 *' into ARC}}
x = (id) test19b; // expected-error {{bridged cast}} \
// expected-note{{use __bridge to convert directly (no change in ownership)}} \
// expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'struct Test19 *' into ARC}}
}
// rdar://problem/8951453
static __thread id test20_implicit; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}}
static __thread __strong id test20_strong; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}}
static __thread __weak id test20_weak; // expected-error {{thread-local variable has non-trivial ownership: type is '__weak id'}}
static __thread __autoreleasing id test20_autoreleasing; // expected-error {{thread-local variable has non-trivial ownership: type is '__autoreleasing id'}} expected-error {{global variables cannot have __autoreleasing ownership}}
static __thread __unsafe_unretained id test20_unsafe;
void test20(void) {
static __thread id test20_implicit; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}}
static __thread __strong id test20_strong; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}}
static __thread __weak id test20_weak; // expected-error {{thread-local variable has non-trivial ownership: type is '__weak id'}}
static __thread __autoreleasing id test20_autoreleasing; // expected-error {{thread-local variable has non-trivial ownership: type is '__autoreleasing id'}} expected-error {{global variables cannot have __autoreleasing ownership}}
static __thread __unsafe_unretained id test20_unsafe;
}
// rdar://9310049
_Bool fn(id obj) {
return (_Bool)obj;
}
// Check casting w/ ownership qualifiers.
void test21() {
__strong id *sip;
(void)(__weak id *)sip; // expected-error{{casting '__strong id *' to type '__weak id *' changes retain/release properties of pointer}}
(void)(__weak const id *)sip; // expected-error{{casting '__strong id *' to type '__weak id const *' changes retain/release properties of pointer}}
(void)(__autoreleasing id *)sip; // expected-error{{casting '__strong id *' to type '__autoreleasing id *' changes retain/release properties of pointer}}
(void)(__autoreleasing const id *)sip; // okay
}
// rdar://problem/9340462
void test22(id x[]) { // expected-error {{must explicitly describe intended ownership of an object array parameter}}
}
// rdar://problem/9400219
void test23(void) {
void *ptr;
ptr = @"foo";
ptr = (ptr ? @"foo" : 0);
ptr = (ptr ? @"foo" : @"bar");
}
id test24(void) {
extern void test24_helper(void);
return test24_helper(), (void*) 0;
}
// rdar://9400841
@interface Base
@property (assign) id content;
@end
@interface Foo : Base
-(void)test;
@end
@implementation Foo
-(void)test {
super.content = 0;
}
@end
// <rdar://problem/9398437>
void test25(Class *classes) {
Class *other_classes;
test25(other_classes);
}
void test26(id y) {
extern id test26_var1;
__sync_swap(&test26_var1, 0, y); // expected-error {{cannot perform atomic operation on a pointer to type '__strong id': type has non-trivial ownership}}
extern __unsafe_unretained id test26_var2;
__sync_swap(&test26_var2, 0, y);
}
@interface Test26
- (id) init;
- (id) initWithInt: (int) x;
@end
@implementation Test26
- (id) init { return self; }
- (id) initWithInt: (int) x {
[self init]; // expected-error {{the result of a delegate init call must be immediately returned or assigned to 'self'}}
return self;
}
@end
// rdar://9525555
@interface Test27 {
__weak id _myProp1;
id myProp2;
}
@property id x;
@property (readonly) id ro;
@property (readonly) id custom_ro;
@property int y;
@property (readonly) __weak id myProp1;
@property (readonly) id myProp2;
@property (readonly) __strong id myProp3;
@end
@implementation Test27
@synthesize x;
@synthesize ro;
@synthesize y;
@synthesize myProp1 = _myProp1;
@synthesize myProp2;
@synthesize myProp3;
-(id)custom_ro { return 0; }
@end
// rdar://9569264
@interface Test28
@property (nonatomic, assign) __strong id a; // expected-error {{unsafe_unretained property 'a' may not also be declared __strong}}
@end
@interface Test28 ()
@property (nonatomic, assign) __strong id b; // expected-error {{unsafe_unretained property 'b' may not also be declared __strong}}
@end
@implementation Test28
@synthesize a;
@synthesize b;
@end
// rdar://9573962
typedef struct Bark Bark;
@interface Test29
@property Bark* P;
@end
@implementation Test29
@synthesize P;
- (id)Meth {
Bark** f = &P;
return 0;
}
@end
// rdar://9495837
@interface Test30
+ (id) new;
- (void)Meth;
@end
@implementation Test30
+ (id) new { return 0; }
- (void) Meth {
__weak id x = [Test30 new]; // expected-warning {{assigning retained object to weak variable}}
id __unsafe_unretained u = [Test30 new]; // expected-warning {{assigning retained object to unsafe_unretained variable}}
id y = [Test30 new];
x = [Test30 new]; // expected-warning {{assigning retained object to weak variable}}
u = [Test30 new]; // expected-warning {{assigning retained object to unsafe_unretained variable}}
y = [Test30 new];
}
@end
// rdar://9411838
@protocol PTest31 @end
int Test31() {
Class cls;
id ids;
id<PTest31> pids;
Class<PTest31> pcls;
int i = (ids->isa ? 1 : 0); // expected-error {{member reference base type 'id' is not a structure or union}}
int j = (pids->isa ? 1 : 0); // expected-error {{member reference base type 'id<PTest31>' is not a structure or union}}
int k = (pcls->isa ? i : j); // expected-error {{member reference base type 'Class<PTest31>' is not a structure or union}}
return cls->isa ? i : j; // expected-error {{member reference base type 'Class' is not a structure or union}}
}
// rdar://9612030
@interface ITest32 {
@public
id ivar;
}
@end
id Test32(__weak ITest32 *x) {
__weak ITest32 *y;
x->ivar = 0; // expected-error {{dereferencing a __weak pointer is not allowed}}
return y ? y->ivar // expected-error {{dereferencing a __weak pointer is not allowed}}
: (*x).ivar; // expected-error {{dereferencing a __weak pointer is not allowed}}
}
// rdar://9619861
extern int printf(const char*, ...);
typedef long intptr_t;
int Test33(id someid) {
printf( "Hello%ld", (intptr_t)someid);
return (int)someid;
}
// rdar://9636091
@interface I34
@property (nonatomic, retain) id newName __attribute__((ns_returns_not_retained)) ;
@property (nonatomic, retain) id newName1 __attribute__((ns_returns_not_retained)) ;
- (id) newName1 __attribute__((ns_returns_not_retained));
@property (nonatomic, retain) id newName2 __attribute__((ns_returns_not_retained)); // expected-note {{roperty declared here}}
- (id) newName2; // expected-warning {{property declared as returning non-retained objects; getter returning retained objects}}
@end
@implementation I34
@synthesize newName;
@synthesize newName1;
- (id) newName1 { return 0; }
@synthesize newName2;
@end
void test35(void) {
extern void test36_helper(id*);
id x;
__strong id *xp = 0;
test36_helper(&x);
test36_helper(xp); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}}
// rdar://problem/9665710
__block id y;
test36_helper(&y);
^{ test36_helper(&y); }();
__strong int non_objc_type; // expected-warning {{'__strong' only applies to Objective-C object or block pointer types}}
}
void test36(int first, ...) {
// <rdar://problem/9758798>
__builtin_va_list arglist;
__builtin_va_start(arglist, first);
id obj = __builtin_va_arg(arglist, id);
__builtin_va_end(arglist);
}
@class Test37; // expected-note{{forward declaration of class here}}
void test37(Test37 *c) {
for (id y in c) { // expected-error {{collection expression type 'Test37' is a forward declaration}}
(void) y;
}
(void)sizeof(id*); // no error.
}
// rdar://problem/9887979
@interface Test38
@property int value;
@end
void test38() {
extern Test38 *test38_helper(void);
switch (test38_helper().value) {
case 0:
case 1:
;
}
}
// rdar://10186536
@class NSColor;
void _NSCalc(NSColor* color, NSColor* bezelColors[]) __attribute__((unavailable("not available in automatic reference counting mode")));
void _NSCalcBeze(NSColor* color, NSColor* bezelColors[]); // expected-error {{must explicitly describe intended ownership of an object array parameter}}
// rdar://9970739
@interface RestaurantTableViewCell
- (void) restaurantLocation;
@end
@interface Radar9970739
- (void) Meth;
@end
@implementation Radar9970739
- (void) Meth {
RestaurantTableViewCell *cell;
[cell restaurantLocatoin]; // expected-error {{no visible @interface for 'RestaurantTableViewCell' declares the selector 'restaurantLocatoin'}}
}
@end
// rdar://11814185
@interface Radar11814185
@property (nonatomic, weak) Radar11814185* picker1;
+ alloc;
- init;
@end
@implementation Radar11814185
@synthesize picker1;
- (void)viewDidLoad
{
picker1 = [[Radar11814185 alloc] init]; // expected-warning {{assigning retained object to weak variable; object will be released after assignment}}
self.picker1 = [[Radar11814185 alloc] init]; // expected-warning {{assigning retained object to weak property; object will be released after assignment}}
}
+ alloc { return 0; }
- init { return 0; }
@end
// <rdar://problem/12569201>. Warn on cases of initializing a weak variable
// with an Objective-C object literal.
void rdar12569201(id key, id value) {
// Declarations.
__weak id x = @"foo"; // no-warning
__weak id y = @{ key : value }; // expected-warning {{assigning dictionary literal to a weak variable; object will be released after assignment}}
__weak id z = @[ value ]; // expected-warning {{assigning array literal to a weak variable; object will be released after assignment}}
__weak id b = ^() {}; // expected-warning {{assigning block literal to a weak variable; object will be released after assignment}}
__weak id n = @42; // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}}
__weak id e = @(42); // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}}
__weak id m = @(41 + 1); // expected-warning {{assigning boxed expression to a weak variable; object will be released after assignment}}
// Assignments.
y = @{ key : value }; // expected-warning {{assigning dictionary literal to a weak variable; object will be released after assignment}}
z = @[ value ]; // expected-warning {{assigning array literal to a weak variable; object will be released after assignment}}
b = ^() {}; // expected-warning {{assigning block literal to a weak variable; object will be released after assignment}}
n = @42; // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}}
e = @(42); // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}}
m = @(41 + 1); // expected-warning {{assigning boxed expression to a weak variable; object will be released after assignment}}
}
@interface C
- (void)method:(id[])objects; // expected-error{{must explicitly describe intended ownership of an object array parameter}}
@end
// rdar://13752880
@interface NSMutableArray : NSArray @end
typedef __strong NSMutableArray * PSNS;
void test(NSArray *x) {
NSMutableArray *y = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}}
__strong NSMutableArray *y1 = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}}
PSNS y2 = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}}
}
// rdar://15123684
@class NSString;
void foo(NSArray *array) {
for (NSString *string in array) {
for (string in @[@"blah", @"more blah", string]) { // expected-error {{selector element of type 'NSString *const __strong' cannot be a constant lvalue}}
}
}
}
// rdar://16627903
extern void abort();
#define TKAssertEqual(a, b) do{\
__typeof(a) a_res = (a);\
__typeof(b) b_res = (b);\
if ((a_res) != (b_res)) {\
abort();\
}\
}while(0)
int garf() {
id object;
TKAssertEqual(object, nil);
TKAssertEqual(object, (id)nil);
}
void block_capture_autoreleasing(A * __autoreleasing *a,
A **b, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
A * _Nullable *c, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
A * _Nullable __autoreleasing *d,
A ** _Nullable e, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
A * __autoreleasing * _Nullable f,
id __autoreleasing *g,
id *h, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
id _Nullable *i, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
id _Nullable __autoreleasing *j,
id * _Nullable k, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
id __autoreleasing * _Nullable l) {
^{
(void)*a;
(void)*b; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
(void)*c; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
(void)*d;
(void)*e; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
(void)*f;
(void)*g;
(void)*h; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
(void)*i; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
(void)*j;
(void)*k; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
(void)*l;
}();
}
void test_vla_fold_keeps_strong(void) {
const unsigned bounds = 1;
static id array[bounds]; // expected-warning {{variable length array folded to constant array as an extension}}
typedef __typeof__(array) array_type;
typedef id __strong array_type[1];
static id weak_array[bounds] __weak; // expected-warning {{variable length array folded to constant array as an extension}}
typedef __typeof__(weak_array) weak_array_type;
typedef id __weak weak_array_type[1];
}

View File

@ -0,0 +1,26 @@
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
struct S { int a; };
extern int charStarFunc(char *); // expected-note{{passing argument to parameter here}}
extern int charFunc(char); // expected-note{{passing argument to parameter here}}
@interface Test
+alloc;
-(int)charStarMeth:(char *)s; // expected-note{{passing argument to parameter 's' here}}
-structMeth:(struct S)s; // expected-note{{passing argument to parameter 's' here}}
-structMeth:(struct S)s
:(struct S)s2; // expected-note{{passing argument to parameter 's2' here}}
@end
void test() {
id obj = [Test alloc];
struct S sInst;
charStarFunc(1); // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'char *'}}
charFunc("abc"); // expected-warning {{incompatible pointer to integer conversion passing 'char [4]' to parameter of type 'char'}}
[obj charStarMeth:1]; // expected-warning {{incompatible integer to pointer conversion sending 'int'}}
[obj structMeth:1]; // expected-error {{sending 'int'}}
[obj structMeth:sInst :1]; // expected-error {{sending 'int'}}
}

View File

@ -0,0 +1,25 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -Wno-objc-root-class %s
// RUN: %clang_cc1 -std=c++98 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -Wno-objc-root-class %s
// RUN: %clang_cc1 -std=c++11 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -Wno-objc-root-class %s
// rdar://9005189
@interface Foo
@end
struct Bar {
int x;
};
@implementation Foo {
struct Bar bar;
}
- (const struct Bar)bar {
return bar;
}
- (void)baz {
bar.x = 0;
[self bar].x = 10; // expected-error-re {{{{assigning to 'readonly' return result of an Objective-C message not allowed|expression is not assignable}}}}
}
@end

View File

@ -0,0 +1,29 @@
// RUN: %clang_cc1 -triple i386-unknown-unknown -fobjc-runtime=macosx-fragile-10.5 %s -fsyntax-only
@interface Test {
double a;
}
@end
@implementation Test
@end
@interface TestObject : Test {
@public
float bar;
int foo;
}
@end
@implementation TestObject
@end
struct wibble {
@defs(TestObject)
};
int main(void)
{
TestObject * a = (id)malloc(100);
a->foo = 12;
printf("12: %d\n", ((struct wibble*)a)->foo);
printf("%d: %d\n", ((char*)&(((struct wibble*)a)->foo)) - (char*)a, ((char*)&(a->foo)) - (char*)a);
return 0;
}

View File

@ -0,0 +1,377 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
/*
Conditions for warning:
1. the property is atomic
2. the current @implementation contains an @synthesize for the property
3. the current @implementation contains a hand-written setter XOR getter
4. the property is read-write
Cases marked WARN should warn one the following:
warning: Atomic property 'x' has a synthesized setter and a
manually-implemented getter, which may break atomicity.
warning: Atomic property 'x' has a synthesized getter and a
manually-implemented setter, which may break atomicity.
Cases not marked WARN only satisfy the indicated subset
of the conditions required to warn.
There should be 8 warnings.
*/
@interface Foo
{
/* 12 4 */ int GetSet;
/* WARN */ int Get;
/* WARN */ int Set;
/* 12 4 */ int None;
/* 2 4 */ int GetSet_Nonatomic;
/* 234 */ int Get_Nonatomic;
/* 234 */ int Set_Nonatomic;
/* 2 4 */ int None_Nonatomic;
/* 12 */ int GetSet_ReadOnly;
/* 123 */ int Get_ReadOnly;
/* 123 */ int Set_ReadOnly;
/* 12 */ int None_ReadOnly;
/* 2 */ int GetSet_Nonatomic_ReadOnly;
/* 23 */ int Get_Nonatomic_ReadOnly;
/* 23 */ int Set_Nonatomic_ReadOnly;
/* 2 */ int None_Nonatomic_ReadOnly;
/* 12 4 */ int GetSet_ReadWriteInExt;
/* WARN */ int Get_ReadWriteInExt;
/* WARN */ int Set_ReadWriteInExt;
/* 12 4 */ int None_ReadWriteInExt;
/* 2 4 */ int GetSet_Nonatomic_ReadWriteInExt;
/* 234 */ int Get_Nonatomic_ReadWriteInExt;
/* 234 */ int Set_Nonatomic_ReadWriteInExt;
/* 2 4 */ int None_Nonatomic_ReadWriteInExt;
/* 12 4 */ int GetSet_LateSynthesize;
/* WARN */ int Get_LateSynthesize;
/* WARN */ int Set_LateSynthesize;
/* 12 4 */ int None_LateSynthesize;
/* 2 4 */ int GetSet_Nonatomic_LateSynthesize;
/* 234 */ int Get_Nonatomic_LateSynthesize;
/* 234 */ int Set_Nonatomic_LateSynthesize;
/* 2 4 */ int None_Nonatomic_LateSynthesize;
/* 12 */ int GetSet_ReadOnly_LateSynthesize;
/* 123 */ int Get_ReadOnly_LateSynthesize;
/* 123 */ int Set_ReadOnly_LateSynthesize;
/* 12 */ int None_ReadOnly_LateSynthesize;
/* 2 */ int GetSet_Nonatomic_ReadOnly_LateSynthesize;
/* 23 */ int Get_Nonatomic_ReadOnly_LateSynthesize;
/* 23 */ int Set_Nonatomic_ReadOnly_LateSynthesize;
/* 2 */ int None_Nonatomic_ReadOnly_LateSynthesize;
/* 12 4 */ int GetSet_ReadWriteInExt_LateSynthesize;
/* WARN */ int Get_ReadWriteInExt_LateSynthesize;
/* WARN */ int Set_ReadWriteInExt_LateSynthesize;
/* 12 4 */ int None_ReadWriteInExt_LateSynthesize;
/* 2 4 */ int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize;
/* 234 */ int Get_Nonatomic_ReadWriteInExt_LateSynthesize;
/* 234 */ int Set_Nonatomic_ReadWriteInExt_LateSynthesize;
/* 2 4 */ int None_Nonatomic_ReadWriteInExt_LateSynthesize;
/* 1 4 */ int GetSet_NoSynthesize;
/* 1 34 */ int Get_NoSynthesize;
/* 1 34 */ int Set_NoSynthesize;
/* 1 4 */ int None_NoSynthesize;
/* 4 */ int GetSet_Nonatomic_NoSynthesize;
/* 34 */ int Get_Nonatomic_NoSynthesize;
/* 34 */ int Set_Nonatomic_NoSynthesize;
/* 4 */ int None_Nonatomic_NoSynthesize;
/* 1 */ int GetSet_ReadOnly_NoSynthesize;
/* 1 3 */ int Get_ReadOnly_NoSynthesize;
/* 1 3 */ int Set_ReadOnly_NoSynthesize;
/* 1 */ int None_ReadOnly_NoSynthesize;
/* */ int GetSet_Nonatomic_ReadOnly_NoSynthesize;
/* 3 */ int Get_Nonatomic_ReadOnly_NoSynthesize;
/* 3 */ int Set_Nonatomic_ReadOnly_NoSynthesize;
/* */ int None_Nonatomic_ReadOnly_NoSynthesize;
/* 1 4 */ int GetSet_ReadWriteInExt_NoSynthesize;
/* 1 34 */ int Get_ReadWriteInExt_NoSynthesize;
/* 1 34 */ int Set_ReadWriteInExt_NoSynthesize;
/* 1 4 */ int None_ReadWriteInExt_NoSynthesize;
/* 4 */ int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize;
/* 34 */ int Get_Nonatomic_ReadWriteInExt_NoSynthesize;
/* 34 */ int Set_Nonatomic_ReadWriteInExt_NoSynthesize;
/* 4 */ int None_Nonatomic_ReadWriteInExt_NoSynthesize;
}
// read-write - might warn
@property int GetSet;
@property int Get; // expected-note {{property declared here}} \
// expected-note {{setter and getter must both be synthesized}}
@property int Set; // expected-note {{property declared here}} \
// expected-note {{setter and getter must both be synthesized}}
@property int None;
@property(nonatomic) int GetSet_Nonatomic;
@property(nonatomic) int Get_Nonatomic;
@property(nonatomic) int Set_Nonatomic;
@property(nonatomic) int None_Nonatomic;
// read-only - must not warn
@property(readonly) int GetSet_ReadOnly;
@property(readonly) int Get_ReadOnly;
@property(readonly) int Set_ReadOnly;
@property(readonly) int None_ReadOnly;
@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly;
@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly;
@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly;
@property(nonatomic,readonly) int None_Nonatomic_ReadOnly;
// read-only in class, read-write in class extension - might warn
@property(readonly) int GetSet_ReadWriteInExt;
@property(readonly) int Get_ReadWriteInExt;
@property(readonly) int Set_ReadWriteInExt;
@property(readonly) int None_ReadWriteInExt;
@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt;
@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt;
@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt;
@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt;
// same as above, but @synthesize follows the hand-written methods - might warn
@property int GetSet_LateSynthesize;
@property int Get_LateSynthesize; // expected-note {{property declared here}} \
// expected-note {{setter and getter must both be synthesized}}
@property int Set_LateSynthesize; // expected-note {{property declared here}} \
// expected-note {{setter and getter must both be synthesized}}
@property int None_LateSynthesize;
@property(nonatomic) int GetSet_Nonatomic_LateSynthesize;
@property(nonatomic) int Get_Nonatomic_LateSynthesize;
@property(nonatomic) int Set_Nonatomic_LateSynthesize;
@property(nonatomic) int None_Nonatomic_LateSynthesize;
@property(readonly) int GetSet_ReadOnly_LateSynthesize;
@property(readonly) int Get_ReadOnly_LateSynthesize;
@property(readonly) int Set_ReadOnly_LateSynthesize;
@property(readonly) int None_ReadOnly_LateSynthesize;
@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly_LateSynthesize;
@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly_LateSynthesize;
@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly_LateSynthesize;
@property(nonatomic,readonly) int None_Nonatomic_ReadOnly_LateSynthesize;
@property(readonly) int GetSet_ReadWriteInExt_LateSynthesize;
@property(readonly) int Get_ReadWriteInExt_LateSynthesize;
@property(readonly) int Set_ReadWriteInExt_LateSynthesize;
@property(readonly) int None_ReadWriteInExt_LateSynthesize;
@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize;
@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt_LateSynthesize;
@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt_LateSynthesize;
@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt_LateSynthesize;
// same as above, but with no @synthesize - must not warn
@property int GetSet_NoSynthesize;
@property int Get_NoSynthesize;
@property int Set_NoSynthesize;
@property int None_NoSynthesize;
@property(nonatomic) int GetSet_Nonatomic_NoSynthesize;
@property(nonatomic) int Get_Nonatomic_NoSynthesize;
@property(nonatomic) int Set_Nonatomic_NoSynthesize;
@property(nonatomic) int None_Nonatomic_NoSynthesize;
@property(readonly) int GetSet_ReadOnly_NoSynthesize;
@property(readonly) int Get_ReadOnly_NoSynthesize;
@property(readonly) int Set_ReadOnly_NoSynthesize;
@property(readonly) int None_ReadOnly_NoSynthesize;
@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly_NoSynthesize;
@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly_NoSynthesize;
@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly_NoSynthesize;
@property(nonatomic,readonly) int None_Nonatomic_ReadOnly_NoSynthesize;
@property(readonly) int GetSet_ReadWriteInExt_NoSynthesize;
@property(readonly) int Get_ReadWriteInExt_NoSynthesize;
@property(readonly) int Set_ReadWriteInExt_NoSynthesize;
@property(readonly) int None_ReadWriteInExt_NoSynthesize;
@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize;
@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt_NoSynthesize;
@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt_NoSynthesize;
@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt_NoSynthesize;
@end
@interface Foo ()
@property(readwrite) int GetSet_ReadWriteInExt;
@property(readwrite) int Get_ReadWriteInExt; // expected-note {{property declared here}} \
// expected-note {{setter and getter must both be synthesized}}
@property(readwrite) int Set_ReadWriteInExt; // expected-note {{property declared here}} \
// expected-note {{setter and getter must both be synthesized}}
@property(readwrite) int None_ReadWriteInExt;
@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt;
@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt;
@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt;
@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt;
@property(readwrite) int GetSet_ReadWriteInExt_LateSynthesize;
@property(readwrite) int Get_ReadWriteInExt_LateSynthesize; // expected-note {{property declared here}} \
// expected-note {{setter and getter must both be synthesized}}
@property(readwrite) int Set_ReadWriteInExt_LateSynthesize; // expected-note {{property declared here}} \
// expected-note {{setter and getter must both be synthesized}}
@property(readwrite) int None_ReadWriteInExt_LateSynthesize;
@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize;
@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt_LateSynthesize;
@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt_LateSynthesize;
@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt_LateSynthesize;
@property(readwrite) int GetSet_ReadWriteInExt_NoSynthesize;
@property(readwrite) int Get_ReadWriteInExt_NoSynthesize;
@property(readwrite) int Set_ReadWriteInExt_NoSynthesize;
@property(readwrite) int None_ReadWriteInExt_NoSynthesize;
@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize;
@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt_NoSynthesize;
@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt_NoSynthesize;
@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt_NoSynthesize;
@end
@implementation Foo
@synthesize GetSet, Get, Set, None, GetSet_Nonatomic, Get_Nonatomic, Set_Nonatomic, None_Nonatomic;
@synthesize GetSet_ReadOnly, Get_ReadOnly, Set_ReadOnly, None_ReadOnly, GetSet_Nonatomic_ReadOnly, Get_Nonatomic_ReadOnly, Set_Nonatomic_ReadOnly, None_Nonatomic_ReadOnly;
@synthesize GetSet_ReadWriteInExt, Get_ReadWriteInExt, Set_ReadWriteInExt, None_ReadWriteInExt, GetSet_Nonatomic_ReadWriteInExt, Get_Nonatomic_ReadWriteInExt, Set_Nonatomic_ReadWriteInExt, None_Nonatomic_ReadWriteInExt;
#define GET(x) \
-(int) x { return self->x; }
#define SET(x) \
-(void) set##x:(int)value { self->x = value; }
GET(GetSet)
SET(GetSet)
GET(Get) // expected-warning {{writable atomic property 'Get' cannot pair a synthesized setter with a user defined getter}}
SET(Set) // expected-warning {{writable atomic property 'Set' cannot pair a synthesized getter with a user defined setter}}
GET(GetSet_Nonatomic)
SET(GetSet_Nonatomic)
GET(Get_Nonatomic)
SET(Set_Nonatomic)
GET(GetSet_ReadOnly)
SET(GetSet_ReadOnly)
GET(Get_ReadOnly)
SET(Set_ReadOnly)
GET(GetSet_Nonatomic_ReadOnly)
SET(GetSet_Nonatomic_ReadOnly)
GET(Get_Nonatomic_ReadOnly)
SET(Set_Nonatomic_ReadOnly)
GET(GetSet_ReadWriteInExt)
SET(GetSet_ReadWriteInExt)
GET(Get_ReadWriteInExt) // expected-warning {{writable atomic property 'Get_ReadWriteInExt' cannot pair a synthesized setter with a user defined getter}}
SET(Set_ReadWriteInExt) // expected-warning {{writable atomic property 'Set_ReadWriteInExt' cannot pair a synthesized getter with a user defined setter}}
GET(GetSet_Nonatomic_ReadWriteInExt)
SET(GetSet_Nonatomic_ReadWriteInExt)
GET(Get_Nonatomic_ReadWriteInExt)
SET(Set_Nonatomic_ReadWriteInExt)
GET(GetSet_LateSynthesize)
SET(GetSet_LateSynthesize)
GET(Get_LateSynthesize) // expected-warning {{writable atomic property 'Get_LateSynthesize' cannot pair a synthesized setter with a user defined getter}}
SET(Set_LateSynthesize) // expected-warning {{writable atomic property 'Set_LateSynthesize' cannot pair a synthesized getter with a user defined setter}}
GET(GetSet_Nonatomic_LateSynthesize)
SET(GetSet_Nonatomic_LateSynthesize)
GET(Get_Nonatomic_LateSynthesize)
SET(Set_Nonatomic_LateSynthesize)
GET(GetSet_ReadOnly_LateSynthesize)
SET(GetSet_ReadOnly_LateSynthesize)
GET(Get_ReadOnly_LateSynthesize)
SET(Set_ReadOnly_LateSynthesize)
GET(GetSet_Nonatomic_ReadOnly_LateSynthesize)
SET(GetSet_Nonatomic_ReadOnly_LateSynthesize)
GET(Get_Nonatomic_ReadOnly_LateSynthesize)
SET(Set_Nonatomic_ReadOnly_LateSynthesize)
GET(GetSet_ReadWriteInExt_LateSynthesize)
SET(GetSet_ReadWriteInExt_LateSynthesize)
GET(Get_ReadWriteInExt_LateSynthesize) // expected-warning {{writable atomic property 'Get_ReadWriteInExt_LateSynthesize' cannot pair a synthesized setter with a user defined getter}}
SET(Set_ReadWriteInExt_LateSynthesize) // expected-warning {{writable atomic property 'Set_ReadWriteInExt_LateSynthesize' cannot pair a synthesized getter with a user defined setter}}
GET(GetSet_Nonatomic_ReadWriteInExt_LateSynthesize)
SET(GetSet_Nonatomic_ReadWriteInExt_LateSynthesize)
GET(Get_Nonatomic_ReadWriteInExt_LateSynthesize)
SET(Set_Nonatomic_ReadWriteInExt_LateSynthesize)
GET(GetSet_NoSynthesize)
SET(GetSet_NoSynthesize)
GET(Get_NoSynthesize)
SET(Set_NoSynthesize)
GET(GetSet_Nonatomic_NoSynthesize)
SET(GetSet_Nonatomic_NoSynthesize)
GET(Get_Nonatomic_NoSynthesize)
SET(Set_Nonatomic_NoSynthesize)
GET(GetSet_ReadOnly_NoSynthesize)
SET(GetSet_ReadOnly_NoSynthesize)
GET(Get_ReadOnly_NoSynthesize)
SET(Set_ReadOnly_NoSynthesize)
GET(GetSet_Nonatomic_ReadOnly_NoSynthesize)
SET(GetSet_Nonatomic_ReadOnly_NoSynthesize)
GET(Get_Nonatomic_ReadOnly_NoSynthesize)
SET(Set_Nonatomic_ReadOnly_NoSynthesize)
GET(GetSet_ReadWriteInExt_NoSynthesize)
SET(GetSet_ReadWriteInExt_NoSynthesize)
GET(Get_ReadWriteInExt_NoSynthesize)
SET(Set_ReadWriteInExt_NoSynthesize)
GET(GetSet_Nonatomic_ReadWriteInExt_NoSynthesize)
SET(GetSet_Nonatomic_ReadWriteInExt_NoSynthesize)
GET(Get_Nonatomic_ReadWriteInExt_NoSynthesize)
SET(Set_Nonatomic_ReadWriteInExt_NoSynthesize)
// late synthesize - follows getter/setter implementations
@synthesize GetSet_LateSynthesize, Get_LateSynthesize, Set_LateSynthesize, None_LateSynthesize, GetSet_Nonatomic_LateSynthesize, Get_Nonatomic_LateSynthesize, Set_Nonatomic_LateSynthesize, None_Nonatomic_LateSynthesize;
@synthesize GetSet_ReadOnly_LateSynthesize, Get_ReadOnly_LateSynthesize, Set_ReadOnly_LateSynthesize, None_ReadOnly_LateSynthesize, GetSet_Nonatomic_ReadOnly_LateSynthesize, Get_Nonatomic_ReadOnly_LateSynthesize, Set_Nonatomic_ReadOnly_LateSynthesize, None_Nonatomic_ReadOnly_LateSynthesize;
@synthesize GetSet_ReadWriteInExt_LateSynthesize, Get_ReadWriteInExt_LateSynthesize, Set_ReadWriteInExt_LateSynthesize, None_ReadWriteInExt_LateSynthesize, GetSet_Nonatomic_ReadWriteInExt_LateSynthesize, Get_Nonatomic_ReadWriteInExt_LateSynthesize, Set_Nonatomic_ReadWriteInExt_LateSynthesize, None_Nonatomic_ReadWriteInExt_LateSynthesize;
// no synthesize - use dynamic instead
@dynamic GetSet_NoSynthesize, Get_NoSynthesize, Set_NoSynthesize, None_NoSynthesize, GetSet_Nonatomic_NoSynthesize, Get_Nonatomic_NoSynthesize, Set_Nonatomic_NoSynthesize, None_Nonatomic_NoSynthesize;
@dynamic GetSet_ReadOnly_NoSynthesize, Get_ReadOnly_NoSynthesize, Set_ReadOnly_NoSynthesize, None_ReadOnly_NoSynthesize, GetSet_Nonatomic_ReadOnly_NoSynthesize, Get_Nonatomic_ReadOnly_NoSynthesize, Set_Nonatomic_ReadOnly_NoSynthesize, None_Nonatomic_ReadOnly_NoSynthesize;
@dynamic GetSet_ReadWriteInExt_NoSynthesize, Get_ReadWriteInExt_NoSynthesize, Set_ReadWriteInExt_NoSynthesize, None_ReadWriteInExt_NoSynthesize, GetSet_Nonatomic_ReadWriteInExt_NoSynthesize, Get_Nonatomic_ReadWriteInExt_NoSynthesize, Set_Nonatomic_ReadWriteInExt_NoSynthesize, None_Nonatomic_ReadWriteInExt_NoSynthesize;
@end
/*
// the following method should cause a warning along the lines of
// :warning: Atomic property 'x' cannot pair a synthesized setter/getter with a manually implemented setter/getter
- (void) setX: (int) aValue
{
x = aValue;
}
// no warning 'cause this is nonatomic
- (void) setY: (int) aValue
{
y = aValue;
}
// the following method should cause a warning along the lines of
// :warning: Atomic property 'x' cannot pair a synthesized setter/getter with a manually implemented setter/getter
- (int) j
{
return j;
}
// no warning 'cause this is nonatomic
- (int) k
{
return k;
}
@end
*/
int main (int argc, const char * argv[]) {
return 0;
}

View File

@ -0,0 +1,120 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s
// RUN: %clang_cc1 -x objective-c++ -std=c++11 -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s
// RUN: %clang_cc1 -x objective-c++ -std=c++03 -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s
// rdar://18490958
#if !__has_feature(attribute_availability_with_version_underscores)
# error "missing feature"
#endif
@protocol P
- (void)proto_method __attribute__((availability(macosx,introduced=10_1,deprecated=10_2))); // expected-note 2 {{'proto_method' has been explicitly marked deprecated here}}
@end
@interface A <P>
- (void)method __attribute__((availability(macosx,introduced=10_1,deprecated=10_2))); // expected-note {{'method' has been explicitly marked deprecated here}}
- (void)overridden __attribute__((availability(macosx,introduced=10_3))); // expected-note{{overridden method is here}}
- (void)overridden2 __attribute__((availability(macosx,introduced=10_3)));
- (void)overridden3 __attribute__((availability(macosx,deprecated=10_3)));
- (void)overridden4 __attribute__((availability(macosx,deprecated=10_3))); // expected-note{{overridden method is here}}
- (void)overridden5 __attribute__((availability(macosx,unavailable)));
- (void)overridden6 __attribute__((availability(macosx,introduced=10_3))); // expected-note{{overridden method is here}}
@end
// rdar://11475360
@interface B : A
- (void)method; // NOTE: we expect 'method' to *not* inherit availability.
- (void)overridden __attribute__((availability(macosx,introduced=10_4))); // expected-warning{{overriding method introduced after overridden method on macOS (10.4 vs. 10.3)}}
- (void)overridden2 __attribute__((availability(macosx,introduced=10_2)));
- (void)overridden3 __attribute__((availability(macosx,deprecated=10_4)));
- (void)overridden4 __attribute__((availability(macosx,deprecated=10_2))); // expected-warning{{overriding method deprecated before overridden method on macOS (10.3 vs. 10.2)}}
- (void)overridden5 __attribute__((availability(macosx,introduced=10_3)));
- (void)overridden6 __attribute__((availability(macosx,unavailable))); // expected-warning{{overriding method cannot be unavailable on macOS when its overridden method is available}}
@end
void f(A *a, B *b) {
[a method]; // expected-warning{{'method' is deprecated: first deprecated in macOS 10.2}}
[b method]; // no-warning
[a proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in macOS 10.2}}
[b proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in macOS 10.2}}
}
// Test case for <rdar://problem/11627873>. Warn about
// using a deprecated method when that method is re-implemented in a
// subclass where the redeclared method is not deprecated.
@interface C
- (void) method __attribute__((availability(macosx,introduced=10_1,deprecated=10_2))); // expected-note {{'method' has been explicitly marked deprecated here}}
@end
@interface D : C
- (void) method;
@end
@interface E : D
- (void) method;
@end
@implementation D
- (void) method {
[super method]; // expected-warning {{'method' is deprecated: first deprecated in macOS 10.2}}
}
@end
@implementation E
- (void) method {
[super method]; // no-warning
}
@end
// rdar://18059669
@class NSMutableArray;
@interface NSDictionary
+ (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ... __attribute__((sentinel(0,1)));
@end
@class NSString;
extern NSString *NSNibTopLevelObjects __attribute__((availability(macosx,introduced=10_0 ,deprecated=10_8,message="" )));
id NSNibOwner, topNibObjects;
@interface AppDelegate (SIEImport) // expected-error {{cannot find interface declaration for 'AppDelegate'}}
-(void)__attribute__((ibaction))importFromSIE:(id)sender;
@end
@implementation AppDelegate (SIEImport) // expected-error {{cannot find interface declaration for 'AppDelegate'}}
-(void)__attribute__((ibaction))importFromSIE:(id)sender {
NSMutableArray *topNibObjects;
NSDictionary *nibLoadDict = [NSDictionary dictionaryWithObjectsAndKeys:self, NSNibOwner, topNibObjects, NSNibTopLevelObjects, ((void *)0)];
}
@end
@interface Mixed
- (void)Meth1 __attribute__((availability(macosx,introduced=10.3_0))); // expected-warning {{use same version number separators '_' or '.'}}
- (void)Meth2 __attribute__((availability(macosx,introduced=10_3.1))); // expected-warning {{use same version number separators '_' or '.'}}
@end
// rdar://18804883
@protocol P18804883
- (void)proto_method __attribute__((availability(macosx,introduced=10_1,deprecated=NA))); // means nothing (not deprecated)
@end
@interface A18804883 <P18804883>
- (void)interface_method __attribute__((availability(macosx,introduced=NA))); // expected-note {{'interface_method' has been explicitly marked unavailable here}}
- (void)strange_method __attribute__((availability(macosx,introduced=NA,deprecated=NA))); // expected-note {{'strange_method' has been explicitly marked unavailable here}}
- (void) always_available __attribute__((availability(macosx,deprecated=NA)));
@end
void foo (A18804883* pa) {
[pa interface_method]; // expected-error {{'interface_method' is unavailable: not available on macOS}}
[pa proto_method];
[pa strange_method]; // expected-error {{'strange_method' is unavailable: not available on macOS}}
[pa always_available];
}

View File

@ -0,0 +1,53 @@
// RUN: %clang_cc1 -triple arm64-apple-tvos12.0 -fsyntax-only -verify %s
void explicit() __attribute__((availability(tvos, introduced=11.0, deprecated=12.0))); // expected-note {{marked deprecated here}}
void inferred() __attribute__((availability(ios, introduced=11.0, deprecated=12.0))); // expected-note {{marked deprecated here}}
void explicitOverInferred()
__attribute__((availability(ios, introduced=11.0, deprecated=12.0)))
__attribute__((availability(tvos, introduced=11.0)));
void explicitOverInferred2()
__attribute__((availability(tvos, introduced=11.0)))
__attribute__((availability(ios, introduced=11.0, deprecated=12.0)));
void simpleUsage() {
explicit(); // expected-warning{{'explicit' is deprecated: first deprecated in tvOS 12.0}}
inferred(); // expected-warning{{'inferred' is deprecated: first deprecated in tvOS 12.0}}
// ok, not deprecated for tvOS.
explicitOverInferred();
explicitOverInferred2();
}
#pragma clang attribute push (__attribute__((availability(tvos, introduced=11.0, deprecated=12.0))), apply_to=function)
void explicitFromPragma(); // expected-note {{marked deprecated here}}
void explicitWinsOverExplicitFromPragma() __attribute__((availability(tvos, introduced=11.0)));
void implicitLosesOverExplicitFromPragma() __attribute__((availability(ios, introduced=11.0))); // expected-note {{marked deprecated here}}
#pragma clang attribute pop
#pragma clang attribute push (__attribute__((availability(ios, introduced=11.0, deprecated=12.0))), apply_to=function)
void implicitFromPragma(); // expected-note {{marked deprecated here}}
void explicitWinsOverImplicitFromPragma() __attribute__((availability(tvos, introduced=11.0)));
void implicitWinsOverImplicitFromPragma() __attribute__((availability(ios, introduced=11.0)));
#pragma clang attribute pop
#pragma clang attribute push (__attribute__((availability(tvos, introduced=11.0, deprecated=12.0))), apply_to=function)
#pragma clang attribute push (__attribute__((availability(ios, introduced=11.0, deprecated=11.3))), apply_to=function)
void pragmaExplicitWinsOverPragmaImplicit(); // expected-note {{marked deprecated here}}
#pragma clang attribute pop
#pragma clang attribute pop
void pragmaUsage() {
explicitFromPragma(); // expected-warning {{'explicitFromPragma' is deprecated: first deprecated in tvOS 12.0}}
explicitWinsOverExplicitFromPragma(); // ok
implicitLosesOverExplicitFromPragma(); // expected-warning {{'implicitLosesOverExplicitFromPragma' is deprecated: first deprecated in tvOS 12.0}}
implicitFromPragma(); // expected-warning {{'implicitFromPragma' is deprecated: first deprecated in tvOS 12.0}}
explicitWinsOverImplicitFromPragma(); // ok
implicitWinsOverImplicitFromPragma(); // ok
pragmaExplicitWinsOverPragmaImplicit(); // expected-warning {{'pragmaExplicitWinsOverPragmaImplicit' is deprecated: first deprecated in tvOS 12.0}}
}

View File

@ -0,0 +1,348 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s
// RUN: %clang_cc1 -D WARN_PARTIAL -Wpartial-availability -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s
@protocol P
- (void)proto_method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 2 {{'proto_method' has been explicitly marked deprecated here}}
#if defined(WARN_PARTIAL)
// expected-note@+2 2 {{'partial_proto_method' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
#endif
- (void)partial_proto_method __attribute__((availability(macosx,introduced=10.8)));
@end
@interface A <P>
- (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}}
#if defined(WARN_PARTIAL)
// expected-note@+2 2 {{'partialMethod' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
#endif
- (void)partialMethod __attribute__((availability(macosx,introduced=10.8)));
- (void)overridden __attribute__((availability(macosx,introduced=10.3))); // expected-note{{overridden method is here}}
- (void)overridden2 __attribute__((availability(macosx,introduced=10.3)));
- (void)overridden3 __attribute__((availability(macosx,deprecated=10.3)));
- (void)overridden4 __attribute__((availability(macosx,deprecated=10.3))); // expected-note{{overridden method is here}}
- (void)overridden5 __attribute__((availability(macosx,unavailable)));
- (void)overridden6 __attribute__((availability(macosx,introduced=10.3))); // expected-note{{overridden method is here}}
- (void)unavailableMethod __attribute__((unavailable));
@end
// rdar://11475360
@interface B : A
- (void)method; // NOTE: we expect 'method' to *not* inherit availability.
- (void)partialMethod; // Likewise.
- (void)overridden __attribute__((availability(macosx,introduced=10.4))); // expected-warning{{overriding method introduced after overridden method on macOS (10.4 vs. 10.3)}}
- (void)overridden2 __attribute__((availability(macosx,introduced=10.2)));
- (void)overridden3 __attribute__((availability(macosx,deprecated=10.4)));
- (void)overridden4 __attribute__((availability(macosx,deprecated=10.2))); // expected-warning{{overriding method deprecated before overridden method on macOS (10.3 vs. 10.2)}}
- (void)overridden5 __attribute__((availability(macosx,introduced=10.3)));
- (void)overridden6 __attribute__((availability(macosx,unavailable))); // expected-warning{{overriding method cannot be unavailable on macOS when its overridden method is available}}
- (void)unavailableMethod; // does *not* inherit unavailability
@end
void f(A *a, B *b) {
[a method]; // expected-warning{{'method' is deprecated: first deprecated in macOS 10.2}}
[b method]; // no-warning
[a proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in macOS 10.2}}
[b proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in macOS 10.2}}
#if defined(WARN_PARTIAL)
// expected-warning@+2 {{'partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'partialMethod' in an @available check to silence this warning}}
#endif
[a partialMethod];
[b partialMethod]; // no warning
#if defined(WARN_PARTIAL)
// expected-warning@+2 {{'partial_proto_method' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'partial_proto_method' in an @available check to silence this warning}}
#endif
[a partial_proto_method];
#if defined(WARN_PARTIAL)
// expected-warning@+2 {{'partial_proto_method' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'partial_proto_method' in an @available check to silence this warning}}
#endif
[b partial_proto_method];
}
@interface A (NewAPI)
- (void)partialMethod;
- (void)partial_proto_method;
@end
void f_after_redecl(A *a, B *b) {
#ifdef WARN_PARTIAL
// expected-warning@+2{{'partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2 {{@available}}
#endif
[a partialMethod];
[b partialMethod]; // no warning
[a partial_proto_method]; // no warning
[b partial_proto_method]; // no warning
}
// Test case for <rdar://problem/11627873>. Warn about
// using a deprecated method when that method is re-implemented in a
// subclass where the redeclared method is not deprecated.
@interface C
- (void) method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}}
@end
@interface D : C
- (void) method;
@end
@interface E : D
- (void) method;
@end
@implementation D
- (void) method {
[super method]; // expected-warning {{'method' is deprecated: first deprecated in macOS 10.2}}
}
@end
@implementation E
- (void) method {
[super method]; // no-warning
}
@end
// rdar://18059669
@class NSMutableArray;
@interface NSDictionary
+ (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ... __attribute__((sentinel(0,1)));
@end
@class NSString;
extern NSString *NSNibTopLevelObjects __attribute__((availability(macosx,introduced=10.0 ,deprecated=10.8,message="" )));
id NSNibOwner, topNibObjects;
@interface AppDelegate (SIEImport) // expected-error {{cannot find interface declaration for 'AppDelegate'}}
-(void)__attribute__((ibaction))importFromSIE:(id)sender;
@end
@implementation AppDelegate (SIEImport) // expected-error {{cannot find interface declaration for 'AppDelegate'}}
-(void)__attribute__((ibaction))importFromSIE:(id)sender {
NSMutableArray *topNibObjects;
NSDictionary *nibLoadDict = [NSDictionary dictionaryWithObjectsAndKeys:self, NSNibOwner, topNibObjects, NSNibTopLevelObjects, ((void *)0)];
}
@end
@protocol PartialProt
- (void)ppartialMethod __attribute__((availability(macosx,introduced=10.8)));
+ (void)ppartialMethod __attribute__((availability(macosx,introduced=10.8)));
@end
@interface PartialI <PartialProt>
#ifdef WARN_PARTIAL
// expected-note@+3{{'partialMethod' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
// expected-note@+3{{'partialMethod' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
#endif
- (void)partialMethod __attribute__((availability(macosx,introduced=10.8)));
+ (void)partialMethod __attribute__((availability(macosx,introduced=10.8)));
@end
@interface PartialI ()
- (void)ipartialMethod1 __attribute__((availability(macosx,introduced=10.8)));
#if defined(WARN_PARTIAL)
// expected-note@+2 {{'ipartialMethod2' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
#endif
- (void)ipartialMethod2 __attribute__((availability(macosx,introduced=10.8)));
+ (void)ipartialMethod1 __attribute__((availability(macosx,introduced=10.8)));
#if defined(WARN_PARTIAL)
// expected-note@+2 {{'ipartialMethod2' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
#endif
+ (void)ipartialMethod2 __attribute__((availability(macosx,introduced=10.8)));
@end
@interface PartialI (Redecls)
- (void)partialMethod;
- (void)ipartialMethod1;
- (void)ppartialMethod;
+ (void)partialMethod;
+ (void)ipartialMethod1;
+ (void)ppartialMethod;
@end
void partialfun(PartialI* a) {
#ifdef WARN_PARTIAL
// expected-warning@+2 {{'partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2{{@available}}
#endif
[a partialMethod];
[a ipartialMethod1]; // no warning
#if defined(WARN_PARTIAL)
// expected-warning@+2 {{'ipartialMethod2' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'ipartialMethod2' in an @available check to silence this warning}}
#endif
[a ipartialMethod2];
[a ppartialMethod]; // no warning
#ifdef WARN_PARTIAL
// expected-warning@+2 {{'partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2 {{@available}}
#endif
[PartialI partialMethod];
[PartialI ipartialMethod1]; // no warning
#if defined(WARN_PARTIAL)
// expected-warning@+2 {{'ipartialMethod2' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'ipartialMethod2' in an @available check to silence this warning}}
#endif
[PartialI ipartialMethod2];
[PartialI ppartialMethod]; // no warning
}
#if defined(WARN_PARTIAL)
// expected-note@+2 2 {{'PartialI2' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
#endif
__attribute__((availability(macosx, introduced = 10.8))) @interface PartialI2
@end
#if defined(WARN_PARTIAL)
// expected-warning@+2 {{'PartialI2' is only available on macOS 10.8 or newer}} expected-note@+2 {{annotate 'partialinter1' with an availability attribute to silence}}
#endif
void partialinter1(PartialI2* p) {
}
@class PartialI2;
#ifdef WARN_PARTIAL
// expected-warning@+2 {{'PartialI2' is only available on macOS 10.8 or newer}} expected-note@+2 {{annotate 'partialinter2' with an availability attribute to silence}}
#endif
void partialinter2(PartialI2* p) {
}
// Test that both the use of the 'typedef' and the enum constant
// produces an error. rdar://problem/20903588
#define UNAVAILABLE __attribute__((unavailable("not available")))
typedef enum MyEnum : int MyEnum;
enum MyEnum : int { // expected-note {{'MyEnum' has been explicitly marked unavailable here}}
MyEnum_Blah UNAVAILABLE, // expected-note {{'MyEnum_Blah' has been explicitly marked unavailable here}}
} UNAVAILABLE;
void use_myEnum() {
// expected-error@+2 {{'MyEnum' is unavailable: not available}}
// expected-error@+1 {{MyEnum_Blah' is unavailable: not available}}
MyEnum e = MyEnum_Blah;
}
// Test that the availability of (optional) protocol methods is not
// inherited be implementations of those protocol methods.
@protocol AvailabilityP2
@optional
-(void)methodA __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 4{{'methodA' has been explicitly marked deprecated here}} \
// expected-note 2{{protocol method is here}}
-(void)methodB __attribute__((unavailable)); // expected-note 4{{'methodB' has been explicitly marked unavailable here}}
-(void)methodC;
@end
void testAvailabilityP2(id<AvailabilityP2> obj) {
[obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
[obj methodB]; // expected-error{{'methodB' is unavailable}}
}
@interface ImplementsAvailabilityP2a <AvailabilityP2>
-(void)methodA;
-(void)methodB;
@end
void testImplementsAvailabilityP2a(ImplementsAvailabilityP2a *obj) {
[obj methodA]; // okay: availability not inherited
[obj methodB]; // okay: unavailability not inherited
}
__attribute__((objc_root_class))
@interface ImplementsAvailabilityP2b <AvailabilityP2>
@end
@implementation ImplementsAvailabilityP2b
-(void)methodA {
// Make sure we're not inheriting availability.
id<AvailabilityP2> obj = self;
[obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
[obj methodB]; // expected-error{{'methodB' is unavailable}}
}
-(void)methodB {
// Make sure we're not inheriting unavailability.
id<AvailabilityP2> obj = self;
[obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
[obj methodB]; // expected-error{{'methodB' is unavailable}}
}
@end
void testImplementsAvailabilityP2b(ImplementsAvailabilityP2b *obj) {
// still get warnings/errors because we see the protocol version.
[obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
[obj methodB]; // expected-error{{'methodB' is unavailable}}
}
__attribute__((objc_root_class))
@interface ImplementsAvailabilityP2c <AvailabilityP2>
-(void)methodA __attribute__((availability(macosx,introduced=10.2))); // expected-warning{{method introduced after the protocol method it implements on macOS (10.2 vs. 10.1)}}
-(void)methodB __attribute__((unavailable));
@end
__attribute__((objc_root_class))
@interface ImplementsAvailabilityP2d <AvailabilityP2>
@end
@implementation ImplementsAvailabilityP2d
-(void)methodA __attribute__((availability(macosx,introduced=10.2))) // expected-warning{{method introduced after the protocol method it implements on macOS (10.2 vs. 10.1)}}
{
}
-(void)methodB __attribute__((unavailable)) {
}
@end
__attribute__((objc_root_class))
@interface InheritUnavailableSuper
-(void)method __attribute__((unavailable)); // expected-note{{'method' has been explicitly marked unavailable here}}
@end
@interface InheritUnavailableSub : InheritUnavailableSuper
-(void)method;
@end
@implementation InheritUnavailableSub
-(void)method {
InheritUnavailableSuper *obj = self;
[obj method]; // expected-error{{'method' is unavailable}}
}
@end
#if defined(WARN_PARTIAL)
int fn_10_5() __attribute__((availability(macosx, introduced=10.5)));
int fn_10_7() __attribute__((availability(macosx, introduced=10.7))); // expected-note{{'fn_10_7' has been marked as being introduced in macOS 10.7 here, but the deployment target is macOS 10.5.0}}
int fn_10_8() __attribute__((availability(macosx, introduced=10.8))) { // expected-note{{'fn_10_8' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
return fn_10_7();
}
__attribute__((objc_root_class))
@interface LookupAvailabilityBase
-(void) method1;
@end
@implementation LookupAvailabilityBase
-(void)method1 { fn_10_7(); } // expected-warning{{only available on macOS 10.7}} expected-note{{@available}}
@end
__attribute__((availability(macosx, introduced=10.7)))
@interface LookupAvailability : LookupAvailabilityBase
- (void)method2;
- (void)method3;
- (void)method4 __attribute__((availability(macosx, introduced=10.8)));
@end
@implementation LookupAvailability
-(void)method2 { fn_10_7(); }
-(void)method3 { fn_10_8(); } // expected-warning{{only available on macOS 10.8}} expected-note{{@available}}
-(void)method4 { fn_10_8(); }
@end
int old_func() __attribute__((availability(macos, introduced=10.4))) {
fn_10_5();
}
#endif

View File

@ -0,0 +1,20 @@
// RUN: %clang_cc1 -verify -fsyntax-only -fobjc-arc -fblocks %s
#define CALLED_ONCE __attribute__((called_once))
void test1(int x CALLED_ONCE); // expected-error{{'called_once' attribute only applies to function-like parameters}}
void test2(double x CALLED_ONCE); // expected-error{{'called_once' attribute only applies to function-like parameters}}
void test3(void (*foo)() CALLED_ONCE); // no-error
void test4(int (^foo)(int) CALLED_ONCE); // no-error
void test5(void (*foo)() __attribute__((called_once(1))));
// expected-error@-1{{'called_once' attribute takes no arguments}}
void test6(void (*foo)() __attribute__((called_once("str1", "str2"))));
// expected-error@-1{{'called_once' attribute takes no arguments}}
CALLED_ONCE void test7(); // expected-warning{{'called_once' attribute only applies to parameters}}
void test8() {
void (*foo)() CALLED_ONCE; // expected-warning{{'called_once' attribute only applies to parameters}}
foo();
}

View File

@ -0,0 +1,49 @@
// RUN: %clang_cc1 -verify -fsyntax-only -fobjc-arc -fblocks %s
#if __has_feature(attribute_cf_returns_on_parameters)
# error "okay!"
// expected-error@-1 {{okay!}}
#else
# error "uh-oh"
#endif
#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
int x CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to functions, methods, and parameters}}
int y CF_RETURNS_NOT_RETAINED; // expected-warning{{'cf_returns_not_retained' attribute only applies to functions, methods, and parameters}}
typedef struct __CFFoo *CFFooRef;
int invalid1() CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to functions that return a pointer}}
void invalid2() CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to functions that return a pointer}}
CFFooRef valid1() CF_RETURNS_RETAINED;
id valid2() CF_RETURNS_RETAINED;
@interface Test
- (int)invalid1 CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to methods that return a pointer}}
- (void)invalid2 CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to methods that return a pointer}}
- (CFFooRef)valid1 CF_RETURNS_RETAINED;
- (id)valid2 CF_RETURNS_RETAINED;
@property int invalidProp1 CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to properties that return a pointer}}
@property void invalidProp2 CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to properties that return a pointer}}
@property CFFooRef valid1 CF_RETURNS_RETAINED;
@property id valid2 CF_RETURNS_RETAINED;
@end
void invalidParam(int a CF_RETURNS_RETAINED, // expected-warning{{'cf_returns_retained' attribute only applies to pointer-to-CF-pointer parameters}}
int *b CF_RETURNS_RETAINED, // expected-warning{{'cf_returns_retained' attribute only applies to pointer-to-CF-pointer parameters}}
id c CF_RETURNS_RETAINED, // expected-warning{{'cf_returns_retained' attribute only applies to pointer-to-CF-pointer parameters}}
void *d CF_RETURNS_RETAINED, // expected-warning{{'cf_returns_retained' attribute only applies to pointer-to-CF-pointer parameters}}
CFFooRef e CF_RETURNS_RETAINED); // expected-warning{{'cf_returns_retained' attribute only applies to pointer-to-CF-pointer parameters}}
void validParam(id *a CF_RETURNS_RETAINED,
CFFooRef *b CF_RETURNS_RETAINED,
void **c CF_RETURNS_RETAINED);
void validParam2(id *a CF_RETURNS_NOT_RETAINED,
CFFooRef *b CF_RETURNS_NOT_RETAINED,
void **c CF_RETURNS_NOT_RETAINED);

View File

@ -0,0 +1,11 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only
// expected-no-diagnostics
@class NSString;
void c1(id *a);
void t1()
{
NSString *s __attribute((cleanup(c1)));
}

View File

@ -0,0 +1,23 @@
// RUN: %clang_cc1 -fsyntax-only -DBOTH -verify %s
// If the decls come from a pch, the behavior shouldn't change:
// RUN: %clang_cc1 -x objective-c-header %s -emit-pch -o %t
// RUN: %clang_cc1 -DUSES -include-pch %t -fsyntax-only -verify %s
// expected-no-diagnostics
// The slightly strange ifdefs are so that the command that builds the gch file
// doesn't need any -D switches, for these would get embedded in the gch.
#ifndef USES
@interface Interface1
- (void)partiallyUnavailableMethod;
@end
@interface Interface2
- (void)partiallyUnavailableMethod __attribute__((unavailable));
@end
#endif
#if defined(USES) || defined(BOTH)
void f(id a) {
[a partiallyUnavailableMethod]; // no warning, `a` could be an Interface1.
}
#endif

View File

@ -0,0 +1,177 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -verify -fsyntax-only %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --implicit-check-not fix-it: %s
// RUN: cp %s %t
// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DIGNORE_UNSUCCESSFUL_RENAMES -fixit -x objective-c %t
// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DIGNORE_UNSUCCESSFUL_RENAMES -Werror -x objective-c %t
#if !__has_feature(attribute_deprecated_with_replacement)
#error "Missing __has_feature"
#endif
#if !__has_feature(attribute_availability_with_replacement)
#error "Missing __has_feature"
#endif
#define DEPRECATED(replacement) __attribute__((deprecated("message", replacement)))
@protocol SuccessfulMultiParameterRenames
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)multi:(int)param1 parameter:(int)param2 replacement:(int)param3 DEPRECATED("multi_new:parameter_new:replace_new_ment:");
- (void)multi_new:(int)param1 parameter_new:(int)param2 replace_new_ment:(int)param3;
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)varArgs:(int)params, ... DEPRECATED("renameVarArgs:");
- (void)renameVarArgs:(int)params, ...;
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)leadingMinus:(int)param DEPRECATED("-leadingMinusRenamed:");
- (void)leadingMinusRenamed:(int)param;
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)leadingPlus:(int)param DEPRECATED("+leadingPlusRenamed:");
- (void)leadingPlusRenamed:(int)param;
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)sourceEmptyName:(int)param1 :(int)param2 DEPRECATED("renameEmptyName:toNonEmpty:");
- (void)renameEmptyName:(int)param1 toNonEmpty:(int)param2;
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)target:(int)param1 willBecomeEmpty:(int)param2 emptyName:(int)param3 DEPRECATED("target::emptyName:");
- (void)target:(int)param1 :(int)param2 emptyName:(int)param3;
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)extra:(int)param1 whiteSpace:(int)param2 DEPRECATED("renameExtra:whiteSpace:");
- (void)renameExtra:(int)param1 whiteSpace:(int)param2;
// Test renaming that was producing valid code earlier is still producing valid
// code. The difference is that now we detect different number of parameters.
//
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)singleArgumentRegression:(int)param DEPRECATED("renameSingleArgument");
- (void)renameSingleArgument:(int)param;
@end
void successfulRenames(id<SuccessfulMultiParameterRenames> object) {
[object multi:0 parameter:1 replacement:2]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:16}:"multi_new"
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:19-[[@LINE-2]]:28}:"parameter_new"
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:31-[[@LINE-3]]:42}:"replace_new_ment"
[object varArgs:1, 2, 3, 0]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:18}:"renameVarArgs"
[object leadingMinus:0]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:23}:"leadingMinusRenamed"
[object leadingPlus:0]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:22}:"leadingPlusRenamed"
[object sourceEmptyName:0 :1]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:26}:"renameEmptyName"
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:29-[[@LINE-2]]:29}:"toNonEmpty"
[object target:0 willBecomeEmpty:1 emptyName:2]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:17}:"target"
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:20-[[@LINE-2]]:35}:""
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:38-[[@LINE-3]]:47}:"emptyName"
[object extra: 0 whiteSpace: 1]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:16}:"renameExtra"
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:23-[[@LINE-2]]:33}:"whiteSpace"
[object singleArgumentRegression:0]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:35}:"renameSingleArgument"
}
#ifndef IGNORE_UNSUCCESSFUL_RENAMES
@protocol UnsuccessfulMultiParameterRenames
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)differentNumberOfParameters:(int)param DEPRECATED("rename:hasMoreParameters:");
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)differentNumber:(int)param1 ofParameters:(int)param2 DEPRECATED("renameHasLessParameters:");
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)methodLike:(int)param1 replacement:(int)param2 DEPRECATED("noColon:atTheEnd");
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)freeFormText DEPRECATED("Use something else");
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)freeFormTextReplacementStartsAsMethod DEPRECATED("-Use something different");
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)replacementHasSingleSkipCharacter DEPRECATED("-");
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)replacementHasInvalid:(int)param1 slotName:(int)param2 DEPRECATED("renameWith:1nonIdentifier:");
@end
void unsuccessfulRenames(id<UnsuccessfulMultiParameterRenames> object) {
[object differentNumberOfParameters:0]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:38}:"rename:hasMoreParameters:"
[object differentNumber:0 ofParameters:1]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:26}:"renameHasLessParameters:"
[object methodLike:0 replacement:1]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:21}:"noColon:atTheEnd"
[object freeFormText]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:23}:"Use something else"
[object freeFormTextReplacementStartsAsMethod]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:48}:"-Use something different"
[object replacementHasSingleSkipCharacter]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:44}:"-"
[object replacementHasInvalid:0 slotName:1]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:32}:"renameWith:1nonIdentifier:"
}
#endif // IGNORE_UNSUCCESSFUL_RENAMES
// Make sure classes are treated the same way as protocols.
__attribute__((objc_root_class))
@interface Interface
// expected-note@+1 {{has been explicitly marked deprecated here}}
+ (void)classMethod:(int)param1 replacement:(int)param2 DEPRECATED("renameClassMethod:replace_new_ment:");
+ (void)renameClassMethod:(int)param1 replace_new_ment:(int)param2;
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)multi:(int)param1 parameter:(int)param2 replacement:(int)param3 DEPRECATED("multi_new:parameter_new:replace_new_ment:");
- (void)multi_new:(int)param1 parameter_new:(int)param2 replace_new_ment:(int)param3;
@end
@implementation Interface
+ (void)classMethod:(int)param1 replacement:(int)param2 {}
+ (void)renameClassMethod:(int)param1 replace_new_ment:(int)param2 {}
- (void)multi:(int)param1 parameter:(int)param2 replacement:(int)param3 {}
- (void)multi_new:(int)param1 parameter_new:(int)param2 replace_new_ment:(int)param3 {}
- (void)usage {
[Interface classMethod:0 replacement:1]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:25}:"renameClassMethod"
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:28-[[@LINE-2]]:39}:"replace_new_ment"
[self multi:0 parameter:1 replacement:2]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:14}:"multi_new"
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:26}:"parameter_new"
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:29-[[@LINE-3]]:40}:"replace_new_ment"
}
@end
// Make sure availability attribute is handled the same way as deprecation attribute.
@protocol AvailabilityAttributeRenames
// expected-note@+1 {{has been explicitly marked deprecated here}}
- (void)multi:(int)param1 parameter:(int)param2 replacement:(int)param3 __attribute__((availability(macosx,deprecated=9.0,replacement="multi_new:parameter_new:replace_new_ment:")));
- (void)multi_new:(int)param1 parameter_new:(int)param2 replace_new_ment:(int)param3;
@end
void availabilityAttributeRenames(id<AvailabilityAttributeRenames> object) {
[object multi:0 parameter:1 replacement:2]; // expected-warning {{is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:16}:"multi_new"
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:19-[[@LINE-2]]:28}:"parameter_new"
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:31-[[@LINE-3]]:42}:"replace_new_ment"
}

View File

@ -0,0 +1,311 @@
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10.4 -verify -Wno-objc-root-class %s
// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -triple x86_64-apple-darwin10.4 -verify -Wno-objc-root-class %s
@interface A {
int X __attribute__((deprecated)); // expected-note 2 {{'X' has been explicitly marked deprecated here}}
}
+ (void)F __attribute__((deprecated)); // expected-note 2 {{'F' has been explicitly marked deprecated here}}
- (void)f __attribute__((deprecated)); // expected-note 5 {{'f' has been explicitly marked deprecated here}}
@end
@implementation A
+ (void)F __attribute__((deprecated))
{
[self F]; // no warning, since the caller is also deprecated.
}
- (void)g
{
X++; // expected-warning{{'X' is deprecated}}
self->X++; // expected-warning{{'X' is deprecated}}
[self f]; // expected-warning{{'f' is deprecated}}
}
- (void)f
{
[self f]; // no warning, the caller is deprecated in its interface.
}
@end
@interface B: A
@end
@implementation B
+ (void)G
{
[super F]; // expected-warning{{'F' is deprecated}}
}
- (void)g
{
[super f]; // // expected-warning{{'f' is deprecated}}
}
@end
@protocol P
- (void)p __attribute__((deprecated)); // expected-note {{'p' has been explicitly marked deprecated here}}
@end
void t1(A *a)
{
[A F]; // expected-warning{{'F' is deprecated}}
[a f]; // expected-warning{{'f' is deprecated}}
}
void t2(id a)
{
[a f]; // expected-warning {{'f' is deprecated}}
}
void t3(A<P>* a)
{
[a f]; // expected-warning{{'f' is deprecated}}
[a p]; // expected-warning{{'p' is deprecated}}
}
void t4(Class c)
{
[c F];
}
@interface Bar
@property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated)); // expected-note 2 {{'FooBar' has been explicitly marked deprecated here}}
- (void) MySetter : (int) value;
@end
int t5() {
Bar *f;
f.FooBar = 1; // expected-warning {{'FooBar' is deprecated}}
return f.FooBar; // expected-warning {{'FooBar' is deprecated}}
}
__attribute ((deprecated)) // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}}
@interface DEPRECATED {
@public int ivar;
DEPRECATED *ivar2; // no warning.
}
- (int) instancemethod;
- (DEPRECATED *) meth; // no warning.
@property int prop;
@end
@interface DEPRECATED (Category) // no warning.
- (DEPRECATED *) meth2; // no warning.
@end
@interface DEPRECATED (Category2) // no warning.
- (id)meth;
@end
__attribute__((deprecated))
void depr_function();
@implementation DEPRECATED (Category2) // no warning
- (id)meth {
depr_function(); // no warning.
return 0;
}
@end
@interface NS : DEPRECATED // expected-warning {{'DEPRECATED' is deprecated}}
@end
@interface Test2
@property int test2 __attribute__((deprecated)); // expected-note 2 {{property 'test2' is declared deprecated here}} expected-note 3 {{'test2' has been explicitly marked deprecated here}} \
// expected-note {{'setTest2:' has been explicitly marked deprecated here}}
@end
void test(Test2 *foo) {
int x;
x = foo.test2; // expected-warning {{'test2' is deprecated}}
x = [foo test2]; // expected-warning {{'test2' is deprecated}}
foo.test2 = x; // expected-warning {{'test2' is deprecated}}
[foo setTest2: x]; // expected-warning {{'setTest2:' is deprecated}}
}
__attribute__((deprecated))
@interface A(Blah) // no warning
- (A*)getA;
@end
@implementation A(Blah) // Don't warn by default
- (A*)getA {
return self;
}
@end
typedef struct {
int x;
} footype __attribute((deprecated)); // expected-note 2 {{'footype' has been explicitly marked deprecated here}}
@interface foo {
footype a; // expected-warning {{'footype' is deprecated}}
footype b __attribute((deprecated));
}
@property footype c; // expected-warning {{'footype' is deprecated}}
@property footype d __attribute((deprecated));
@end
// rdar://13569424
@interface NewI
+(void)cmeth;
@end
typedef NewI DeprI __attribute__((deprecated("blah"))); // expected-note 4 {{'DeprI' has been explicitly marked deprecated here}}
@interface SI : DeprI // expected-warning {{'DeprI' is deprecated: blah}}
-(DeprI*)meth; // expected-warning {{'DeprI' is deprecated: blah}}
@end
@implementation SI
-(DeprI*)meth { // expected-warning {{'DeprI' is deprecated: blah}}
[DeprI cmeth]; // expected-warning {{'DeprI' is deprecated: blah}}
return 0;
}
@end
// <rdar://problem/15407366> and <rdar://problem/15466783>:
// - Using deprecated class name inside class should not warn about deprecation.
// - Implementations of deprecated classes should not result in deprecation warnings.
__attribute__((deprecated))
@interface DeprecatedClassA
@end
__attribute__((deprecated))
@interface DeprecatedClassB
// The self-reference return value should not be
// flagged as the use of a deprecated declaration.
+ (DeprecatedClassB *)sharedInstance; // no-warning
// Since this class is deprecated, returning a reference
// to another deprecated class is fine as they may
// have been deprecated together. From a user's
// perspective they are all deprecated.
+ (DeprecatedClassA *)somethingElse; // no-warning
@end
@implementation DeprecatedClassB
+ (DeprecatedClassB *)sharedInstance
{
// This self-reference should not
// be flagged as a use of a deprecated
// declaration.
static DeprecatedClassB *x; // no-warning
return x;
}
+ (DeprecatedClassA *)somethingElse {
// Since this class is deprecated, referencing
// another deprecated class is also OK.
static DeprecatedClassA *x; // no-warning
return x;
}
@end
// rdar://16068470
@interface TestBase
@property (nonatomic, strong) id object __attribute__((deprecated("deprecated"))); // expected-note {{'object' has been explicitly marked deprecated here}} \
expected-note {{property 'object' is declared deprecated here}} \
expected-note {{'setObject:' has been explicitly marked deprecated here}} \
expected-note {{property declared here}}
@end
@interface TestDerived : TestBase
@property (nonatomic, strong) id object; //expected-warning {{auto property synthesis will not synthesize property 'object'; it will be implemented by its superclass}}
@end
@interface TestUse @end
@implementation TestBase @end
@implementation TestDerived @end // expected-note {{detected while default synthesizing properties in class implementation}}
@implementation TestUse
- (void) use
{
TestBase *base = (id)0;
TestDerived *derived = (id)0;
id object = (id)0;
base.object = object; // expected-warning {{'object' is deprecated: deprecated}}
derived.object = object;
[base setObject:object]; // expected-warning {{'setObject:' is deprecated: deprecated}}
[derived setObject:object];
}
@end
// rdar://18848183
@interface NSString
- (const char *)cString __attribute__((availability(macosx,introduced=10.0 ,deprecated=10.4,message="" ))); // expected-note {{'cString' has been explicitly marked deprecated here}}
@end
id PID = 0;
const char * func() {
return [PID cString]; // expected-warning {{'cString' is deprecated: first deprecated in macOS 10.4}}
}
// rdar://18960378
@interface NSObject
+ (instancetype)alloc;
- (instancetype)init;
@end
@interface NSLocale
- (instancetype)init __attribute__((unavailable));
@end
@interface PLBatteryProperties : NSObject
+ (id)properties;
@end
@implementation PLBatteryProperties
+ (id)properties {
return [[self alloc] init];
}
@end
@implementation UndeclaredImpl // expected-warning{{cannot find interface declaration}}
- (void)partiallyUnavailableMethod {}
@end
@interface InterfaceWithSameMethodAsUndeclaredImpl
- (void)partiallyUnavailableMethod __attribute__((unavailable));
@end
void f(id a) {
[a partiallyUnavailableMethod]; // no warning, `a` could be an UndeclaredImpl.
}
@interface InterfaceWithImplementation
- (void)anotherPartiallyUnavailableMethod;
@end
@implementation InterfaceWithImplementation
- (void)anotherPartiallyUnavailableMethod {}
@end
@interface InterfaceWithSameMethodAsInterfaceWithImplementation
- (void)anotherPartiallyUnavailableMethod __attribute__((unavailable));
@end
void g(id a) {
[a anotherPartiallyUnavailableMethod]; // no warning, `a` could be an InterfaceWithImplementation.
}
typedef struct {} S1 __attribute__((unavailable)); // expected-note2{{marked unavailable here}}
typedef struct {} S2 __attribute__((deprecated)); // expected-note2{{marked deprecated here}}
@interface ExtensionForMissingInterface() // expected-error{{cannot find interface declaration}}
- (void)method1:(S1) x; // expected-error{{is unavailable}}
- (void)method2:(S2) x; // expected-warning{{is deprecated}}
@end
@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}}
- (void)method1:(S1) x; // expected-error{{is unavailable}}
- (void)method2:(S2) x; // expected-warning{{is deprecated}}
@end

View File

@ -0,0 +1,456 @@
// RUN: %clang_cc1 -fsyntax-only -Wno-incomplete-implementation -verify -fblocks %s
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
#define NS_UNAVAILABLE __attribute__((unavailable))
void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{'objc_designated_initializer' attribute only applies to Objective-C methods}}
@protocol P1
-(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
@end
__attribute__((objc_root_class))
@interface I1
-(void)meth NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
-(id)init NS_DESIGNATED_INITIALIZER;
+(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
@end
@interface I1(cat)
-(id)init2 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
@end
@interface I1()
-(id)init3 NS_DESIGNATED_INITIALIZER;
@end
@implementation I1
-(void)meth {}
-(id)init NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface or class extension declarations}}
+(id)init { return 0; }
-(id)init3 { return 0; }
-(id)init4 NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface or class extension declarations}} \
// expected-warning {{convenience initializer missing a 'self' call to another initializer}}
@end
__attribute__((objc_root_class))
@interface B1
-(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 6 {{method marked as designated initializer of the class here}}
-(id)initB2;
@end
@interface B1()
-(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
@end;
@implementation B1
-(id)initB1 { return 0; }
-(id)initB2 { return 0; } // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
-(id)initB3 { return 0; }
@end
@interface S1 : B1
-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
-(id)initS2 NS_DESIGNATED_INITIALIZER;
-(id)initS3 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
-(id)initB1;
@end
@interface S1()
-(id)initS4 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
@end
@implementation S1
-(id)initS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return 0;
}
-(id)initS2 {
return [super initB1];
}
-(id)initS3 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return [super initB2]; // expected-warning {{designated initializer invoked a non-designated initializer}}
}
-(id)initS4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
}
-(id)initB1 {
return [self initS1];
}
-(id)initB3 {
return [self initS1];
}
@end
@interface S2 : B1
-(id)initB1;
@end
@interface SS2 : S2
-(id)initSS1 NS_DESIGNATED_INITIALIZER;
@end
@implementation SS2 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \
// expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
-(id)initSS1 {
return [super initB1];
}
@end
@interface S3 : B1
-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
@end
@interface SS3 : S3
-(id)initSS1 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
@end
@implementation SS3 // expected-warning {{method override for the designated initializer of the superclass '-initS1' not found}}
-(id)initSS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return [super initB1]; // expected-warning {{designated initializer invoked a non-designated initializer}}
}
@end
@interface S4 : B1
-(id)initB1;
-(id)initB3;
@end
@implementation S4
-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return 0;
}
-(id)initB3 {
return [super initB3];
}
@end
@interface S5 : B1
-(void)meth;
@end
@implementation S5
-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return 0;
}
-(id)initB3 {
[self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
S5 *s;
[s initB1];
[self meth];
void (^blk)(void) = ^{
[self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
};
return [super initB3];
}
-(void)meth {}
@end
@interface S6 : B1
-(id)initS1 NS_DESIGNATED_INITIALIZER;
-(id)initS2;
-(id)initS3;
-(id)initS4;
@end
@implementation S6 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \
// expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
-(id)initS1 {
return [super initB1];
}
-(id)initS2 { // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
return [super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}}
}
-(id)initS3 {
return [self initB1];
}
-(id)initS4 {
return [self initS1];
}
-(id)initS5 {
[super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}}
void (^blk)(void) = ^{
[super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}}
};
return [self initS1];
}
-(id)initS6 { // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
S6 *s;
return [s initS1];
}
@end
@interface SS4 : S4
-(id)initB1;
@end
@implementation SS4
-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return 0;
}
@end
@interface S7 : B1
-(id)initB1;
-(id)initB3;
-(id)initNewOne;
@end
@interface SS7 : S7
-(id)initB1;
@end
@implementation SS7
-(id)initB1 {
return 0;
}
@end
__attribute__((objc_root_class))
@interface B2
-(id)init;
@end
@interface S8: B2
-(id)initS8 NS_DESIGNATED_INITIALIZER;
@end
@implementation S8
-(id)initS8
{
return [super init];
}
@end
@interface S9 : B1
-(id)initB1;
-(id)initB3;
@end
@interface S9(secondInit)
-(id)initNewOne;
@end
@interface SS9 : S9
-(id)initB1;
@end
@implementation SS9
-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return 0;
}
@end
// rdar://16261494
@class GEOPDAnalyticMetadata; // expected-note {{forward declaration of class here}}
@implementation GEOPDAnalyticMetadata (PlaceCardExtras) // expected-error {{cannot find interface declaration for 'GEOPDAnalyticMetadata'}}
- (instancetype)initInProcess
{
return ((void*)0);
}
@end
// rdar://16305460
__attribute__((objc_root_class))
@interface MyObject
- (instancetype)initWithStuff:(id)stuff __attribute__((objc_designated_initializer));
- (instancetype)init NS_UNAVAILABLE;
@end
@implementation MyObject
- (instancetype)init
{
return ((void*)0);
}
@end
// rdar://16323233
__attribute__((objc_root_class))
@interface B4
-(id)initB4 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
-(id)initNonDI;
@end
@interface rdar16323233 : B4
-(id)initS4 NS_DESIGNATED_INITIALIZER;
@end
@implementation rdar16323233
-(id)initS4 {
static id sSharedObject = (void*)0;
(void)^(void) {
sSharedObject = [super initB4];
};
return 0;
}
-(id)initB4 {
return [self initS4];
}
@end
@interface S1B4 : B4
@end
@implementation S1B4
-(id)initB4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return [super initNonDI]; // expected-warning {{designated initializer invoked a non-designated initializer}}
}
@end
@interface S2B4 : B4
-(id)initB4;
@end
@implementation S2B4
-(id)initB4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return [super initNonDI]; // expected-warning {{designated initializer invoked a non-designated initializer}}
}
@end
@interface S3B4 : B4
@end
@implementation S3B4
-(id)initNew {
return [super initB4];
}
-(id)initB4 {
return [self initNew];
}
@end
@interface S4B4 : B4
-(id)initNew;
@end
@implementation S4B4
-(id)initNew {
return [super initB4];
}
-(id)initB4 {
return [self initNew];
}
@end
@interface S5B4 : B4
-(id)initB4;
@end
@implementation S5B4
-(id)initNew {
return [super initB4];
}
-(id)initB4 {
return [self initNew];
}
@end
@interface S6B4 : B4
-(id)initNew;
-(id)initB4;
@end
@implementation S6B4
-(id)initNew {
return [super initB4];
}
-(id)initB4 {
return [self initNew];
}
@end
__attribute__((objc_root_class))
@interface NSObject
-(instancetype) init NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
@end
@interface Test3 : NSObject
@end
@implementation Test3
-(instancetype) initWithBasePath:(id)path {
return [super init];
}
-(instancetype) init {
return [self initWithBasePath:0];
}
@end
@interface Test1 : NSObject
-(instancetype) init NS_DESIGNATED_INITIALIZER;
@end
@implementation Test1
-(instancetype) init {
return self;
}
@end
@interface SubTest1 : Test1
-(instancetype)init NS_UNAVAILABLE;
-(instancetype)initWithRequiredParameter:(id)foo NS_DESIGNATED_INITIALIZER;
@end
@implementation SubTest1
-(instancetype)initWithRequiredParameter:(id)foo {
return [super init];
}
@end
@interface SubTest1Ext : Test1
-(instancetype)initWithRequiredParameter:(id)foo NS_DESIGNATED_INITIALIZER;
@end
// Mark 'init' as unavailable in the extension to silence warning.
@interface SubTest1Ext()
-(instancetype)init NS_UNAVAILABLE;
@end
@implementation SubTest1Ext
-(instancetype)initWithRequiredParameter:(id)foo {
return [super init];
}
@end
@interface Test2 : NSObject
@end
@interface SubTest2 : Test2
@end
@implementation SubTest2
-(instancetype) init { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return self;
}
@end
__attribute__((objc_root_class))
@interface RootNoDI
-(id)init;
@end
@interface Base : RootNoDI
@end
@implementation Base
@end
@interface Derived : Base
- (instancetype)initWithInt:(int)n NS_DESIGNATED_INITIALIZER;
@end
@implementation Derived
- (instancetype)initWithInt:(int)n
{
return [super init];
}
@end
@interface ExtensionForMissingInterface() // expected-error{{cannot find interface declaration}}
- (instancetype)init NS_DESIGNATED_INITIALIZER;
@end
@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}}
- (instancetype)init NS_DESIGNATED_INITIALIZER; // expected-error{{only applies to init methods of interface or class extension declarations}}
@end
@interface TwoAttrs
-(instancetype)foo
__attribute__((objc_designated_initializer))
__attribute__((objc_method_family(init)));
-(instancetype)bar
__attribute__((objc_method_family(init)))
__attribute__((objc_designated_initializer));
-(instancetype)baz
__attribute__((objc_designated_initializer, objc_method_family(init)));
-(instancetype)quux
__attribute__((objc_method_family(init), objc_designated_initializer));
@end

View File

@ -0,0 +1,16 @@
// RUN: %clang_cc1 -verify -fsyntax-only -fblocks %s
@interface TestAttrMallocOnMethods {}
- (id) test1 __attribute((malloc)); // expected-warning {{attribute only applies to functions}}
- (int) test2 __attribute((malloc)); // expected-warning {{attribute only applies to functions}}
@end
id bar(void) __attribute((malloc)); // no-warning
typedef void (^bptr)(void);
bptr baz(void) __attribute((malloc)); // no-warning
__attribute((malloc)) id (*f)(); // expected-warning {{attribute only applies to functions}}
__attribute((malloc)) bptr (*g)(); // expected-warning {{attribute only applies to functions}}
__attribute((malloc)) void *(^h)(); // expected-warning {{attribute only applies to functions}}

View File

@ -0,0 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// expected-no-diagnostics
@interface NSObject
- (void)doSomething __attribute__((nodebug));
@end

View File

@ -0,0 +1,18 @@
// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fblocks -verify %s
// rdar://20130079
#if __has_feature(objc_arc)
__attribute__((ns_returns_retained)) id (^invalidBlockRedecl)(); // expected-note {{previous definition is here}}
id (^invalidBlockRedecl)(); //expected-error {{redefinition of 'invalidBlockRedecl' with a different type: 'id (^__strong)()' vs 'id ((^__strong))() __attribute__((ns_returns_retained))'}}
#else
__attribute__((ns_returns_retained)) id (^invalidBlockRedecl)();
id (^invalidBlockRedecl)();
#endif
typedef __attribute__((ns_returns_retained)) id (^blockType)();
typedef __attribute__((ns_returns_retained)) int (^invalidBlockType)(); // expected-warning {{'ns_returns_retained' attribute only applies to functions that return an Objective-C object}}
__attribute__((ns_returns_retained)) int functionDecl(); // expected-warning {{'ns_returns_retained' attribute only applies to functions that return an Objective-C object}}

View File

@ -0,0 +1,16 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify
__attribute__((__objc_exception__))
@interface NSException {
int x;
}
@end
__attribute__((__objc_exception__)) // expected-error {{'__objc_exception__' attribute only applies to Objective-C interfaces}}
int X;
__attribute__((__objc_exception__)) // expected-error {{'__objc_exception__' attribute only applies to Objective-C interfaces}}
void foo();

View File

@ -0,0 +1,30 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
static id __attribute((objc_gc(weak))) a;
static id __attribute((objc_gc(strong))) b;
static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute requires a string}}
static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' attribute requires a string}}
static id __attribute((objc_gc(foo, 456))) e; // expected-error{{'objc_gc' attribute takes one argument}}
static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' attribute argument not supported: '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 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_ownership' only applies to Objective-C object or block pointer types; type here is 'int'}}
/* 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
void test2(id __attribute((objc_gc(strong))) *strong,
id __attribute((objc_gc(weak))) *weak) {
void *opaque;
opaque = strong;
strong = opaque;
opaque = weak;
weak = opaque;
}

View File

@ -0,0 +1,39 @@
// RUN: %clang_cc1 -verify -Wno-objc-root-class -fsyntax-only %s
__attribute__((objc_nonlazy_class))
@interface A
@end
@implementation A
@end
__attribute__((objc_nonlazy_class)) int X; // expected-error {{'objc_nonlazy_class' attribute only applies to Objective-C interfaces}}
__attribute__((objc_nonlazy_class()))
@interface B
@end
@implementation B
@end
__attribute__((objc_nonlazy_class("foo"))) // expected-error{{'objc_nonlazy_class' attribute takes no arguments}}
@interface C
@end
@implementation C
@end
__attribute__((objc_nonlazy_class)) // expected-error {{'objc_nonlazy_class' attribute only applies to Objective-C interfaces}}
@protocol B
@end
__attribute__((objc_nonlazy_class)) // expected-error {{'objc_nonlazy_class' attribute only applies to Objective-C interfaces}}
void foo();
@interface E
@end
__attribute__((objc_nonlazy_class))
@implementation E
@end
__attribute__((objc_nonlazy_class))
@implementation E (MyCat)
@end

View File

@ -0,0 +1,19 @@
// RUN: %clang_cc1 -verify -fsyntax-only %s
__attribute__((objc_runtime_visible))
@interface A
@end
@interface A(X)
@end
@implementation A(X) // expected-error{{cannot implement a category for class 'A' that is only visible via the Objective-C runtime}}
@end
@interface B : A
@end
@implementation B // expected-error{{cannot implement subclass 'B' of a superclass 'A' that is only visible via the Objective-C runtime}}
@end

View File

@ -0,0 +1,9 @@
// RUN: %clang_cc1 %s -fobjc-arc -ast-print | FileCheck %s
__strong id x;
id y;
__strong id z;
// CHECK: __strong id x;
// CHECK-NOT: __strong id y;
// CHECK: __strong id z;

View File

@ -0,0 +1,20 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wattributes -Wobjc-root-class %s
@interface RootClass {} // expected-warning {{class 'RootClass' defined without specifying a base class}} \
// expected-note {{add a super class to fix this problem}}
@end
@implementation RootClass
@end
__attribute__((objc_root_class))
@interface NonRootClass : RootClass // expected-error {{objc_root_class attribute may only be specified on a root class declaration}}
@end
@implementation NonRootClass
@end
__attribute__((objc_root_class)) static void nonClassDeclaration() // expected-error {{'objc_root_class' attribute only applies to Objective-C interfaces}}
{
}
__attribute__((objc_root_class(1))) // expected-error {{'objc_root_class' attribute takes no arguments}}
@interface I1
@end

View File

@ -0,0 +1,102 @@
// RUN: %clang_cc1 %s -fblocks -fsyntax-only -verify
#define ASYNC(...) __attribute__((swift_async(__VA_ARGS__)))
#define ASYNC_ERROR(...) __attribute__((swift_async_error(__VA_ARGS__)))
ASYNC(swift_private, 1)
ASYNC_ERROR(zero_argument, 1)
void test_good(void (^handler)(int));
ASYNC(swift_private, 2)
ASYNC_ERROR(nonzero_argument, 2)
void test_good2(double, void (^handler)(double, int, double));
enum SomeEnum { SE_a, SE_b };
ASYNC(swift_private, 1)
ASYNC_ERROR(nonzero_argument, 1)
void test_good3(void (^handler)(enum SomeEnum, double));
ASYNC_ERROR(zero_argument, 1)
ASYNC(swift_private, 1)
void test_rev_order(void (^handler)(int));
@class NSError;
ASYNC(swift_private, 1)
ASYNC_ERROR(nonnull_error)
void test_nserror(void (^handler)(NSError *));
typedef struct __attribute__((objc_bridge(NSError))) __CFError * CFErrorRef;
ASYNC(swift_private, 1)
ASYNC_ERROR(nonnull_error)
void test_cferror(void (^handler)(CFErrorRef));
ASYNC(swift_private, 1)
ASYNC_ERROR(nonnull_error) // expected-error {{'swift_async_error' attribute with 'nonnull_error' convention can only be applied to a function with a completion handler with an error parameter}}
void test_interror(void (^handler)(int));
ASYNC(swift_private, 1)
ASYNC_ERROR(zero_argument, 1) // expected-error {{'swift_async_error' attribute with 'zero_argument' convention must have an integral-typed parameter in completion handler at index 1, type here is 'double'}}
void test_not_integral(void (^handler)(double));
ASYNC(swift_private, 1)
ASYNC_ERROR(none)
void test_none(void (^)());
ASYNC(none)
ASYNC_ERROR(none)
void test_double_none(void (^)());
ASYNC(none)
ASYNC_ERROR(none, 1) // expected-error {{'swift_async_error' attribute takes one argument}}
void test_double_none_args();
ASYNC(swift_private, 1)
ASYNC_ERROR(nonnull_error, 1) // expected-error{{'swift_async_error' attribute takes one argument}}
void test_args(void (^)(void));
ASYNC(swift_private, 1)
ASYNC_ERROR(zero_argument, 1, 1) // expected-error{{'swift_async_error' attribute takes no more than 2 arguments}}
void test_args2(void (^)(int));
ASYNC_ERROR(none) int x; // expected-warning{{'swift_async_error' attribute only applies to functions and Objective-C methods}}
@interface ObjC
-(void)m1:(void (^)(int))handler
ASYNC(swift_private, 1)
ASYNC_ERROR(zero_argument, 1);
-(void)m2:(int)first withSecond:(void (^)(int))handler
ASYNC(swift_private, 2)
ASYNC_ERROR(nonzero_argument, 1);
-(void)m3:(void (^)(void))block
ASYNC_ERROR(zero_argument, 1) // expected-error {{'swift_async_error' attribute parameter 2 is out of bounds}}
ASYNC(swift_private, 1);
-(void)m4:(void (^)(double, int, float))handler
ASYNC(swift_private, 1)
ASYNC_ERROR(nonzero_argument, 1); // expected-error{{swift_async_error' attribute with 'nonzero_argument' convention must have an integral-typed parameter in completion handler at index 1, type here is 'double'}}
-(void)m5:(void (^)(NSError *))handler
ASYNC(swift_private, 1)
ASYNC_ERROR(nonnull_error);
-(void)m6:(void (^)(void *))handler
ASYNC(swift_private, 1)
ASYNC_ERROR(nonnull_error); // expected-error{{'swift_async_error' attribute with 'nonnull_error' convention can only be applied to a method with a completion handler with an error parameter}}
@end
// 'swift_error' and 'swift_async_error' are OK on one function.
ASYNC(swift_private, 1)
ASYNC_ERROR(nonnull_error)
__attribute__((swift_error(nonnull_error)))
void swift_error_and_swift_async_error(void (^handler)(NSError *), NSError **);
@interface TestNoSwiftAsync
// swift_async_error can make sense without swift_async.
-(void)doAThingWithCompletion:(void (^)(NSError *))completion
ASYNC_ERROR(nonnull_error);
@end

View File

@ -0,0 +1,38 @@
// RUN: %clang_cc1 -verify -fsyntax-only -fblocks %s
// RUN: %clang_cc1 -xobjective-c++ -verify -fsyntax-only -fblocks %s
#define SA(...) __attribute__((swift_async(__VA_ARGS__)))
SA(none) int a; // expected-warning{{'swift_async' attribute only applies to functions and Objective-C methods}}
SA(none) void b();
SA(not_swift_private, 0) void c(); // expected-error{{'swift_async' attribute parameter 2 is out of bounds}}
SA(swift_private, 1) void d(); // expected-error{{'swift_async' attribute parameter 2 is out of bounds}}
SA(swift_private, 1) void e(int); // expected-error{{'swift_async' completion handler parameter must have block type returning 'void', type here is 'int'}}
SA(not_swift_private, 1) void f(int (^)()); // expected-error{{'swift_async' completion handler parameter must have block type returning 'void', type here is 'int (^)()'}}
SA(swift_private, 1) void g(void (^)());
SA(none, 1) void h(); // expected-error{{'swift_async' attribute takes one argument}}
SA() void i(); // expected-error{{'swift_async' attribute takes at least 1 argument}}
SA(not_swift_private) void j(); // expected-error{{'swift_async' attribute requires exactly 2 arguments}}
SA(43) void k(); // expected-error{{'swift_async' attribute requires parameter 1 to be an identifier}}
SA(not_a_thing, 0) void l(); // expected-error{{first argument to 'swift_async' must be either 'none', 'swift_private', or 'not_swift_private'}}
@interface TestOnMethods
-(void)m1:(int (^)())callback SA(swift_private, 1); // expected-error{{'swift_async' completion handler parameter must have block type returning 'void', type here is 'int (^)()'}}
-(void)m2:(void (^)())callback SA(swift_private, 0); // expected-error{{'swift_async' attribute parameter 2 is out of bounds}}
-(void)m3:(void (^)())callback SA(swift_private, 2); // expected-error{{'swift_async' attribute parameter 2 is out of bounds}}
-(void)m4 SA(none);
-(void)m5:(int)p handler:(void (^)(int))callback SA(not_swift_private, 2);
@end
#ifdef __cplusplus
struct S {
SA(none) void mf1();
SA(swift_private, 2) void mf2(void (^)());
SA(swift_private, 1) void mf3(void (^)()); // expected-error{{'swift_async' attribute is invalid for the implicit this argument}}
SA(swift_private, 0) void mf4(void (^)()); // expected-error{{'swift_async' attribute parameter 2 is out of bounds}}
SA(not_swift_private, 2) void mf5(int (^)()); // expected-error{{'swift_async' completion handler parameter must have block type returning 'void', type here is 'int (^)()'}}
};
#endif

View File

@ -0,0 +1,93 @@
// RUN: %clang_cc1 -verify -fsyntax-only -fobjc-arc -fblocks %s
@class NSError;
#if __SIZEOF_POINTER__ == 4
typedef unsigned char BOOL;
#else
typedef _Bool BOOL;
#endif
typedef struct __attribute__((__objc_bridge__(NSError))) __CFError *CFErrorRef;
extern int f0(void) __attribute__((__swift_error__));
// expected-error@-1 {{'__swift_error__' attribute takes one argument}}
extern int f1(void) __attribute__((__swift_error__(invalid)));
// expected-warning@-1 {{'__swift_error__' attribute argument not supported: 'invalid'}}
extern int f2(void) __attribute__((__swift_error__(none,zero_result)));
// expected-error@-1 {{use of undeclared identifier 'zero_result'}}
@interface Erroneous
- (BOOL)m0:(NSError **)error __attribute__((__swift_error__(none)));
- (BOOL)m1:(NSError **)error __attribute__((__swift_error__(nonnull_error)));
- (BOOL)m2:(NSError **)error __attribute__((__swift_error__(null_result)));
// expected-error@-1 {{'__swift_error__' attribute with 'null_result' convention can only be applied to a method returning a pointer}}
- (BOOL)m3:(NSError **)error __attribute__((__swift_error__(nonzero_result)));
- (BOOL)m4:(NSError **)error __attribute__((__swift_error__(zero_result)));
- (Undeclared)n0:(NSError **)error __attribute__((__swift_error__(none)));
// expected-error@-1 {{expected a type}}
- (Undeclared)n1:(NSError **)error __attribute__((__swift_error__(nonnull_error)));
// expected-error@-1 {{expected a type}}
- (Undeclared)n2:(NSError **)error __attribute__((__swift_error__(null_result)));
// expected-error@-1 {{expected a type}}
- (Undeclared)n3:(NSError **)error __attribute__((__swift_error__(nonzero_result)));
// expected-error@-1 {{expected a type}}
// FIXME: the follow-on warning should really be suppressed, but apparently
// having an ill-formed return type doesn't mark anything as invalid.
// expected-error@-4 {{can only be applied}}
- (Undeclared)n4:(NSError **)error __attribute__((__swift_error__(zero_result)));
// expected-error@-1 {{expected a type}}
// FIXME: the follow-on warning should really be suppressed, but apparently
// having an ill-formed return type doesn't mark anything as invalid.
// expected-error@-4 {{can only be applied}}
- (instancetype)o0 __attribute__((__swift_error__(none)));
- (instancetype)o1 __attribute__((__swift_error__(nonnull_error)));
// expected-error@-1 {{'__swift_error__' attribute can only be applied to a method with an error parameter}}
- (instancetype)o2 __attribute__((__swift_error__(null_result)));
// expected-error@-1 {{'__swift_error__' attribute can only be applied to a method with an error parameter}}
- (instancetype)o3 __attribute__((__swift_error__(nonzero_result)));
// expected-error@-1 {{'__swift_error__' attribute can only be applied to a method with an error parameter}}
- (instancetype)o4 __attribute__((__swift_error__(zero_result)));
// expected-error@-1 {{'__swift_error__' attribute can only be applied to a method with an error parameter}}
@end
extern BOOL m0(CFErrorRef *) __attribute__((__swift_error__(none)));
extern BOOL m1(CFErrorRef *) __attribute__((__swift_error__(nonnull_error)));
extern BOOL m2(CFErrorRef *) __attribute__((__swift_error__(null_result)));
// expected-error@-1 {{'__swift_error__' attribute with 'null_result' convention can only be applied to a function returning a pointer}}
extern BOOL m3(CFErrorRef *) __attribute__((__swift_error__(nonzero_result)));
extern BOOL m4(CFErrorRef *) __attribute__((__swift_error__(zero_result)));
extern Undeclared n0(CFErrorRef *) __attribute__((__swift_error__(none)));
// expected-error@-1 {{unknown type name 'Undeclared'}}
extern Undeclared n1(CFErrorRef *) __attribute__((__swift_error__(nonnull_error)));
// expected-error@-1 {{unknown type name 'Undeclared'}}
extern Undeclared n2(CFErrorRef *) __attribute__((__swift_error__(null_result)));
// expected-error@-1 {{unknown type name 'Undeclared'}}
extern Undeclared n3(CFErrorRef *) __attribute__((__swift_error__(nonzero_result)));
// expected-error@-1 {{unknown type name 'Undeclared'}}
extern Undeclared n4(CFErrorRef *) __attribute__((__swift_error__(zero_result)));
// expected-error@-1 {{unknown type name 'Undeclared'}}
extern void *o0(CFErrorRef *) __attribute__((__swift_error__(none)));
extern void *o1(CFErrorRef *) __attribute__((__swift_error__(nonnull_error)));
extern void *o2(CFErrorRef *) __attribute__((__swift_error__(null_result)));
extern void *o3(CFErrorRef *) __attribute__((__swift_error__(nonzero_result)));
// expected-error@-1 {{'__swift_error__' attribute with 'nonzero_result' convention can only be applied to a function returning an integral type}}
extern void *o4(CFErrorRef *) __attribute__((__swift_error__(zero_result)));
// expected-error@-1 {{'__swift_error__' attribute with 'zero_result' convention can only be applied to a function returning an integral type}}
extern void *p0(void) __attribute__((__swift_error__(none)));
extern void *p1(void) __attribute__((__swift_error__(nonnull_error)));
// expected-error@-1 {{'__swift_error__' attribute can only be applied to a function with an error parameter}}
extern void *p2(void) __attribute__((__swift_error__(null_result)));
// expected-error@-1 {{'__swift_error__' attribute can only be applied to a function with an error parameter}}
extern void *p3(void) __attribute__((__swift_error__(nonzero_result)));
// expected-error@-1 {{'__swift_error__' attribute can only be applied to a function with an error parameter}}
extern void *p4(void) __attribute__((__swift_error__(zero_result)));
// expected-error@-1 {{'__swift_error__' attribute can only be applied to a function with an error parameter}}
extern BOOL b __attribute__((__swift_error__(none)));
// expected-error@-1 {{attribute only applies to functions and Objective-C methods}}

View File

@ -0,0 +1,38 @@
// RUN: %clang_cc1 -verify -fsyntax-only %s
// expected-error@+1 {{'__swift_bridge__' attribute takes one argument}}
__attribute__((__swift_bridge__))
@interface I
@end
// expected-error@+1 {{'__swift_bridge__' attribute requires a string}}
__attribute__((__swift_bridge__(1)))
@interface J
@end
// expected-error@+1 {{'__swift_bridge__' attribute takes one argument}}
__attribute__((__swift_bridge__("K", 1)))
@interface K
@end
@interface L
// expected-error@+1 {{'__swift_bridge__' attribute only applies to tag types, typedefs, Objective-C interfaces, and Objective-C protocols}}
- (void)method __attribute__((__swift_bridge__("method")));
@end
__attribute__((__swift_bridge__("Array")))
@interface NSArray
@end
__attribute__((__swift_bridge__("ProtocolP")))
@protocol P
@end
typedef NSArray *NSArrayAlias __attribute__((__swift_bridge__("ArrayAlias")));
struct __attribute__((__swift_bridge__("StructT"))) T {};
// Duplicate attributes with the same arguments are fine.
struct __attribute__((swift_bridge("foo"), swift_bridge("foo"))) S;
// Duplicate attributes with different arguments are not.
struct __attribute__((swift_bridge("foo"), swift_bridge("bar"))) S; // expected-warning {{attribute 'swift_bridge' is already applied with different arguments}}

View File

@ -0,0 +1,14 @@
// RUN: %clang_cc1 -verify -fsyntax-only %s
@interface NSString
@end
typedef NSString *NSStringAlias __attribute__((__swift_bridged_typedef__));
typedef int IntAlias __attribute__((__swift_bridged_typedef__));
struct __attribute__((swift_bridged_typedef)) S {};
// expected-error@-1 {{'swift_bridged_typedef' attribute only applies to typedefs}}
typedef unsigned char UnsignedChar __attribute__((__swift_bridged_typedef__("UnsignedChar")));
// expected-error@-1 {{'__swift_bridged_typedef__' attribute takes no arguments}}

View File

@ -0,0 +1,205 @@
// RUN: %clang_cc1 -verify -fsyntax-only -fobjc-arc -fblocks %s
#define SWIFT_NAME(name) __attribute__((__swift_name__(name)))
#define SWIFT_ASYNC_NAME(name) __attribute__((__swift_async_name__(name)))
typedef struct {
float x, y, z;
} Point3D;
__attribute__((__swift_name__("PType")))
@protocol P
@end
__attribute__((__swift_name__("IClass")))
@interface I<P>
- (instancetype)init SWIFT_NAME("init()");
- (instancetype)initWithValue:(int)value SWIFT_NAME("iWithValue(_:)");
+ (void)refresh SWIFT_NAME("refresh()");
- (instancetype)i SWIFT_NAME("i()");
- (I *)iWithValue:(int)value SWIFT_NAME("i(value:)");
- (I *)iWithValue:(int)value value:(int)value2 SWIFT_NAME("i(value:extra:)");
- (I *)iWithValueConvertingValue:(int)value value:(int)value2 SWIFT_NAME("i(_:extra:)");
+ (I *)iWithOtheValue:(int)value SWIFT_NAME("init");
// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
+ (I *)iWithAnotherValue:(int)value SWIFT_NAME("i()");
// expected-warning@-1 {{too few parameters in the signature specified by the '__swift_name__' attribute (expected 1; got 0)}}
+ (I *)iWithYetAnotherValue:(int)value SWIFT_NAME("i(value:extra:)");
// expected-warning@-1 {{too many parameters in the signature specified by the '__swift_name__' attribute (expected 1; got 2}}
+ (I *)iAndReturnErrorCode:(int *)errorCode SWIFT_NAME("i()"); // no-warning
+ (I *)iWithValue:(int)value andReturnErrorCode:(int *)errorCode SWIFT_NAME("i(value:)"); // no-warning
+ (I *)iFromErrorCode:(const int *)errorCode SWIFT_NAME("i()");
// expected-warning@-1 {{too few parameters in the signature specified by the '__swift_name__' attribute (expected 1; got 0)}}
+ (I *)iWithPointerA:(int *)value andReturnErrorCode:(int *)errorCode SWIFT_NAME("i()"); // no-warning
+ (I *)iWithPointerB:(int *)value andReturnErrorCode:(int *)errorCode SWIFT_NAME("i(pointer:)"); // no-warning
+ (I *)iWithPointerC:(int *)value andReturnErrorCode:(int *)errorCode SWIFT_NAME("i(pointer:errorCode:)"); // no-warning
+ (I *)iWithOtherI:(I *)other SWIFT_NAME("i()");
// expected-warning@-1 {{too few parameters in the signature specified by the '__swift_name__' attribute (expected 1; got 0)}}
+ (instancetype)specialI SWIFT_NAME("init(options:)");
+ (instancetype)specialJ SWIFT_NAME("init(options:extra:)");
// expected-warning@-1 {{too many parameters in the signature specified by the '__swift_name__' attribute (expected 0; got 2)}}
+ (instancetype)specialK SWIFT_NAME("init(_:)");
// expected-warning@-1 {{too many parameters in the signature specified by the '__swift_name__' attribute (expected 0; got 1)}}
+ (instancetype)specialL SWIFT_NAME("i(options:)");
// expected-warning@-1 {{too many parameters in the signature specified by the '__swift_name__' attribute (expected 0; got 1)}}
+ (instancetype)trailingParen SWIFT_NAME("foo(");
// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
+ (instancetype)trailingColon SWIFT_NAME("foo:");
// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
+ (instancetype)initialIgnore:(int)value SWIFT_NAME("_(value:)");
// expected-warning@-1 {{'__swift_name__' attribute has invalid identifier for the base name}}
+ (instancetype)middleOmitted:(int)value SWIFT_NAME("i(:)");
// expected-warning@-1 {{'__swift_name__' attribute has invalid identifier for the parameter name}}
@property(strong) id someProp SWIFT_NAME("prop");
@end
enum SWIFT_NAME("E") E {
value1,
value2,
value3 SWIFT_NAME("three"),
value4 SWIFT_NAME("four()"), // expected-warning {{'__swift_name__' attribute has invalid identifier for the base name}}
};
struct SWIFT_NAME("TStruct") SStruct {
int i, j, k SWIFT_NAME("kay");
};
int i SWIFT_NAME("g_i");
void f0(int i) SWIFT_NAME("f_0");
// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
void f1(int i) SWIFT_NAME("f_1()");
// expected-warning@-1 {{too few parameters in the signature specified by the '__swift_name__' attribute (expected 1; got 0)}}
void f2(int i) SWIFT_NAME("f_2(a:b:)");
// expected-warning@-1 {{too many parameters in the signature specified by the '__swift_name__' attribute (expected 1; got 2)}}
void f3(int x, int y) SWIFT_NAME("fWithX(_:y:)");
void f4(int x, int *error) SWIFT_NAME("fWithX(_:)");
typedef int int_t SWIFT_NAME("IntType");
struct Point3D createPoint3D(float x, float y, float z) SWIFT_NAME("Point3D.init(x:y:z:)");
struct Point3D rotatePoint3D(Point3D point, float radians) SWIFT_NAME("Point3D.rotate(self:radians:)");
struct Point3D badRotatePoint3D(Point3D point, float radians) SWIFT_NAME("Point3D.rotate(radians:)");
// expected-warning@-1 {{too few parameters in the signature specified by the '__swift_name__' attribute (expected 2; got 1)}}
extern struct Point3D identityPoint SWIFT_NAME("Point3D.identity");
float Point3DGetMagnitude(Point3D point) SWIFT_NAME("getter:Point3D.magnitude(self:)");
float Point3DGetMagnitudeAndSomethingElse(Point3D point, float f) SWIFT_NAME("getter:Point3D.magnitude(self:f:)");
// expected-warning@-1 {{'__swift_name__' attribute for getter must not have any parameters besides 'self:'}}
float Point3DGetRadius(Point3D point) SWIFT_NAME("getter:Point3D.radius(self:)");
void Point3DSetRadius(Point3D point, float radius) SWIFT_NAME("setter:Point3D.radius(self:newValue:)");
float Point3DPreGetRadius(Point3D point) SWIFT_NAME("getter:Point3D.preRadius(self:)");
void Point3DPreSetRadius(float radius, Point3D point) SWIFT_NAME("setter:Point3D.preRadius(newValue:self:)");
void Point3DSetRadiusAndSomethingElse(Point3D point, float radius, float f) SWIFT_NAME("setter:Point3D.radius(self:newValue:f:)");
// expected-warning@-1 {{'__swift_name__' attribute for setter must have one parameter for new value}}
float Point3DGetComponent(Point3D point, unsigned index) SWIFT_NAME("getter:Point3D.subscript(self:_:)");
float Point3DSetComponent(Point3D point, unsigned index, float value) SWIFT_NAME("setter:Point3D.subscript(self:_:newValue:)");
float Point3DGetMatrixComponent(Point3D point, unsigned x, unsigned y) SWIFT_NAME("getter:Point3D.subscript(self:x:y:)");
void Point3DSetMatrixComponent(Point3D point, unsigned x, float value, unsigned y) SWIFT_NAME("setter:Point3D.subscript(self:x:newValue:y:)");
float Point3DSetWithoutNewValue(Point3D point, unsigned x, unsigned y) SWIFT_NAME("setter:Point3D.subscript(self:x:y:)");
// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' setter must have a 'newValue:' parameter}}
float Point3DSubscriptButNotGetterSetter(Point3D point, unsigned x) SWIFT_NAME("Point3D.subscript(self:_:)");
// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' must be a getter or setter}}
void Point3DSubscriptSetterTwoNewValues(Point3D point, unsigned x, float a, float b) SWIFT_NAME("setter:Point3D.subscript(self:_:newValue:newValue:)");
// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' setter cannot have multiple 'newValue:' parameters}}
float Point3DSubscriptGetterNewValue(Point3D point, unsigned x, float a, float b) SWIFT_NAME("getter:Point3D.subscript(self:_:newValue:newValue:)");
// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' getter cannot have a 'newValue:' parameter}}
void Point3DMethodWithNewValue(Point3D point, float newValue) SWIFT_NAME("Point3D.method(self:newValue:)");
void Point3DMethodWithNewValues(Point3D point, float newValue, float newValueB) SWIFT_NAME("Point3D.method(self:newValue:newValue:)");
float Point3DStaticSubscript(unsigned x) SWIFT_NAME("getter:Point3D.subscript(_:)");
// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' must have a 'self:' parameter}}
float Point3DStaticSubscriptNoArgs(void) SWIFT_NAME("getter:Point3D.subscript()");
// expected-warning@-1 {{'__swift_name__' attribute for 'subscript' must have at least one parameter}}
float Point3DPreGetComponent(Point3D point, unsigned index) SWIFT_NAME("getter:Point3D.subscript(self:_:)");
Point3D getCurrentPoint3D(void) SWIFT_NAME("getter:currentPoint3D()");
void setCurrentPoint3D(Point3D point) SWIFT_NAME("setter:currentPoint3D(newValue:)");
Point3D getLastPoint3D(void) SWIFT_NAME("getter:lastPoint3D()");
void setLastPoint3D(Point3D point) SWIFT_NAME("setter:lastPoint3D(newValue:)");
Point3D getZeroPoint(void) SWIFT_NAME("getter:Point3D.zero()");
void setZeroPoint(Point3D point) SWIFT_NAME("setter:Point3D.zero(newValue:)");
Point3D getZeroPointNoPrototype() SWIFT_NAME("getter:Point3D.zeroNoPrototype()");
// expected-warning@-1 {{'__swift_name__' attribute only applies to non-K&R-style functions}}
Point3D badGetter1(int x) SWIFT_NAME("getter:bad1(_:)");
// expected-warning@-1 {{'__swift_name__' attribute for getter must not have any parameters besides 'self:'}}
void badSetter1(void) SWIFT_NAME("getter:bad1())");
// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
Point3D badGetter2(Point3D point) SWIFT_NAME("getter:bad2(_:))");
// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
void badSetter2(Point3D point) SWIFT_NAME("setter:bad2(self:))");
// expected-warning@-1 {{'__swift_name__' attribute argument must be a string literal specifying a Swift function name}}
void g(int i) SWIFT_NAME("function(int:)");
// expected-note@-1 {{conflicting attribute is here}}
// expected-error@+1 {{'swift_name' and 'swift_name' attributes are not compatible}}
void g(int i) SWIFT_NAME("function(_:)") {
}
typedef int (^CallbackTy)(void);
@interface AsyncI<P>
- (void)doSomethingWithCallback:(CallbackTy)callback SWIFT_ASYNC_NAME("doSomething()");
- (void)doSomethingX:(int)x withCallback:(CallbackTy)callback SWIFT_ASYNC_NAME("doSomething(x:)");
// expected-warning@+1 {{too many parameters in the signature specified by the '__swift_async_name__' attribute (expected 1; got 2)}}
- (void)doSomethingY:(int)x withCallback:(CallbackTy)callback SWIFT_ASYNC_NAME("doSomething(x:y:)");
// expected-warning@+1 {{too few parameters in the signature specified by the '__swift_async_name__' attribute (expected 1; got 0)}}
- (void)doSomethingZ:(int)x withCallback:(CallbackTy)callback SWIFT_ASYNC_NAME("doSomething()");
// expected-warning@+1 {{'__swift_async_name__' attribute cannot be applied to a method with no parameters}}
- (void)doSomethingNone SWIFT_ASYNC_NAME("doSomething()");
// expected-error@+1 {{'__swift_async_name__' attribute takes one argument}}
- (void)brokenAttr __attribute__((__swift_async_name__("brokenAttr", 2)));
@end
void asyncFunc(CallbackTy callback) SWIFT_ASYNC_NAME("asyncFunc()");
// expected-warning@+1 {{'__swift_async_name__' attribute cannot be applied to a function with no parameters}}
void asyncNoParams(void) SWIFT_ASYNC_NAME("asyncNoParams()");
// expected-error@+1 {{'__swift_async_name__' attribute only applies to Objective-C methods and functions}}
SWIFT_ASYNC_NAME("NoAsync")
@protocol NoAsync @end

View File

@ -0,0 +1,13 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
typedef int Bad1 __attribute__((swift_newtype(invalid)));
// expected-warning@-1 {{'swift_newtype' attribute argument not supported: 'invalid'}}
typedef int Bad2 __attribute__((swift_newtype()));
// expected-error@-1 {{argument required after attribute}}
typedef int Bad3 __attribute__((swift_newtype(invalid, ignored)));
// expected-error@-1 {{expected ')'}}
// expected-note@-2 {{to match this '('}}
// expected-warning@-3 {{'swift_newtype' attribute argument not supported: 'invalid'}}
struct __attribute__((__swift_newtype__(struct))) Bad4 {};
// expected-error@-1 {{'__swift_newtype__' attribute only applies to typedefs}}

View File

@ -0,0 +1,24 @@
// RUN: %clang_cc1 -verify -fsyntax-only %s
#if !__has_attribute(swift_objc_members)
#error cannot verify presence of swift_objc_members attribute
#endif
__attribute__((__swift_objc_members__))
__attribute__((__objc_root_class__))
@interface I
@end
__attribute__((swift_objc_members))
@protocol P
@end
// expected-error@-3 {{'swift_objc_members' attribute only applies to Objective-C interfaces}}
__attribute__((swift_objc_members))
extern void f(void);
// expected-error@-2 {{'swift_objc_members' attribute only applies to Objective-C interfaces}}
// expected-error@+1 {{'__swift_objc_members__' attribute takes no arguments}}
__attribute__((__swift_objc_members__("J")))
@interface J
@end

View File

@ -0,0 +1,29 @@
// RUN: %clang_cc1 -verify -fsyntax-only -fobjc-arc %s
__attribute__((__swift_private__))
@protocol P
@end
__attribute__((__swift_private__))
@interface I
@end
@interface J
@property id property __attribute__((__swift_private__));
- (void)instanceMethod __attribute__((__swift_private__));
+ (void)classMethod __attribute__((__swift_private__));
@end
void f(void) __attribute__((__swift_private__));
struct __attribute__((__swift_private__)) S {};
enum __attribute__((__swift_private__)) E {
one,
two,
};
typedef struct { } T __attribute__((__swift_private__));
void g(void) __attribute__((__swift_private__("private")));
// expected-error@-1 {{'__swift_private__' attribute takes no arguments}}

View File

@ -0,0 +1,22 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
void *objc_autoreleasepool_push();
void autoreleasepool_pop(void*);
@interface AUTORP @end
@implementation AUTORP
- (void) unregisterTask:(id) task {
goto L; // expected-error {{cannot jump}}
@autoreleasepool { // expected-note {{jump bypasses auto release push of @autoreleasepool block}}
void *tmp = objc_autoreleasepool_push();
L:
autoreleasepool_pop(tmp);
@autoreleasepool {
return;
}
}
}
@end

View File

@ -0,0 +1,24 @@
// RUN: %clang_cc1 -triple arm64-apple-ios11 -fapplication-extension -Wdeprecated-implementations -verify -Wno-objc-root-class %s
// RUN: %clang_cc1 -triple arm64-apple-tvos11 -fapplication-extension -Wdeprecated-implementations -verify -Wno-objc-root-class %s
// Declarations marked as 'unavailable' in an app extension should not generate a
// warning on implementation.
@interface Parent
- (void)ok __attribute__((availability(ios_app_extension,unavailable,message="not available")));
- (void)reallyUnavail __attribute__((availability(ios,unavailable))); // expected-note {{method 'reallyUnavail' declared here}}
- (void)reallyUnavail2 __attribute__((unavailable)); // expected-note {{method 'reallyUnavail2' declared here}}
@end
@interface Child : Parent
@end
@implementation Child
- (void)ok { // no warning.
}
- (void)reallyUnavail { // expected-warning {{implementing unavailable method}}
}
- (void)reallyUnavail2 { // expected-warning {{implementing unavailable method}}
}
@end

View File

@ -0,0 +1,23 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
// rdar://10177744
@interface Foo
@property (nonatomic, retain) NSString* what; // expected-error {{unknown type name 'NSString'}} \
// expected-error {{property with}} \
// expected-note {{previous definition is here}}
@end
@implementation Foo
- (void) setWhat: (NSString*) value { // expected-error {{expected a type}} \
// expected-warning {{conflicting parameter types in implementation of}}
__what; // expected-error {{use of undeclared identifier}} \
// expected-warning {{expression result unused}}
}
@synthesize what; // expected-note {{'what' declared here}}
@end
@implementation Bar // expected-warning {{cannot find interface declaration for}}
- (NSString*) what { // expected-error {{expected a type}}
return __what; // expected-error {{use of undeclared identifier}}
}
@end

View File

@ -0,0 +1,20 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
@interface I
- (id) retain;
@end
int objc_lookUpClass(const char*);
void __raiseExc1() {
[objc_lookUpClass("NSString") retain]; // expected-warning {{receiver type 'int' is not 'id'}}
}
typedef const struct __CFString * CFStringRef;
void func() {
CFStringRef obj;
[obj self]; // expected-warning {{receiver type 'CFStringRef' (aka 'const struct __CFString *') is not 'id'}} \\
expected-warning {{method '-self' not found}}
}

View File

@ -0,0 +1,21 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks
// expected-no-diagnostics
@interface Whatever
- copy;
@end
typedef long (^MyBlock)(id obj1, id obj2);
void foo(MyBlock b) {
id bar = [b copy];
}
void foo2(id b) {
}
void foo3(void (^block)(void)) {
foo2(block);
id x;
foo(x);
}

View File

@ -0,0 +1,12 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -fobjc-gc-only %s
// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -fobjc-gc-only %s
@interface Thing {}
@property void(^someBlock)(void); // expected-warning {{'copy' attribute must be specified for the block property}}
@property(copy) void(^OK)(void);
// rdar://8820813
@property (readonly) void (^block)(void); // readonly property is OK
@end

View File

@ -0,0 +1,51 @@
// RUN: %clang_cc1 -S -o - -triple i686-windows -verify -fblocks \
// RUN: -Wno-unused-comparison %s
#pragma clang diagnostic ignored "-Wunused-comparison"
#define nil ((id)nullptr)
@protocol NSObject
@end
@protocol NSCopying
@end
@protocol OtherProtocol
@end
__attribute__((objc_root_class))
@interface NSObject <NSObject, NSCopying>
@end
__attribute__((objc_root_class))
@interface Test
@end
int main() {
void (^block)() = ^{};
NSObject *object;
id<NSObject, NSCopying> qualifiedId;
id<OtherProtocol> poorlyQualified1;
Test *objectOfWrongType;
block == nil;
block == object;
block == qualifiedId;
nil == block;
object == block;
qualifiedId == block;
// these are still not valid: blocks must be compared with id, NSObject*, or a protocol-qualified id
// conforming to NSCopying or NSObject.
block == poorlyQualified1; // expected-error {{invalid operands to binary expression ('void (^)()' and 'id<OtherProtocol>')}}
block == objectOfWrongType; // expected-error {{invalid operands to binary expression ('void (^)()' and 'Test *')}}
poorlyQualified1 == block; // expected-error {{invalid operands to binary expression ('id<OtherProtocol>' and 'void (^)()')}}
objectOfWrongType == block; // expected-error {{invalid operands to binary expression ('Test *' and 'void (^)()')}}
return 0;
}

View File

@ -0,0 +1,77 @@
// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
// FIXME: should compile
// Test for blocks with explicit return type specified.
typedef float * PF;
float gf;
@interface NSView
- (id) some_method_that_returns_id;
@end
NSView *some_object;
void some_func (NSView * (^) (id));
typedef struct dispatch_item_s *dispatch_item_t;
typedef void (^completion_block_t)(void);
typedef double (^myblock)(int);
double test(myblock I);
int main() {
__block int x = 1;
__block int y = 2;
(void)^void *{ return 0; };
(void)^float(float y){ return y; };
(void)^double (float y, double d) {
if (y)
return d;
else
return y;
};
const char * (^chb) (int flag, const char *arg, char *arg1) = ^ const char * (int flag, const char *arg, char *arg1) {
if (flag)
return 0;
if (flag == 1)
return arg;
else if (flag == 2)
return "";
return arg1;
};
(void)^PF { return &gf; };
some_func(^ NSView * (id whatever) { return [some_object some_method_that_returns_id]; });
double res = test(^(int z){x = y+z; return (double)z; });
}
void func() {
completion_block_t X;
completion_block_t (^blockx)(dispatch_item_t) = ^completion_block_t (dispatch_item_t item) {
return X;
};
completion_block_t (^blocky)(dispatch_item_t) = ^(dispatch_item_t item) {
return X;
};
blockx = blocky;
}
// intent: block taking int returning block that takes char,int and returns int
int (^(^block)(double x))(char, short);
void foo() {
int one = 1;
block = ^(double x){ return ^(char c, short y) { return one + c + y; };}; // expected-error {{returning block that lives on the local stack}}
// or:
block = ^(double x){ return ^(char c, short y) { return one + (int)c + y; };}; // expected-error {{returning block that lives on the local stack}}
}

View File

@ -0,0 +1,27 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks
// rdar://10734265
@class NSObject;
typedef void (^block1_t)(int arg);
typedef void (^block2_t)(block1_t arg);
typedef void (^block3_t)(NSObject *arg);
typedef void (^block4_t)(id arg);
void fn(block4_t arg); // expected-note {{passing argument to parameter 'arg' here}}
void another_fn(block2_t arg);
int main() {
block1_t b1;
block2_t b2;
block3_t b3;
block3_t b4;
block4_t b5;
fn(b1); // expected-error {{incompatible block pointer types passing 'block1_t' (aka 'void (^)(int)') to parameter of type 'block4_t' (aka 'void (^)(id)')}}
fn(b2); // must succeed: block1_t *is* compatible with id
fn(b3); // succeeds: NSObject* compatible with id
fn(b4); // succeeds: id compatible with id
another_fn(b5);
}

View File

@ -0,0 +1,20 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
// expected-no-diagnostics
@interface NSObject {
struct objc_object *isa;
}
@end
@interface Foo : NSObject {
int _prop;
}
@end
@implementation Foo
- (int)doSomething {
int (^blk)(void) = ^{ return _prop; };
return blk();
}
@end

View File

@ -0,0 +1,14 @@
// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks -fobjc-arc
// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
__auto_type block = ^ id __attribute__((ns_returns_retained)) (id filter) {
return filter; // ok
};
__auto_type block2 = ^ __attribute__((ns_returns_retained)) id (id filter) {
return filter; // ok
};
__auto_type block3 = ^ id (id filter) __attribute__((ns_returns_retained)) {
return filter; // ok
};
// expected-no-diagnostics

View File

@ -0,0 +1,44 @@
// RUN: %clang_cc1 %s -fblocks -verify -fsyntax-only
@interface NSObject
@end
@interface Test : NSObject
- (void)test;
@end
@implementation Test
- (void)test
{
void (^simpleBlock)() = ^ _Nonnull { //expected-warning {{attribute '_Nonnull' ignored, because it cannot be applied to omitted return type}}
return;
};
void (^simpleBlock2)() = ^ _Nonnull void { //expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'void'}}
return;
};
void (^simpleBlock3)() = ^ _Nonnull (void) { //expected-warning {{attribute '_Nonnull' ignored, because it cannot be applied to omitted return type}}
return;
};
void (^simpleBlock4)() = ^ const { //expected-warning {{'const' qualifier on omitted return type '<dependent type>' has no effect}}
return;
};
void (^simpleBlock5)() = ^ const void { //expected-error {{incompatible block pointer types initializing 'void (^)()' with an expression of type 'const void (^)(void)'}}
return; // expected-warning@-1 {{function cannot return qualified void type 'const void'}}
};
void (^simpleBlock6)() = ^ const (void) { //expected-warning {{'const' qualifier on omitted return type '<dependent type>' has no effect}}
return;
};
void (^simpleBlock7)() = ^ _Nonnull __attribute__((align_value(128))) _Nullable const (void) { // expected-warning {{attribute '_Nullable' ignored, because it cannot be applied to omitted return type}} \
// expected-warning {{attribute '_Nonnull' ignored, because it cannot be applied to omitted return type}} \
// expected-warning {{'const' qualifier on omitted return type '<dependent type>' has no effect}} \
// expected-warning {{'align_value' attribute only applies to variables and typedefs}}
return;
};
void (^simpleBlock9)() = ^ __attribute__ ((align_value(128))) _Nonnull const (void) { // expected-warning {{attribute '_Nonnull' ignored, because it cannot be applied to omitted return type}} \
// expected-warning {{'const' qualifier on omitted return type '<dependent type>' has no effect}} \
// expected-warning {{'align_value' attribute only applies to variables and typedefs}}
return;
};
}
@end

View File

@ -0,0 +1,12 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s
// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s
// rdar://10681443
@interface I
- (void) compileSandboxProfileAndReturnError:(__attribute__((__blocks__(byref))) id)errorp; // expected-error {{__block attribute not allowed, only allowed on local variables}}
@end
@implementation I
- (void) compileSandboxProfileAndReturnError:(__attribute__((__blocks__(byref))) id)errorp {} // expected-error {{__block attribute not allowed, only allowed on local variables}}
@end

Some files were not shown because too many files have changed in this diff Show More