2011-10-02 09:16:38 +08:00
|
|
|
// RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -DNO_USE
|
|
|
|
// RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -verify
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
#include <arc-system-header.h>
|
|
|
|
|
|
|
|
#ifndef NO_USE
|
|
|
|
void test(id op, void *cp) {
|
2015-10-28 13:03:19 +08:00
|
|
|
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}}
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void test3(struct Test3 *p) {
|
2015-10-28 13:03:19 +08:00
|
|
|
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}}
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void test4(Test4 *p) {
|
2015-10-28 13:03:19 +08:00
|
|
|
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}}
|
2011-06-16 07:02:42 +08:00
|
|
|
p->field2 = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void test5(struct Test5 *p) {
|
2015-10-28 13:03:19 +08:00
|
|
|
p->field = 0; // expected-error {{'field' is unavailable in ARC}}
|
|
|
|
// expected-note@arc-system-header.h:25 {{field has non-trivial ownership qualification}}
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2015-10-28 13:03:19 +08:00
|
|
|
*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}}
|
2013-04-17 16:06:46 +08:00
|
|
|
// expected-note@arc-system-header.h:41 2 {{property 'prop' is declared unavailable here}}
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
Add TreatUnavailableAsInvalid for the verification-only mode in InitListChecker.
Given the following test case:
typedef struct {
const char *name;
id field;
} Test9;
extern void doSomething(Test9 arg);
void test9() {
Test9 foo2 = {0, 0};
doSomething(foo2);
}
With a release compiler, we don't emit any message and silently ignore the
variable "foo2". With an assert compiler, we get an assertion failure.
The root cause —————————————
Back in r140457 we gave InitListChecker a verification-only mode, and will use
CanUseDecl instead of DiagnoseUseOfDecl for verification-only mode.
These two functions handle unavailable issues differently:
In Sema::CanUseDecl, we say the decl is invalid when the Decl is unavailable and
the current context is available.
In Sema::DiagnoseUseOfDecl, we say the decl is usable by ignoring the return
code of DiagnoseAvailabilityOfDecl
So with an assert build, we will hit an assertion in diagnoseListInit
assert(DiagnoseInitList.HadError() &&
"Inconsistent init list check result.");
The fix -------------------
If we follow what is implemented in CanUseDecl and treat Decls with
unavailable issues as invalid, the variable decl of “foo2” will be marked as
invalid. Since unavailable checking is processed in delayed diagnostics
(r197627), we will silently ignore the diagnostics when we find out that
the variable decl is invalid.
We add a flag "TreatUnavailableAsInvalid" for the verification-only mode.
For overload resolution, we want to say decls with unavailable issues are
invalid; but for everything else, we should say they are valid and
emit diagnostics. Depending on the value of the flag, CanUseDecl
can return different values for unavailable issues.
rdar://23557300
Differential Revision: http://reviews.llvm.org/D15314
llvm-svn: 263149
2016-03-11 02:53:19 +08:00
|
|
|
|
|
|
|
extern void doSomething(Test9 arg);
|
|
|
|
void test9() {
|
|
|
|
Test9 foo2 = {0, 0}; // expected-error {{'field' is unavailable in ARC}}
|
|
|
|
// expected-note@arc-system-header.h:56 {{field has non-trivial ownership qualification}}
|
|
|
|
doSomething(foo2);
|
|
|
|
}
|
2011-06-16 07:02:42 +08:00
|
|
|
#endif
|
2011-06-18 05:56:12 +08:00
|
|
|
|
|
|
|
// test8 in header
|