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