blob: df9d8700099e8c526a54eb3f853d48a31af87942 [file] [log] [blame]
Jordy Rose6d2b92e2012-05-16 21:13:36 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-constraints=basic -triple i386-apple-darwin9 -verify %s
2// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-constraints=basic -triple x86_64-apple-darwin9 -verify %s
3// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-constraints=range -triple i386-apple-darwin9 -verify %s
4// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-constraints=range -triple x86_64-apple-darwin9 -verify %s
Jordy Rosef158b712012-05-16 20:29:44 +00005
6// This file runs in C++ mode so that the comparison type is 'bool', not 'int'.
7void clang_analyzer_eval(int);
8typedef typeof(sizeof(int)) size_t;
9
10// PR12206/12510 - When SimpleSValBuilder figures out that a symbol is fully
11// constrained, it should cast the value to the result type in a binary
12// operation...unless the binary operation is a comparison, in which case the
13// two arguments should be the same type, but won't match the result type.
14//
15// This is not directly related to additive folding, but we use SValBuilder's
16// additive folding to tickle the bug. ExprEngine will simplify fully-constrained
17// symbols, so SValBuilder will only see them if they are (a) part of an evaluated
18// SymExpr (e.g. with additive folding) or (b) generated by a checker (e.g.
19// unix.cstring's strlen() modelling).
20void PR12206(int x) {
21 size_t comparisonSize = sizeof(1 == 1);
22
23 // Sanity check. This test is useless if size_t isn't bigger than bool.
24 clang_analyzer_eval(sizeof(size_t) > comparisonSize); // expected-warning{{TRUE}}
25
26 // Build a SymIntExpr, dependent on x.
27 int local = x - 1;
28
29 // Create a value that requires more bits to store than a comparison result.
30 int value = 1;
31 value <<= 8 * comparisonSize;
32 value += 1;
33
34 // Constrain the value of x.
35 if (x != value) return;
36
37 // Constant-folding will turn (local+1) back into the symbol for x.
38 // The point of this dance is to make SValBuilder be responsible for
39 // turning the symbol into a ConcreteInt, rather than ExprEngine.
40
41 // Test relational operators.
42 clang_analyzer_eval((local + 1) >= 2); // expected-warning{{TRUE}}
43 clang_analyzer_eval(2 <= (local + 1)); // expected-warning{{TRUE}}
44
45 // Test equality operators.
46 clang_analyzer_eval((local + 1) != 1); // expected-warning{{TRUE}}
47 clang_analyzer_eval(1 != (local + 1)); // expected-warning{{TRUE}}
48}
49
50void PR12206_truncation(signed char x) {
51 // Build a SymIntExpr, dependent on x.
52 signed char local = x - 1;
53
54 // Constrain the value of x.
55 if (x != 1) return;
56
57 // Constant-folding will turn (local+1) back into the symbol for x.
58 // The point of this dance is to make SValBuilder be responsible for
59 // turning the symbol into a ConcreteInt, rather than ExprEngine.
60
61 // Construct a value that cannot be represented by 'char',
62 // but that has the same lower bits as x.
63 signed int value = 1 + (1 << 8);
64
65 // Test relational operators.
66 clang_analyzer_eval((local + 1) < value); // expected-warning{{TRUE}}
67 clang_analyzer_eval(value > (local + 1)); // expected-warning{{TRUE}}
68
69 // Test equality operators.
70 clang_analyzer_eval((local + 1) != value); // expected-warning{{TRUE}}
71 clang_analyzer_eval(value != (local + 1)); // expected-warning{{TRUE}}
72}
73
74// This test is insurance in case we significantly change how SymExprs are
75// evaluated.
76size_t strlen(const char *s);
77void PR12206_strlen(const char *x) {
78 size_t comparisonSize = sizeof(1 == 1);
79
80 // Sanity check. This test is useless if size_t isn't bigger than bool.
81 clang_analyzer_eval(sizeof(size_t) > comparisonSize); // expected-warning{{TRUE}}
82
83 // Create a value that requires more bits to store than a comparison result.
84 size_t value = 1UL;
85 value <<= 8 * comparisonSize;
86 value += 1;
87
88 // Constrain the length of x.
89 if (strlen(x) != value) return;
90
91 // Test relational operators.
92 clang_analyzer_eval(strlen(x) >= 2); // expected-warning{{TRUE}}
93 clang_analyzer_eval(2 <= strlen(x)); // expected-warning{{TRUE}}
94
95 // Test equality operators.
96 clang_analyzer_eval(strlen(x) != 1); // expected-warning{{TRUE}}
97 clang_analyzer_eval(1 != strlen(x)); // expected-warning{{TRUE}}
98}