| // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,debug.ExprInspection -triple i386-apple-darwin9 -verify %s | 
 | // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,debug.ExprInspection -triple x86_64-apple-darwin9 -verify %s | 
 |  | 
 | // This file runs in C++ mode so that the comparison type is 'bool', not 'int'. | 
 | void clang_analyzer_eval(int); | 
 | typedef typeof(sizeof(int)) size_t; | 
 |  | 
 | // PR12206/12510 - When SimpleSValBuilder figures out that a symbol is fully | 
 | // constrained, it should cast the value to the result type in a binary | 
 | // operation...unless the binary operation is a comparison, in which case the | 
 | // two arguments should be the same type, but won't match the result type. | 
 | // | 
 | // This is not directly related to additive folding, but we use SValBuilder's | 
 | // additive folding to tickle the bug. ExprEngine will simplify fully-constrained | 
 | // symbols, so SValBuilder will only see them if they are (a) part of an evaluated | 
 | // SymExpr (e.g. with additive folding) or (b) generated by a checker (e.g. | 
 | // unix.cstring's strlen() modelling). | 
 | void PR12206(int x) { | 
 |   size_t comparisonSize = sizeof(1 == 1); | 
 |  | 
 |   // Sanity check. This test is useless if size_t isn't bigger than bool. | 
 |   clang_analyzer_eval(sizeof(size_t) > comparisonSize); // expected-warning{{TRUE}} | 
 |  | 
 |   // Build a SymIntExpr, dependent on x. | 
 |   int local = x - 1; | 
 |  | 
 |   // Create a value that requires more bits to store than a comparison result. | 
 |   int value = 1; | 
 |   value <<= 8 * comparisonSize; | 
 |   value += 1; | 
 |  | 
 |   // Constrain the value of x. | 
 |   if (x != value) return; | 
 |  | 
 |   // Constant-folding will turn (local+1) back into the symbol for x. | 
 |   // The point of this dance is to make SValBuilder be responsible for | 
 |   // turning the symbol into a ConcreteInt, rather than ExprEngine. | 
 |  | 
 |   // Test relational operators. | 
 |   clang_analyzer_eval((local + 1) >= 2); // expected-warning{{TRUE}} | 
 |   clang_analyzer_eval(2 <= (local + 1)); // expected-warning{{TRUE}} | 
 |  | 
 |   // Test equality operators. | 
 |   clang_analyzer_eval((local + 1) != 1); // expected-warning{{TRUE}} | 
 |   clang_analyzer_eval(1 != (local + 1)); // expected-warning{{TRUE}} | 
 | } | 
 |  | 
 | void PR12206_truncation(signed char x) { | 
 |   // Build a SymIntExpr, dependent on x. | 
 |   signed char local = x - 1; | 
 |  | 
 |   // Constrain the value of x. | 
 |   if (x != 1) return; | 
 |  | 
 |   // Constant-folding will turn (local+1) back into the symbol for x. | 
 |   // The point of this dance is to make SValBuilder be responsible for | 
 |   // turning the symbol into a ConcreteInt, rather than ExprEngine. | 
 |  | 
 |   // Construct a value that cannot be represented by 'char', | 
 |   // but that has the same lower bits as x. | 
 |   signed int value = 1 + (1 << 8); | 
 |  | 
 |   // Test relational operators. | 
 |   clang_analyzer_eval((local + 1) < value); // expected-warning{{TRUE}} | 
 |   clang_analyzer_eval(value > (local + 1)); // expected-warning{{TRUE}} | 
 |  | 
 |   // Test equality operators. | 
 |   clang_analyzer_eval((local + 1) != value); // expected-warning{{TRUE}} | 
 |   clang_analyzer_eval(value != (local + 1)); // expected-warning{{TRUE}} | 
 | } | 
 |  | 
 | // This test is insurance in case we significantly change how SymExprs are | 
 | // evaluated. | 
 | size_t strlen(const char *s); | 
 | void PR12206_strlen(const char *x) { | 
 |   size_t comparisonSize = sizeof(1 == 1); | 
 |  | 
 |   // Sanity check. This test is useless if size_t isn't bigger than bool. | 
 |   clang_analyzer_eval(sizeof(size_t) > comparisonSize); // expected-warning{{TRUE}} | 
 |  | 
 |   // Create a value that requires more bits to store than a comparison result. | 
 |   size_t value = 1UL; | 
 |   value <<= 8 * comparisonSize; | 
 |   value += 1; | 
 |  | 
 |   // Constrain the length of x. | 
 |   if (strlen(x) != value) return; | 
 |  | 
 |   // Test relational operators. | 
 |   clang_analyzer_eval(strlen(x) >= 2); // expected-warning{{TRUE}} | 
 |   clang_analyzer_eval(2 <= strlen(x)); // expected-warning{{TRUE}} | 
 |  | 
 |   // Test equality operators. | 
 |   clang_analyzer_eval(strlen(x) != 1); // expected-warning{{TRUE}} | 
 |   clang_analyzer_eval(1 != strlen(x)); // expected-warning{{TRUE}} | 
 | } |