[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:
Jordan Rose 2013-10-23 20:08:55 +00:00
parent 48342ee908
commit bb61c8cc73
2 changed files with 62 additions and 3 deletions

View File

@ -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)) {

View File

@ -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}}
}
}