blob: 7900b9dd1286a7ee76815b6cef3c2c10a713a6eb [file] [log] [blame]
George Karpenkovead01622017-10-11 18:39:40 +00001// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
2
3// Nullability of const string-like globals, testing
George Karpenkov9a542f72017-10-13 00:51:41 +00004// NonnullGlobalConstantsChecker.
George Karpenkovead01622017-10-11 18:39:40 +00005
6void clang_analyzer_eval(bool);
7
8@class NSString;
9typedef const struct __CFString *CFStringRef;
George Karpenkov9a542f72017-10-13 00:51:41 +000010typedef const struct __CFBoolean * CFBooleanRef;
George Karpenkovead01622017-10-11 18:39:40 +000011
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}
George Karpenkov9a542f72017-10-13 00:51:41 +000092
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}