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.
|
||||
if (RTy->isUnionType())
|
||||
return UnknownVal();
|
||||
return createLazyBinding(B, R);
|
||||
|
||||
if (RTy->isArrayType()) {
|
||||
if (RTy->isConstantArrayType())
|
||||
|
@ -1906,6 +1906,8 @@ RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) {
|
|||
return bindStruct(B, TR, V);
|
||||
if (Ty->isVectorType())
|
||||
return bindVector(B, TR, V);
|
||||
if (Ty->isUnionType())
|
||||
return bindAggregate(B, TR, V);
|
||||
}
|
||||
|
||||
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// RUN: %clang_cc1 -analyze -analyzer-checker=core %s -verify
|
||||
// expected-no-diagnostics
|
||||
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection %s -verify
|
||||
|
||||
extern void clang_analyzer_eval(bool);
|
||||
extern "C" char *strdup(const char *s);
|
||||
|
||||
namespace PR14054_reduced {
|
||||
struct Definition;
|
||||
|
@ -49,3 +51,58 @@ namespace PR14054_original {
|
|||
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