1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -verify %s \
// RUN: -analyzer-checker=core.builtin \
// RUN: -analyzer-checker=debug.ExprInspection \
// RUN: -analyzer-checker=unix.cstring \
// RUN: -analyzer-config display-checker-name=false
typedef unsigned long size_t;
struct S {
struct S3 {
int y[10];
};
struct S2 : S3 {
int *x;
} s2[10];
int z;
};
void clang_analyzer_explain(int);
void clang_analyzer_explain(void *);
void clang_analyzer_explain(const int *);
void clang_analyzer_explain(S);
size_t clang_analyzer_getExtent(void *);
size_t strlen(const char *);
int conjure();
S conjure_S();
int glob;
static int stat_glob;
void *glob_ptr;
// Test strings are regex'ed because we need to match exact string
// rather than a substring.
void test_1(int param, void *ptr) {
clang_analyzer_explain(&glob); // expected-warning-re{{{{^pointer to global variable 'glob'$}}}}
clang_analyzer_explain(param); // expected-warning-re{{{{^argument 'param'$}}}}
clang_analyzer_explain(ptr); // expected-warning-re{{{{^argument 'ptr'$}}}}
if (param == 42)
clang_analyzer_explain(param); // expected-warning-re{{{{^signed 32-bit integer '42'$}}}}
}
void test_2(char *ptr, int ext) {
clang_analyzer_explain((void *) "asdf"); // expected-warning-re{{{{^pointer to element of type 'char' with index 0 of string literal "asdf"$}}}}
clang_analyzer_explain(strlen(ptr)); // expected-warning-re{{{{^metadata of type 'unsigned long' tied to pointee of argument 'ptr'$}}}}
clang_analyzer_explain(conjure()); // expected-warning-re{{{{^symbol of type 'int' conjured at statement 'conjure\(\)'$}}}}
clang_analyzer_explain(glob); // expected-warning-re{{{{^value derived from \(symbol of type 'int' conjured at statement 'conjure\(\)'\) for global variable 'glob'$}}}}
clang_analyzer_explain(glob_ptr); // expected-warning-re{{{{^value derived from \(symbol of type 'int' conjured at statement 'conjure\(\)'\) for global variable 'glob_ptr'$}}}}
clang_analyzer_explain(clang_analyzer_getExtent(ptr)); // expected-warning-re{{{{^extent of pointee of argument 'ptr'$}}}}
int *x = new int[ext];
clang_analyzer_explain(x); // expected-warning-re{{{{^pointer to element of type 'int' with index 0 of heap segment that starts at symbol of type 'int \*' conjured at statement 'new int \[ext\]'$}}}}
// Sic! What gets computed is the extent of the element-region.
clang_analyzer_explain(clang_analyzer_getExtent(x)); // expected-warning-re{{{{^\(argument 'ext'\) \* 4$}}}}
delete[] x;
}
void test_3(S s) {
clang_analyzer_explain(&s); // expected-warning-re{{{{^pointer to parameter 's'$}}}}
clang_analyzer_explain(s.z); // expected-warning-re{{{{^initial value of field 'z' of parameter 's'$}}}}
clang_analyzer_explain(&s.s2[5].y[3]); // expected-warning-re{{{{^pointer to element of type 'int' with index 3 of field 'y' of base object 'S::S3' inside element of type 'struct S::S2' with index 5 of field 's2' of parameter 's'$}}}}
if (!s.s2[7].x) {
clang_analyzer_explain(s.s2[7].x); // expected-warning-re{{{{^concrete memory address '0'$}}}}
// FIXME: we need to be explaining '1' rather than '0' here; not explainer bug.
clang_analyzer_explain(s.s2[7].x + 1); // expected-warning-re{{{{^concrete memory address '0'$}}}}
}
}
void test_4(int x, int y) {
int z;
static int stat;
clang_analyzer_explain(x + 1); // expected-warning-re{{{{^\(argument 'x'\) \+ 1$}}}}
clang_analyzer_explain(1 + y); // expected-warning-re{{{{^\(argument 'y'\) \+ 1$}}}}
clang_analyzer_explain(x + y); // expected-warning-re{{{{^\(argument 'x'\) \+ \(argument 'y'\)$}}}}
clang_analyzer_explain(z); // expected-warning-re{{{{^undefined value$}}}}
clang_analyzer_explain(&z); // expected-warning-re{{{{^pointer to local variable 'z'$}}}}
clang_analyzer_explain(stat); // expected-warning-re{{{{^signed 32-bit integer '0'$}}}}
clang_analyzer_explain(&stat); // expected-warning-re{{{{^pointer to static local variable 'stat'$}}}}
clang_analyzer_explain(stat_glob); // expected-warning-re{{{{^initial value of global variable 'stat_glob'$}}}}
clang_analyzer_explain(&stat_glob); // expected-warning-re{{{{^pointer to global variable 'stat_glob'$}}}}
clang_analyzer_explain((int[]){1, 2, 3}); // expected-warning-re{{{{^pointer to element of type 'int' with index 0 of temporary object constructed at statement '\(int\[3\]\)\{1, 2, 3\}'$}}}}
}
namespace {
class C {
int x[10];
public:
void test_5(int i) {
clang_analyzer_explain(this); // expected-warning-re{{{{^pointer to 'this' object$}}}}
clang_analyzer_explain(&x[i]); // expected-warning-re{{{{^pointer to element of type 'int' with index 'argument 'i'' of field 'x' of 'this' object$}}}}
clang_analyzer_explain(__builtin_alloca(i)); // expected-warning-re{{{{^pointer to region allocated by '__builtin_alloca\(i\)'$}}}}
}
};
} // end of anonymous namespace
void test_6() {
clang_analyzer_explain(conjure_S()); // expected-warning-re{{{{^lazily frozen compound value of 1st parameter of function 'clang_analyzer_explain\(\)'$}}}}
clang_analyzer_explain(conjure_S().z); // expected-warning-re{{{{^value derived from \(symbol of type 'int' conjured at statement 'conjure_S\(\)'\) for field 'z' of temporary object constructed at statement 'conjure_S\(\)'$}}}}
}
class C_top_level {
public:
C_top_level(int param) {
clang_analyzer_explain(¶m); // expected-warning-re{{{{^pointer to parameter 'param'$}}}}
}
};
class C_non_top_level {
public:
C_non_top_level(int param) {
clang_analyzer_explain(¶m); // expected-warning-re{{{{^pointer to parameter 'param'$}}}}
}
};
void test_7(int n) {
C_non_top_level c(n);
auto lambda_top_level = [n](int param) {
clang_analyzer_explain(¶m); // expected-warning-re{{{{^pointer to parameter 'param'$}}}}
};
auto lambda_non_top_level = [n](int param) {
clang_analyzer_explain(¶m); // expected-warning-re{{{{^pointer to parameter 'param'$}}}}
};
lambda_non_top_level(n);
}
|