// PR16664 and PR18159 void testConsistencyNestedWarning(bool value) { if (value) { if (!value || value || check(NoReturnDtor())) { clang_analyzer_eval(true); // expected-warning{{TRUE}} } } }
void testLoop() { for (int i = 0; i < 10; ++i) { if (i < 3 && (i >= 2 || check(NoReturnDtor()))) { clang_analyzer_eval(true); // no warning, unreachable code } } }
// PR16664 and PR18159 void testConsistencyNestedComplexNestedBranch(bool value) { if (value) { if (!value || (!value || check(NoReturnDtor()) || value)) { clang_analyzer_eval(true); // no warning, unreachable code } } }
void testConsistencyIf(int i) { if (i != 5) return; if (i == 5 && (i == 4 || check(NoReturnDtor()) || i == 5)) { clang_analyzer_eval(true); // no warning, unreachable code } }
void OperatorEvaluationTest(int y) { int x = 1; int w = x ?: y; // expected-note {{'?' condition is true}} // TODO: We are not precise when processing the "?:" operator in C++. clang_analyzer_eval(w == 1); // expected-warning{{UNKNOWN}} // expected-note@-1{{UNKNOWN}} }
void testConstrainState(int p) { ASSERT_TRUE(p == 7); clang_analyzer_eval(p == 7); // expected-warning {{TRUE}} ASSERT_TRUE(false); clang_analyzer_warnIfReached(); // no-warning }
void testReturnValue() { int i = 5; auto l = [i] (int a) { return i + a; }; int b = l(3); clang_analyzer_eval(b == 8); // expected-warning{{TRUE}} }
void testFunctionPointerCapture() { void (*func)(int &) = inc; int i = 5; [&i, func] { func(i); }(); clang_analyzer_eval(i == 6); // expected-warning{{TRUE}} }
void f8() { C *after, *before; { A a[2] = {C(false, nullptr, nullptr), C(true, &after, &before)}; } // FIXME: Should be TRUE. Should not warn about garbage value. clang_analyzer_eval(after == before); // expected-warning{{UNKNOWN}} }
void checkThatConstMethodCallDoesInvalidateObjectForCircularReferences() { Outer2 t; t.x = 1; t.in.ref = &t; t.foo(); // FIXME: Should be UNKNOWN. clang_analyzer_eval(t.x); // expected-warning{{TRUE}} }
void testStrlenCallee() { char str[42]; invalidate(str); size_t lenBefore = strlenWrapper(str); invalidate(str); size_t lenAfter = strlenWrapper(str); clang_analyzer_eval(lenBefore == lenAfter); // expected-warning{{UNKNOWN}} }
void testCtorInitializer() { AddressVector<ClassWithDestructor> v; { TestCtorInitializer t(v); // Check if the last destructor is an automatic destructor. // A temporary destructor would have fired by now. #if ELIDE clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}} #else clang_analyzer_eval(v.len == 3); // expected-warning{{TRUE}} #endif } #if ELIDE // 0. Construct the member variable. // 1. Destroy the member variable. clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}} clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}} #else // 0. Construct the temporary. // 1. Construct the member variable. // 2. Destroy the temporary. // 3. Destroy the member variable. clang_analyzer_eval(v.len == 4); // expected-warning{{TRUE}} clang_analyzer_eval(v.buf[0] == v.buf[2]); // expected-warning{{TRUE}} clang_analyzer_eval(v.buf[1] == v.buf[3]); // expected-warning{{TRUE}} #endif }
void test() { Derived* p; *(reinterpret_cast<void**>(&p)) = new C; p->f(); // We should still be able to do some reasoning about bindings. p->x = 42; clang_analyzer_eval(p->x == 42); // expected-warning{{TRUE}} };
void loopWithCall() { void *arr[2]; for (int i = 0; i < 2; ++i) { int x; arr[i] = &x; } // FIXME: Should be UNKNOWN. clang_analyzer_eval(arr[0] == arr[1]); // expected-warning{{TRUE}} }
void f() { const int &x = A().i; // no-crash const int &y = A().j[1]; // no-crash const int &z = (A().j[1], A().j[0]); // no-crash clang_analyzer_eval(x == 1); clang_analyzer_eval(y == 3); clang_analyzer_eval(z == 2); #ifdef TEMPORARIES // expected-warning@-4{{TRUE}} // expected-warning@-4{{TRUE}} // expected-warning@-4{{TRUE}} #else // expected-warning@-8{{UNKNOWN}} // expected-warning@-8{{UNKNOWN}} // expected-warning@-8{{UNKNOWN}} #endif }
// PR16664 and PR18159 void testConsistencyNestedVariableModification(bool value) { bool other = true; if (value) { if (!other || !value || (other = false) || check(NoReturnDtor()) || !other) { clang_analyzer_eval(true); // no warning, unreachable code } } }
void testAliasingBetweenParameterAndCapture() { int i = 5; auto l = [&i](int &p) { i++; p++; }; l(i); clang_analyzer_eval(i == 7); // expected-warning{{TRUE}} }
void callMutableLambdaMultipleTimes(int &p) { int v = 0; p = 8; auto l = [&v, p]() mutable { v = p; p++; }; l(); clang_analyzer_eval(v == 8); // expected-warning{{TRUE}} clang_analyzer_eval(p == 8); // expected-warning{{TRUE}} l(); clang_analyzer_eval(v == 9); // expected-warning{{TRUE}} clang_analyzer_eval(p == 8); // expected-warning{{TRUE}} }
void captureFields() { i = 5; [this]() { // clang_analyzer_eval does nothing in inlined functions. if (i != 5) clang_analyzer_warnIfReached(); ++i; }(); clang_analyzer_eval(i == 6); // expected-warning{{TRUE}} }
void testFunctionPointerReturn(void *opaque) { typedef int &(*RefFn)(); RefFn getRef = (RefFn)opaque; // Don't crash writing to or reading from this reference. int &x = getRef(); x = 42; clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} }
void foo() { D d; d.f = 7; int B::* pfb = &B::f; int D::* pfd = pfb; int v = d.*pfd; clang_analyzer_eval(v == 7); // expected-warning{{TRUE}} }
void foo() { int x = 0; S(x).x += 1; clang_analyzer_eval(x == 1); #ifdef INLINE // expected-warning@-2{{TRUE}} #else // expected-warning@-4{{UNKNOWN}} #endif }
void f2() { C *after, *before; C c = C(1, &after, &before); clang_analyzer_eval(after == before); #ifdef TEMPORARIES // expected-warning@-2{{TRUE}} #else // expected-warning@-4{{UNKNOWN}} #endif }
void test() { Child obj; obj.x = 42; // Originally, calling a devirtualized method with a covariant return type // caused a crash because the return value had the wrong type. When we then // go to layer a CXXBaseObjectRegion on it, the base isn't a direct base of // the object region and we get an assertion failure. clang_analyzer_eval(obj.getThis()->x == 42); // expected-warning{{TRUE}} }
void testVector(std::vector<int> &nums) { if (nums.begin() != nums.end()) return; clang_analyzer_eval(nums.size() == 0); #if INLINE // expected-warning@-2 {{TRUE}} #else // expected-warning@-4 {{UNKNOWN}} #endif }
void testException(std::exception e) { // Notice that the argument is NOT passed by reference, so we can devirtualize. const char *x = e.what(); clang_analyzer_eval(x == 0); #if INLINE // expected-warning@-2 {{TRUE}} #else // expected-warning@-4 {{UNKNOWN}} #endif }
void strlen_subregion() { struct two_strings { char a[2], b[2]; }; extern void use_two_strings(struct two_strings *); struct two_strings z; use_two_strings(&z); size_t a = strlen(z.a); z.b[0] = 5; size_t b = strlen(z.a); if (a == 0) clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} use_two_strings(&z); size_t c = strlen(z.a); if (a == 0) clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} }
C() : t(T(4)) { S s = {1, 2, 3}; t.s = s; // FIXME: Should be TRUE regardless of copy elision. clang_analyzer_eval(t.w == 4); #ifdef ELIDE // expected-warning@-2{{TRUE}} #else // expected-warning@-4{{UNKNOWN}} #endif }
void strlen_indirect2(char *x) { size_t a = strlen(x); char *p = x; char **p2 = &p; extern void use_string_ptr2(char**); use_string_ptr2(p2); size_t c = strlen(x); if (a == 0) clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} }
void testImplicitlyDeclaredGlobalNew() { if (someGlobal != 0) return; // This used to crash because the global operator new is being implicitly // declared and it does not have a valid source location. (PR13090) void *x = ::operator new(0); ::operator delete(x); // Check that the new/delete did not invalidate someGlobal; clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} }