forked from OSchip/llvm-project
124 lines
3.6 KiB
Plaintext
124 lines
3.6 KiB
Plaintext
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
|
|
|
|
// Nullability of const string-like globals, testing
|
|
// NonnullGlobalConstantsChecker.
|
|
|
|
void clang_analyzer_eval(bool);
|
|
|
|
@class NSString;
|
|
typedef const struct __CFString *CFStringRef;
|
|
typedef const struct __CFBoolean *CFBooleanRef;
|
|
|
|
#define CF_BRIDGED_TYPE(T) __attribute__((objc_bridge(T)))
|
|
typedef const struct CF_BRIDGED_TYPE(NSNull) __CFNull *CFNullRef;
|
|
extern const CFNullRef kCFNull;
|
|
|
|
// Global NSString* is non-null.
|
|
extern NSString *const StringConstGlobal;
|
|
void stringConstGlobal() {
|
|
clang_analyzer_eval(StringConstGlobal); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// The logic does not apply to local variables though.
|
|
extern NSString *stringGetter();
|
|
void stringConstLocal() {
|
|
NSString *const local = stringGetter();
|
|
clang_analyzer_eval(local); // expected-warning{{UNKNOWN}}
|
|
}
|
|
|
|
// Global const CFStringRef's are also assumed to be non-null.
|
|
extern const CFStringRef CFStringConstGlobal;
|
|
void cfStringCheckGlobal() {
|
|
clang_analyzer_eval(CFStringConstGlobal); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// But only "const" ones.
|
|
extern CFStringRef CFStringNonConstGlobal;
|
|
void cfStringCheckMutableGlobal() {
|
|
clang_analyzer_eval(CFStringNonConstGlobal); // expected-warning{{UNKNOWN}}
|
|
}
|
|
|
|
// char* const is also assumed to be non-null.
|
|
extern const char *const ConstCharStarConst;
|
|
void constCharStarCheckGlobal() {
|
|
clang_analyzer_eval(ConstCharStarConst); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// Pointer value can be mutable.
|
|
extern char *const CharStarConst;
|
|
void charStarCheckGlobal() {
|
|
clang_analyzer_eval(CharStarConst); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// But the pointer itself should be immutable.
|
|
extern char *CharStar;
|
|
void charStartCheckMutableGlobal() {
|
|
clang_analyzer_eval(CharStar); // expected-warning{{UNKNOWN}}
|
|
}
|
|
|
|
// Type definitions should also work across typedefs, for pointers:
|
|
typedef char *const str;
|
|
extern str globalStr;
|
|
void charStarCheckTypedef() {
|
|
clang_analyzer_eval(globalStr); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// And for types.
|
|
typedef NSString *const NStr;
|
|
extern NStr globalNSString;
|
|
void NSStringCheckTypedef() {
|
|
clang_analyzer_eval(globalNSString); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// Note that constness could be either inside
|
|
// the var declaration, or in a typedef.
|
|
typedef NSString *NStr2;
|
|
extern const NStr2 globalNSString2;
|
|
void NSStringCheckConstTypedef() {
|
|
clang_analyzer_eval(globalNSString2); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// Nested typedefs should work as well.
|
|
typedef const CFStringRef str1;
|
|
typedef str1 str2;
|
|
extern str2 globalStr2;
|
|
void testNestedTypedefs() {
|
|
clang_analyzer_eval(globalStr2); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// And for NSString *.
|
|
typedef NSString *const nstr1;
|
|
typedef nstr1 nstr2;
|
|
extern nstr2 nglobalStr2;
|
|
void testNestedTypedefsForNSString() {
|
|
clang_analyzer_eval(nglobalStr2); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// And for CFBooleanRefs.
|
|
extern const CFBooleanRef kBool;
|
|
void testNonnullBool() {
|
|
clang_analyzer_eval(kBool); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// And again, only for const one.
|
|
extern CFBooleanRef kBoolMutable;
|
|
void testNonnullNonconstBool() {
|
|
clang_analyzer_eval(kBoolMutable); // expected-warning{{UNKNOWN}}
|
|
}
|
|
|
|
// If it's annotated as nonnull, it doesn't even need to be const.
|
|
extern CFStringRef _Nonnull str3;
|
|
void testNonnullNonconstCFString() {
|
|
clang_analyzer_eval(str3); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
// This one's nonnull for two reasons.
|
|
extern const CFStringRef _Nonnull str4;
|
|
void testNonnullNonnullCFString() {
|
|
clang_analyzer_eval(str4); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
void test_kCFNull() {
|
|
clang_analyzer_eval(kCFNull); // expected-warning{{TRUE}}
|
|
}
|