mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 19:36:05 +00:00

It makes sense to track rvalue expressions in the case of special concrete integer values. The most notable special value is zero (later we may find other values). By tracking the origin of 0, we can provide a better explanation for users e.g. in case of division by 0 warnings. When the divisor is a product of a multiplication then now we can show which operand (or both) was (were) zero and why. Differential Revision: https://reviews.llvm.org/D99344
99 lines
4.3 KiB
C++
99 lines
4.3 KiB
C++
// RUN: %clang_analyze_cc1 -analyzer-checker=core \
|
|
// RUN: -analyzer-output=text \
|
|
// RUN: -verify %s
|
|
|
|
namespace test_tracking_of_lhs_multiplier {
|
|
int f(int x, int y) {
|
|
bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \
|
|
// expected-note {{'p0' initialized to 0}}
|
|
int div = p0 * y; // expected-note {{'div' initialized to 0}}
|
|
return 1 / div; // expected-note {{Division by zero}} \
|
|
// expected-warning {{Division by zero}}
|
|
}
|
|
} // namespace test_tracking_of_lhs_multiplier
|
|
|
|
namespace test_tracking_of_rhs_multiplier {
|
|
int f(int x, int y) {
|
|
bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \
|
|
// expected-note {{'p0' initialized to 0}}
|
|
int div = y * p0; // expected-note {{'div' initialized to 0}}
|
|
return 1 / div; // expected-note {{Division by zero}} \
|
|
// expected-warning {{Division by zero}}
|
|
}
|
|
} // namespace test_tracking_of_rhs_multiplier
|
|
|
|
namespace test_tracking_of_nested_multiplier {
|
|
int f(int x, int y, int z) {
|
|
bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \
|
|
// expected-note {{'p0' initialized to 0}}
|
|
int div = y*z*p0; // expected-note {{'div' initialized to 0}}
|
|
return 1 / div; // expected-note {{Division by zero}} \
|
|
// expected-warning {{Division by zero}}
|
|
}
|
|
} // namespace test_tracking_of_nested_multiplier
|
|
|
|
namespace test_tracking_through_multiple_stmts {
|
|
int f(int x, int y) {
|
|
bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}}
|
|
bool p1 = p0 ? 0 : 1; // expected-note {{'p0' is false}} \
|
|
// expected-note {{'?' condition is false}}
|
|
bool p2 = 1 - p1; // expected-note {{'p2' initialized to 0}}
|
|
int div = p2 * y; // expected-note {{'div' initialized to 0}}
|
|
return 1 / div; // expected-note {{Division by zero}} \
|
|
// expected-warning {{Division by zero}}
|
|
}
|
|
} // namespace test_tracking_through_multiple_stmts
|
|
|
|
namespace test_tracking_both_lhs_and_rhs {
|
|
int f(int x, int y) {
|
|
bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \
|
|
// expected-note {{'p0' initialized to 0}}
|
|
bool p1 = y < 0; // expected-note {{Assuming 'y' is >= 0}} \
|
|
// expected-note {{'p1' initialized to 0}}
|
|
int div = p0 * p1; // expected-note {{'div' initialized to 0}}
|
|
return 1 / div; // expected-note {{Division by zero}} \
|
|
// expected-warning {{Division by zero}}
|
|
}
|
|
} // namespace test_tracking_both_lhs_and_rhs
|
|
|
|
namespace test_tracking_of_multiplier_and_parens {
|
|
int f(int x, int y, int z) {
|
|
bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \
|
|
// expected-note {{'p0' initialized to 0}}
|
|
int div = y*(z*p0); // expected-note {{'div' initialized to 0}}
|
|
return 1 / div; // expected-note {{Division by zero}} \
|
|
// expected-warning {{Division by zero}}
|
|
}
|
|
} // namespace test_tracking_of_multiplier_and_parens
|
|
|
|
namespace test_tracking_of_divisible {
|
|
int f(int x, int y) {
|
|
bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \
|
|
// expected-note {{'p0' initialized to 0}}
|
|
int div = p0 / y; // expected-note {{'div' initialized to 0}}
|
|
return 1 / div; // expected-note {{Division by zero}} \
|
|
// expected-warning {{Division by zero}}
|
|
}
|
|
} // namespace test_tracking_of_divisible
|
|
|
|
namespace test_tracking_of_modulo {
|
|
int f(int x, int y) {
|
|
bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \
|
|
// expected-note {{'p0' initialized to 0}}
|
|
int div = p0 % y; // expected-note {{'div' initialized to 0}}
|
|
return 1 / div; // expected-note {{Division by zero}} \
|
|
// expected-warning {{Division by zero}}
|
|
}
|
|
} // namespace test_tracking_of_modulo
|
|
|
|
namespace test_tracking_of_assignment {
|
|
int f(int x) {
|
|
bool p0 = x < 0; // expected-note {{Assuming 'x' is >= 0}} \
|
|
// expected-note {{'p0' initialized to 0}}
|
|
int div = 1;
|
|
div *= p0; // expected-note {{The value 0 is assigned to 'div'}}
|
|
return 1 / div; // expected-note {{Division by zero}} \
|
|
// expected-warning {{Division by zero}}
|
|
}
|
|
} // namespace test_tracking_of_assignment
|