SVal getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
const TypedValueRegion *R,
- QualType Ty,
- const MemRegion *superR);
+ QualType Ty);
SVal getLazyBinding(const SubRegion *LazyBindingRegion,
RegionBindingsRef LazyBinding);
}
}
}
- return getBindingForFieldOrElementCommon(B, R, R->getElementType(),superR);
+ return getBindingForFieldOrElementCommon(B, R, R->getElementType());
}
SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B,
return *V;
QualType Ty = R->getValueType();
- return getBindingForFieldOrElementCommon(B, R, Ty, R->getSuperRegion());
+ return getBindingForFieldOrElementCommon(B, R, Ty);
}
Optional<SVal>
SVal
RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
const TypedValueRegion *R,
- QualType Ty,
- const MemRegion *superR) {
+ QualType Ty) {
// At this point we have already checked in either getBindingForElement or
// getBindingForField if 'R' has a direct binding.
// quickly result in a warning.
bool hasPartialLazyBinding = false;
- const SubRegion *Base = dyn_cast<SubRegion>(superR);
- while (Base) {
+ const SubRegion *SR = dyn_cast<SubRegion>(R);
+ while (SR) {
+ const MemRegion *Base = SR->getSuperRegion();
if (Optional<SVal> D = getBindingForDerivedDefaultValue(B, Base, R, Ty)) {
if (D->getAs<nonloc::LazyCompoundVal>()) {
hasPartialLazyBinding = true;
// If our super region is a field or element itself, walk up the region
// hierarchy to see if there is a default value installed in an ancestor.
- Base = dyn_cast<SubRegion>(Base->getSuperRegion());
+ SR = dyn_cast<SubRegion>(Base);
}
if (R->hasStackNonParametersStorage()) {
// Currently we don't reason specially about Clang-style vectors. Check
// if superR is a vector and if so return Unknown.
if (const TypedValueRegion *typedSuperR =
- dyn_cast<TypedValueRegion>(superR)) {
+ dyn_cast<TypedValueRegion>(R->getSuperRegion())) {
if (typedSuperR->getValueType()->isVectorType())
return UnknownVal();
}
void clang_analyzer_eval(int);
+#include "Inputs/system-header-simulator.h"
+
void use(int);
id foo(int x) {
if (x)
}
extern int globalInt;
-extern struct {
+struct IntWrapper {
int value;
-} globalStruct;
+};
+extern struct IntWrapper globalStruct;
extern void invalidateGlobals();
void testGlobalInvalidation() {
invalidateGlobals();
clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
+
+ // Repeat to make sure we don't get the /same/ new symbolic values.
+ if (globalInt != 42)
+ return;
+ if (globalStruct.value != 43)
+ return;
+ clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{TRUE}}
+
+ invalidateGlobals();
+ clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
}
void testGlobalInvalidationWithDirectBinding() {
clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(globalStruct.value == 43); // expected-warning{{UNKNOWN}}
}
+
+void testStaticLocals(void) {
+ static int i;
+ int tmp;
+
+ extern int someSymbolicValue();
+ i = someSymbolicValue();
+
+ if (i == 5) {
+ clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
+ scanf("%d", &tmp);
+ clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
+ }
+
+ i = 6;
+ clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
+ scanf("%d", &tmp);
+ clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
+
+ i = someSymbolicValue();
+ if (i == 7) {
+ clang_analyzer_eval(i == 7); // expected-warning{{TRUE}}
+ scanf("%d", &i);
+ clang_analyzer_eval(i == 7); // expected-warning{{UNKNOWN}}
+ }
+
+ i = 8;
+ clang_analyzer_eval(i == 8); // expected-warning{{TRUE}}
+ scanf("%d", &i);
+ clang_analyzer_eval(i == 8); // expected-warning{{UNKNOWN}}
+}
+
+void testNonSystemGlobals(void) {
+ extern int i;
+ int tmp;
+
+ if (i == 5) {
+ clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
+ scanf("%d", &tmp);
+ clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(i == 5); // expected-warning{{UNKNOWN}}
+ }
+
+ i = 6;
+ clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
+ scanf("%d", &tmp);
+ clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(i == 6); // expected-warning{{UNKNOWN}}
+
+ if (i == 7) {
+ clang_analyzer_eval(i == 7); // expected-warning{{TRUE}}
+ scanf("%d", &i);
+ clang_analyzer_eval(i == 7); // expected-warning{{UNKNOWN}}
+ }
+
+ i = 8;
+ clang_analyzer_eval(i == 8); // expected-warning{{TRUE}}
+ scanf("%d", &i);
+ clang_analyzer_eval(i == 8); // expected-warning{{UNKNOWN}}
+}
+
+void testWrappedGlobals(void) {
+ extern char c;
+ SomeStruct s;
+
+ if (c == 'C') {
+ s.p = &c;
+ clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(0);
+ clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(&s);
+ clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}}
+ }
+
+ c = 'c';
+ s.p = &c;
+ clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(0);
+ clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(&s);
+ clang_analyzer_eval(c == 'c'); // expected-warning{{UNKNOWN}}
+
+ if (c == 'C') {
+ s.p = &c;
+ clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(0);
+ clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
+ fakeSystemHeaderCall(&s);
+ clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}}
+ }
+}
+
+void testWrappedStaticsViaGlobal(void) {
+ static char c;
+ extern SomeStruct s;
+
+ extern char getSomeChar();
+ c = getSomeChar();
+
+ if (c == 'C') {
+ s.p = &c;
+ clang_analyzer_eval(c == 'C'); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(c == 'C'); // expected-warning{{UNKNOWN}}
+ }
+
+ c = 'c';
+ s.p = &c;
+ clang_analyzer_eval(c == 'c'); // expected-warning{{TRUE}}
+ invalidateGlobals();
+ clang_analyzer_eval(c == 'c'); // expected-warning{{UNKNOWN}}
+}