ADD: code refactoring
This commit is contained in:
parent
d573d87610
commit
28e71ed6ea
|
@ -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: -->
|
|
@ -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?
|
||||||
|
-->
|
|
@ -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).
|
|
@ -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
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
# Builds
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
examples/SemaObjC*.txt
|
||||||
|
|
||||||
|
# wasm
|
||||||
|
*.wasm
|
|
@ -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"
|
4
LICENSE
4
LICENSE
|
@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -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.
|
|
@ -0,0 +1,4 @@
|
||||||
|
# TODO
|
||||||
|
[ ] precedence order
|
||||||
|
[ ] highlights.scm
|
||||||
|
[ ] highlights tests
|
|
@ -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",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -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
|
|
@ -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 (_) {}
|
|
@ -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());
|
||||||
|
*/
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
|
@ -0,0 +1 @@
|
||||||
|
struct S { int x; };
|
|
@ -0,0 +1,3 @@
|
||||||
|
module empty {
|
||||||
|
header "empty.h"
|
||||||
|
}
|
|
@ -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;
|
|
@ -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 *'}}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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'}}
|
||||||
|
}
|
|
@ -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
|
|
@ -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}:")"
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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}}
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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}}
|
||||||
|
}
|
|
@ -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}}
|
|
@ -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}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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}}
|
||||||
|
}
|
|
@ -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}}
|
||||||
|
}
|
|
@ -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; };
|
||||||
|
}
|
|
@ -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];
|
||||||
|
}
|
|
@ -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'}}
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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];
|
||||||
|
}
|
||||||
|
|
|
@ -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}}
|
||||||
|
}
|
|
@ -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
|
|
@ -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();
|
||||||
|
}
|
|
@ -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);
|
|
@ -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)));
|
||||||
|
}
|
|
@ -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
|
|
@ -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"
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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}}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||||
|
// expected-no-diagnostics
|
||||||
|
@interface NSObject
|
||||||
|
- (void)doSomething __attribute__((nodebug));
|
||||||
|
@end
|
|
@ -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}}
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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}}
|
|
@ -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}}
|
|
@ -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}}
|
|
@ -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
|
|
@ -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}}
|
|
@ -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
|
|
@ -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}}
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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}}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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}}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue