1 | // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -disable-free -analyzer-checker=core,deadcode,alpha.security.taint,debug.TaintTest,debug.ExprInspection -verify %s |
2 | |
3 | void clang_analyzer_eval(int); |
4 | |
5 | // Note, we do need to include headers here, since the analyzer checks if the function declaration is located in a system header. |
6 | #include "Inputs/system-header-simulator.h" |
7 | |
8 | // Test that system header does not invalidate the internal global. |
9 | int size_rdar9373039 = 1; |
10 | int rdar9373039() { |
11 | int x; |
12 | int j = 0; |
13 | |
14 | for (int i = 0 ; i < size_rdar9373039 ; ++i) |
15 | x = 1; |
16 | |
17 | // strlen doesn't invalidate the value of 'size_rdar9373039'. |
18 | int extra = (2 + strlen ("Clang") + ((4 - ((unsigned int) (2 + strlen ("Clang")) % 4)) % 4)) + (2 + strlen ("1.0") + ((4 - ((unsigned int) (2 + strlen ("1.0")) % 4)) % 4)); |
19 | |
20 | for (int i = 0 ; i < size_rdar9373039 ; ++i) |
21 | j += x; // no-warning |
22 | |
23 | return j; |
24 | } |
25 | |
26 | // Test stdin does not get invalidated by a system call nor by an internal call. |
27 | void foo(); |
28 | int stdinTest() { |
29 | int i = 0; |
30 | fscanf(stdin, "%d", &i); |
31 | foo(); |
32 | int m = i; // expected-warning + {{tainted}} |
33 | fscanf(stdin, "%d", &i); |
34 | int j = i; // expected-warning + {{tainted}} |
35 | return m + j; // expected-warning + {{tainted}} |
36 | } |
37 | |
38 | // Test errno gets invalidated by a system call. |
39 | int testErrnoSystem() { |
40 | int i; |
41 | int *p = 0; |
42 | fscanf(stdin, "%d", &i); |
43 | if (errno == 0) { |
44 | fscanf(stdin, "%d", &i); // errno gets invalidated here. |
45 | return 5 / errno; // no-warning |
46 | } |
47 | |
48 | errno = 0; |
49 | fscanf(stdin, "%d", &i); // errno gets invalidated here. |
50 | return 5 / errno; // no-warning |
51 | } |
52 | |
53 | // Test that errno gets invalidated by internal calls. |
54 | int testErrnoInternal() { |
55 | int i; |
56 | int *p = 0; |
57 | fscanf(stdin, "%d", &i); |
58 | if (errno == 0) { |
59 | foo(); // errno gets invalidated here. |
60 | return 5 / errno; // no-warning |
61 | } |
62 | return 0; |
63 | } |
64 | |
65 | // Test that const integer does not get invalidated. |
66 | const int x = 0; |
67 | int constIntGlob() { |
68 | const int *m = &x; |
69 | foo(); |
70 | return 3 / *m; // expected-warning {{Division by zero}} |
71 | } |
72 | |
73 | extern const int y; |
74 | int constIntGlobExtern() { |
75 | if (y == 0) { |
76 | foo(); |
77 | return 5 / y; // expected-warning {{Division by zero}} |
78 | } |
79 | return 0; |
80 | } |
81 | |
82 | static void * const ptr = 0; |
83 | void constPtrGlob() { |
84 | clang_analyzer_eval(ptr == 0); // expected-warning{{TRUE}} |
85 | foo(); |
86 | clang_analyzer_eval(ptr == 0); // expected-warning{{TRUE}} |
87 | } |
88 | |
89 | static const int x2 = x; |
90 | void constIntGlob2() { |
91 | clang_analyzer_eval(x2 == 0); // expected-warning{{TRUE}} |
92 | foo(); |
93 | clang_analyzer_eval(x2 == 0); // expected-warning{{TRUE}} |
94 | } |
95 | |
96 | void testAnalyzerEvalIsPure() { |
97 | extern int someGlobal; |
98 | if (someGlobal == 0) { |
99 | clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} |
100 | clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} |
101 | } |
102 | } |
103 | |
104 | // Test that static variables with initializers do not get reinitialized on |
105 | // recursive calls. |
106 | void Function2(void); |
107 | int *getPtr(); |
108 | void Function1(void) { |
109 | static unsigned flag; |
110 | static int *p = 0; |
111 | if (!flag) { |
112 | flag = 1; |
113 | p = getPtr(); |
114 | } |
115 | int m = *p; // no-warning: p is never null. |
116 | m++; |
117 | Function2(); |
118 | } |
119 | void Function2(void) { |
120 | Function1(); |
121 | } |
122 | |
123 | void SetToNonZero(void) { |
124 | static int g = 5; |
125 | clang_analyzer_eval(g == 5); // expected-warning{{TRUE}} |
126 | } |
127 | |
128 | |