Clang Project

clang_source_code/test/Analysis/nonnull-global-constants.mm
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
2
3// Nullability of const string-like globals, testing
4// NonnullGlobalConstantsChecker.
5
6void clang_analyzer_eval(bool);
7
8@class NSString;
9typedef const struct __CFString *CFStringRef;
10typedef const struct __CFBoolean * CFBooleanRef;
11
12// Global NSString* is non-null.
13extern NSString *const StringConstGlobal;
14void stringConstGlobal() {
15  clang_analyzer_eval(StringConstGlobal); // expected-warning{{TRUE}}
16}
17
18// The logic does not apply to local variables though.
19extern NSString *stringGetter();
20void stringConstLocal() {
21  NSString *const local = stringGetter();
22  clang_analyzer_eval(local); // expected-warning{{UNKNOWN}}
23}
24
25// Global const CFStringRef's are also assumed to be non-null.
26extern const CFStringRef CFStringConstGlobal;
27void cfStringCheckGlobal() {
28  clang_analyzer_eval(CFStringConstGlobal); // expected-warning{{TRUE}}
29}
30
31// But only "const" ones.
32extern CFStringRef CFStringNonConstGlobal;
33void cfStringCheckMutableGlobal() {
34  clang_analyzer_eval(CFStringNonConstGlobal); // expected-warning{{UNKNOWN}}
35}
36
37// char* const is also assumed to be non-null.
38extern const char *const ConstCharStarConst;
39void constCharStarCheckGlobal() {
40  clang_analyzer_eval(ConstCharStarConst); // expected-warning{{TRUE}}
41}
42
43// Pointer value can be mutable.
44extern char *const CharStarConst;
45void charStarCheckGlobal() {
46  clang_analyzer_eval(CharStarConst); // expected-warning{{TRUE}}
47}
48
49// But the pointer itself should be immutable.
50extern char *CharStar;
51void charStartCheckMutableGlobal() {
52  clang_analyzer_eval(CharStar); // expected-warning{{UNKNOWN}}
53}
54
55// Type definitions should also work across typedefs, for pointers:
56typedef char *const str;
57extern str globalStr;
58void charStarCheckTypedef() {
59  clang_analyzer_eval(globalStr); // expected-warning{{TRUE}}
60}
61
62// And for types.
63typedef NSString *const NStr;
64extern NStr globalNSString;
65void NSStringCheckTypedef() {
66  clang_analyzer_eval(globalNSString); // expected-warning{{TRUE}}
67}
68
69// Note that constness could be either inside
70// the var declaration, or in a typedef.
71typedef NSString *NStr2;
72extern const NStr2 globalNSString2;
73void NSStringCheckConstTypedef() {
74  clang_analyzer_eval(globalNSString2); // expected-warning{{TRUE}}
75}
76
77// Nested typedefs should work as well.
78typedef const CFStringRef str1;
79typedef str1 str2;
80extern str2 globalStr2;
81void testNestedTypedefs() {
82  clang_analyzer_eval(globalStr2); // expected-warning{{TRUE}}
83}
84
85// And for NSString *.
86typedef NSString *const nstr1;
87typedef nstr1 nstr2;
88extern nstr2 nglobalStr2;
89void testNestedTypedefsForNSString() {
90  clang_analyzer_eval(nglobalStr2); // expected-warning{{TRUE}}
91}
92
93// And for CFBooleanRefs.
94extern const CFBooleanRef kBool;
95void testNonnullBool() {
96  clang_analyzer_eval(kBool); // expected-warning{{TRUE}}
97}
98
99// And again, only for const one.
100extern CFBooleanRef kBoolMutable;
101void testNonnullNonconstBool() {
102  clang_analyzer_eval(kBoolMutable); // expected-warning{{UNKNOWN}}
103}
104