forked from OSchip/llvm-project
[analyzer] Generate a LazyCompoundVal when loading from a union-typed region.
This ensures that variables accessible through a union are invalidated when the union value is passed to a function. We still don't fully handle union values, but this should at least quiet some false positives. PR16596 llvm-svn: 193265
This commit is contained in:
parent
48342ee908
commit
bb61c8cc73
|
@ -1312,7 +1312,7 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T)
|
||||||
|
|
||||||
// FIXME: Handle unions.
|
// FIXME: Handle unions.
|
||||||
if (RTy->isUnionType())
|
if (RTy->isUnionType())
|
||||||
return UnknownVal();
|
return createLazyBinding(B, R);
|
||||||
|
|
||||||
if (RTy->isArrayType()) {
|
if (RTy->isArrayType()) {
|
||||||
if (RTy->isConstantArrayType())
|
if (RTy->isConstantArrayType())
|
||||||
|
@ -1906,6 +1906,8 @@ RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) {
|
||||||
return bindStruct(B, TR, V);
|
return bindStruct(B, TR, V);
|
||||||
if (Ty->isVectorType())
|
if (Ty->isVectorType())
|
||||||
return bindVector(B, TR, V);
|
return bindVector(B, TR, V);
|
||||||
|
if (Ty->isUnionType())
|
||||||
|
return bindAggregate(B, TR, V);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
|
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// RUN: %clang_cc1 -analyze -analyzer-checker=core %s -verify
|
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection %s -verify
|
||||||
// expected-no-diagnostics
|
|
||||||
|
extern void clang_analyzer_eval(bool);
|
||||||
|
extern "C" char *strdup(const char *s);
|
||||||
|
|
||||||
namespace PR14054_reduced {
|
namespace PR14054_reduced {
|
||||||
struct Definition;
|
struct Definition;
|
||||||
|
@ -49,3 +51,58 @@ namespace PR14054_original {
|
||||||
x = pn->pn_u.name.lexdef->pn_u.name.lexdef;
|
x = pn->pn_u.name.lexdef->pn_u.name.lexdef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace PR17596 {
|
||||||
|
union IntOrString {
|
||||||
|
int i;
|
||||||
|
char *s;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void process(IntOrString);
|
||||||
|
|
||||||
|
void test() {
|
||||||
|
IntOrString uu;
|
||||||
|
uu.s = strdup("");
|
||||||
|
process(uu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testPositive() {
|
||||||
|
IntOrString uu;
|
||||||
|
uu.s = strdup("");
|
||||||
|
} // expected-warning{{leak}}
|
||||||
|
|
||||||
|
void testCopy() {
|
||||||
|
IntOrString uu;
|
||||||
|
uu.i = 4;
|
||||||
|
clang_analyzer_eval(uu.i == 4); // expected-warning{{TRUE}}
|
||||||
|
|
||||||
|
IntOrString vv;
|
||||||
|
vv.i = 5;
|
||||||
|
uu = vv;
|
||||||
|
// FIXME: Should be true.
|
||||||
|
clang_analyzer_eval(uu.i == 5); // expected-warning{{UNKNOWN}}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testInvalidation() {
|
||||||
|
IntOrString uu;
|
||||||
|
uu.s = strdup("");
|
||||||
|
|
||||||
|
IntOrString vv;
|
||||||
|
char str[] = "abc";
|
||||||
|
vv.s = str;
|
||||||
|
|
||||||
|
// FIXME: This is a leak of uu.s.
|
||||||
|
uu = vv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void testIndirectInvalidation() {
|
||||||
|
IntOrString uu;
|
||||||
|
char str[] = "abc";
|
||||||
|
uu.s = str;
|
||||||
|
|
||||||
|
clang_analyzer_eval(uu.s[0] == 'a'); // expected-warning{{TRUE}}
|
||||||
|
|
||||||
|
process(uu);
|
||||||
|
clang_analyzer_eval(uu.s[0] == 'a'); // expected-warning{{UNKNOWN}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue