2013-01-31 10:57:06 +08:00
|
|
|
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
|
2008-09-20 04:53:52 +08:00
|
|
|
|
|
|
|
typedef unsigned int NSUInteger;
|
2013-01-31 10:57:06 +08:00
|
|
|
typedef __typeof__(sizeof(int)) size_t;
|
|
|
|
|
|
|
|
void *malloc(size_t);
|
|
|
|
void *calloc(size_t nmemb, size_t size);
|
|
|
|
void free(void *);
|
|
|
|
|
|
|
|
void clang_analyzer_eval(int);
|
2008-09-20 04:53:52 +08:00
|
|
|
|
|
|
|
@interface A
|
|
|
|
- (NSUInteger)foo;
|
|
|
|
@end
|
|
|
|
|
|
|
|
NSUInteger f8(A* x){
|
|
|
|
const NSUInteger n = [x foo];
|
|
|
|
int* bogus;
|
|
|
|
|
|
|
|
if (n > 0) { // tests const cast transfer function logic
|
|
|
|
NSUInteger i;
|
|
|
|
|
|
|
|
for (i = 0; i < n; ++i)
|
|
|
|
bogus = 0;
|
|
|
|
|
|
|
|
if (bogus) // no-warning
|
|
|
|
return n+1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
2011-06-28 04:36:38 +08:00
|
|
|
|
|
|
|
|
|
|
|
// PR10163 -- don't warn for default-initialized float arrays.
|
|
|
|
// (An additional test is in uninit-vals-ps-region.m)
|
|
|
|
void test_PR10163(float);
|
|
|
|
void PR10163 (void) {
|
|
|
|
float x[2] = {0};
|
|
|
|
test_PR10163(x[1]); // no-warning
|
|
|
|
}
|
2013-01-31 10:57:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
float x;
|
|
|
|
float y;
|
[analyzer] "Force" LazyCompoundVals on bind when they are simple enough.
The analyzer uses LazyCompoundVals to represent rvalues of aggregate types,
most importantly structs and arrays. This allows us to efficiently copy
around an entire struct, rather than doing a memberwise load every time a
struct rvalue is encountered. This can also keep memory usage down by
allowing several structs to "share" the same snapshotted bindings.
However, /lookup/ through LazyCompoundVals can be expensive, especially
since they can end up chaining back to the original value. While we try
to reuse LazyCompoundVals whenever it's safe, and cache information about
this transitivity, the fact is it's sometimes just not a good idea to
perpetuate LazyCompoundVals -- the tradeoffs just aren't worth it.
This commit changes RegionStore so that binding a LazyCompoundVal to struct
will do a memberwise copy if the struct is simple enough. Today's definition
of "simple enough" is "up to N scalar members" (see below), but that could
easily be changed in the future. This is enough to bring the test case in
PR15697 back down to a manageable analysis time (within 20% of its original
time, in an unfair test where the new analyzer is not compiled with LTO).
The actual value of "N" is controlled by a new -analyzer-config option,
'region-store-small-struct-limit'. It defaults to "2", meaning structs with
zero, one, or two scalar members will be considered "simple enough" for
this code path.
It's worth noting that a more straightforward implementation would do this
on load, not on bind, and make use of the structure we already have for this:
CompoundVal. A long time ago, this was actually how RegionStore modeled
aggregate-to-aggregate copies, but today it's only used for compound literals.
Unfortunately, it seems that we've special-cased LazyCompoundVal in certain
places (such as liveness checks) but failed to similarly special-case
CompoundVal in all of them. Until we're confident that CompoundVal is
handled properly everywhere, this solution is safer, since the entire
optimization is just an implementation detail of RegionStore.
<rdar://problem/13599304>
llvm-svn: 179767
2013-04-19 00:33:46 +08:00
|
|
|
float z;
|
2013-01-31 10:57:06 +08:00
|
|
|
} Point;
|
|
|
|
typedef struct {
|
|
|
|
Point origin;
|
|
|
|
int size;
|
|
|
|
} Circle;
|
|
|
|
|
|
|
|
Point makePoint(float x, float y) {
|
|
|
|
Point result;
|
|
|
|
result.x = x;
|
|
|
|
result.y = y;
|
[analyzer] "Force" LazyCompoundVals on bind when they are simple enough.
The analyzer uses LazyCompoundVals to represent rvalues of aggregate types,
most importantly structs and arrays. This allows us to efficiently copy
around an entire struct, rather than doing a memberwise load every time a
struct rvalue is encountered. This can also keep memory usage down by
allowing several structs to "share" the same snapshotted bindings.
However, /lookup/ through LazyCompoundVals can be expensive, especially
since they can end up chaining back to the original value. While we try
to reuse LazyCompoundVals whenever it's safe, and cache information about
this transitivity, the fact is it's sometimes just not a good idea to
perpetuate LazyCompoundVals -- the tradeoffs just aren't worth it.
This commit changes RegionStore so that binding a LazyCompoundVal to struct
will do a memberwise copy if the struct is simple enough. Today's definition
of "simple enough" is "up to N scalar members" (see below), but that could
easily be changed in the future. This is enough to bring the test case in
PR15697 back down to a manageable analysis time (within 20% of its original
time, in an unfair test where the new analyzer is not compiled with LTO).
The actual value of "N" is controlled by a new -analyzer-config option,
'region-store-small-struct-limit'. It defaults to "2", meaning structs with
zero, one, or two scalar members will be considered "simple enough" for
this code path.
It's worth noting that a more straightforward implementation would do this
on load, not on bind, and make use of the structure we already have for this:
CompoundVal. A long time ago, this was actually how RegionStore modeled
aggregate-to-aggregate copies, but today it's only used for compound literals.
Unfortunately, it seems that we've special-cased LazyCompoundVal in certain
places (such as liveness checks) but failed to similarly special-case
CompoundVal in all of them. Until we're confident that CompoundVal is
handled properly everywhere, this solution is safer, since the entire
optimization is just an implementation detail of RegionStore.
<rdar://problem/13599304>
llvm-svn: 179767
2013-04-19 00:33:46 +08:00
|
|
|
result.z = 0.0;
|
2013-01-31 10:57:06 +08:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PR14765_test() {
|
|
|
|
Circle *testObj = calloc(sizeof(Circle), 1);
|
|
|
|
|
|
|
|
clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
|
|
|
|
|
|
|
|
testObj->origin = makePoint(0.0, 0.0);
|
|
|
|
if (testObj->size > 0) { ; } // warning occurs here
|
|
|
|
|
|
|
|
// FIXME: Assigning to 'testObj->origin' kills the default binding for the
|
|
|
|
// whole region, meaning that we've forgotten that testObj->size should also
|
|
|
|
// default to 0. Tracked by <rdar://problem/12701038>.
|
|
|
|
// This should be TRUE.
|
|
|
|
clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}}
|
|
|
|
|
|
|
|
free(testObj);
|
|
|
|
}
|
|
|
|
|
2013-03-20 07:01:57 +08:00
|
|
|
void PR14765_argument(Circle *testObj) {
|
2013-01-31 10:57:06 +08:00
|
|
|
int oldSize = testObj->size;
|
|
|
|
clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
|
|
|
|
|
|
|
|
testObj->origin = makePoint(0.0, 0.0);
|
2013-03-20 06:38:09 +08:00
|
|
|
clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
|
2013-03-20 07:01:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int x;
|
|
|
|
int y;
|
[analyzer] "Force" LazyCompoundVals on bind when they are simple enough.
The analyzer uses LazyCompoundVals to represent rvalues of aggregate types,
most importantly structs and arrays. This allows us to efficiently copy
around an entire struct, rather than doing a memberwise load every time a
struct rvalue is encountered. This can also keep memory usage down by
allowing several structs to "share" the same snapshotted bindings.
However, /lookup/ through LazyCompoundVals can be expensive, especially
since they can end up chaining back to the original value. While we try
to reuse LazyCompoundVals whenever it's safe, and cache information about
this transitivity, the fact is it's sometimes just not a good idea to
perpetuate LazyCompoundVals -- the tradeoffs just aren't worth it.
This commit changes RegionStore so that binding a LazyCompoundVal to struct
will do a memberwise copy if the struct is simple enough. Today's definition
of "simple enough" is "up to N scalar members" (see below), but that could
easily be changed in the future. This is enough to bring the test case in
PR15697 back down to a manageable analysis time (within 20% of its original
time, in an unfair test where the new analyzer is not compiled with LTO).
The actual value of "N" is controlled by a new -analyzer-config option,
'region-store-small-struct-limit'. It defaults to "2", meaning structs with
zero, one, or two scalar members will be considered "simple enough" for
this code path.
It's worth noting that a more straightforward implementation would do this
on load, not on bind, and make use of the structure we already have for this:
CompoundVal. A long time ago, this was actually how RegionStore modeled
aggregate-to-aggregate copies, but today it's only used for compound literals.
Unfortunately, it seems that we've special-cased LazyCompoundVal in certain
places (such as liveness checks) but failed to similarly special-case
CompoundVal in all of them. Until we're confident that CompoundVal is
handled properly everywhere, this solution is safer, since the entire
optimization is just an implementation detail of RegionStore.
<rdar://problem/13599304>
llvm-svn: 179767
2013-04-19 00:33:46 +08:00
|
|
|
int z;
|
2013-03-20 07:01:57 +08:00
|
|
|
} IntPoint;
|
|
|
|
typedef struct {
|
|
|
|
IntPoint origin;
|
|
|
|
int size;
|
|
|
|
} IntCircle;
|
|
|
|
|
|
|
|
IntPoint makeIntPoint(int x, int y) {
|
|
|
|
IntPoint result;
|
|
|
|
result.x = x;
|
|
|
|
result.y = y;
|
[analyzer] "Force" LazyCompoundVals on bind when they are simple enough.
The analyzer uses LazyCompoundVals to represent rvalues of aggregate types,
most importantly structs and arrays. This allows us to efficiently copy
around an entire struct, rather than doing a memberwise load every time a
struct rvalue is encountered. This can also keep memory usage down by
allowing several structs to "share" the same snapshotted bindings.
However, /lookup/ through LazyCompoundVals can be expensive, especially
since they can end up chaining back to the original value. While we try
to reuse LazyCompoundVals whenever it's safe, and cache information about
this transitivity, the fact is it's sometimes just not a good idea to
perpetuate LazyCompoundVals -- the tradeoffs just aren't worth it.
This commit changes RegionStore so that binding a LazyCompoundVal to struct
will do a memberwise copy if the struct is simple enough. Today's definition
of "simple enough" is "up to N scalar members" (see below), but that could
easily be changed in the future. This is enough to bring the test case in
PR15697 back down to a manageable analysis time (within 20% of its original
time, in an unfair test where the new analyzer is not compiled with LTO).
The actual value of "N" is controlled by a new -analyzer-config option,
'region-store-small-struct-limit'. It defaults to "2", meaning structs with
zero, one, or two scalar members will be considered "simple enough" for
this code path.
It's worth noting that a more straightforward implementation would do this
on load, not on bind, and make use of the structure we already have for this:
CompoundVal. A long time ago, this was actually how RegionStore modeled
aggregate-to-aggregate copies, but today it's only used for compound literals.
Unfortunately, it seems that we've special-cased LazyCompoundVal in certain
places (such as liveness checks) but failed to similarly special-case
CompoundVal in all of them. Until we're confident that CompoundVal is
handled properly everywhere, this solution is safer, since the entire
optimization is just an implementation detail of RegionStore.
<rdar://problem/13599304>
llvm-svn: 179767
2013-04-19 00:33:46 +08:00
|
|
|
result.z = 0;
|
2013-03-20 07:01:57 +08:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PR14765_test_int() {
|
|
|
|
IntCircle *testObj = calloc(sizeof(IntCircle), 1);
|
|
|
|
|
|
|
|
clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}}
|
[analyzer] "Force" LazyCompoundVals on bind when they are simple enough.
The analyzer uses LazyCompoundVals to represent rvalues of aggregate types,
most importantly structs and arrays. This allows us to efficiently copy
around an entire struct, rather than doing a memberwise load every time a
struct rvalue is encountered. This can also keep memory usage down by
allowing several structs to "share" the same snapshotted bindings.
However, /lookup/ through LazyCompoundVals can be expensive, especially
since they can end up chaining back to the original value. While we try
to reuse LazyCompoundVals whenever it's safe, and cache information about
this transitivity, the fact is it's sometimes just not a good idea to
perpetuate LazyCompoundVals -- the tradeoffs just aren't worth it.
This commit changes RegionStore so that binding a LazyCompoundVal to struct
will do a memberwise copy if the struct is simple enough. Today's definition
of "simple enough" is "up to N scalar members" (see below), but that could
easily be changed in the future. This is enough to bring the test case in
PR15697 back down to a manageable analysis time (within 20% of its original
time, in an unfair test where the new analyzer is not compiled with LTO).
The actual value of "N" is controlled by a new -analyzer-config option,
'region-store-small-struct-limit'. It defaults to "2", meaning structs with
zero, one, or two scalar members will be considered "simple enough" for
this code path.
It's worth noting that a more straightforward implementation would do this
on load, not on bind, and make use of the structure we already have for this:
CompoundVal. A long time ago, this was actually how RegionStore modeled
aggregate-to-aggregate copies, but today it's only used for compound literals.
Unfortunately, it seems that we've special-cased LazyCompoundVal in certain
places (such as liveness checks) but failed to similarly special-case
CompoundVal in all of them. Until we're confident that CompoundVal is
handled properly everywhere, this solution is safer, since the entire
optimization is just an implementation detail of RegionStore.
<rdar://problem/13599304>
llvm-svn: 179767
2013-04-19 00:33:46 +08:00
|
|
|
clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
|
2013-03-20 07:01:57 +08:00
|
|
|
|
|
|
|
testObj->origin = makeIntPoint(1, 2);
|
|
|
|
if (testObj->size > 0) { ; } // warning occurs here
|
|
|
|
|
|
|
|
// FIXME: Assigning to 'testObj->origin' kills the default binding for the
|
|
|
|
// whole region, meaning that we've forgotten that testObj->size should also
|
|
|
|
// default to 0. Tracked by <rdar://problem/12701038>.
|
|
|
|
// This should be TRUE.
|
|
|
|
clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}}
|
|
|
|
clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
|
[analyzer] "Force" LazyCompoundVals on bind when they are simple enough.
The analyzer uses LazyCompoundVals to represent rvalues of aggregate types,
most importantly structs and arrays. This allows us to efficiently copy
around an entire struct, rather than doing a memberwise load every time a
struct rvalue is encountered. This can also keep memory usage down by
allowing several structs to "share" the same snapshotted bindings.
However, /lookup/ through LazyCompoundVals can be expensive, especially
since they can end up chaining back to the original value. While we try
to reuse LazyCompoundVals whenever it's safe, and cache information about
this transitivity, the fact is it's sometimes just not a good idea to
perpetuate LazyCompoundVals -- the tradeoffs just aren't worth it.
This commit changes RegionStore so that binding a LazyCompoundVal to struct
will do a memberwise copy if the struct is simple enough. Today's definition
of "simple enough" is "up to N scalar members" (see below), but that could
easily be changed in the future. This is enough to bring the test case in
PR15697 back down to a manageable analysis time (within 20% of its original
time, in an unfair test where the new analyzer is not compiled with LTO).
The actual value of "N" is controlled by a new -analyzer-config option,
'region-store-small-struct-limit'. It defaults to "2", meaning structs with
zero, one, or two scalar members will be considered "simple enough" for
this code path.
It's worth noting that a more straightforward implementation would do this
on load, not on bind, and make use of the structure we already have for this:
CompoundVal. A long time ago, this was actually how RegionStore modeled
aggregate-to-aggregate copies, but today it's only used for compound literals.
Unfortunately, it seems that we've special-cased LazyCompoundVal in certain
places (such as liveness checks) but failed to similarly special-case
CompoundVal in all of them. Until we're confident that CompoundVal is
handled properly everywhere, this solution is safer, since the entire
optimization is just an implementation detail of RegionStore.
<rdar://problem/13599304>
llvm-svn: 179767
2013-04-19 00:33:46 +08:00
|
|
|
clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
|
2013-03-20 07:01:57 +08:00
|
|
|
|
2013-01-31 10:57:06 +08:00
|
|
|
free(testObj);
|
|
|
|
}
|
|
|
|
|
2013-03-20 07:01:57 +08:00
|
|
|
void PR14765_argument_int(IntCircle *testObj) {
|
|
|
|
int oldSize = testObj->size;
|
|
|
|
clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
|
|
|
|
|
|
|
|
testObj->origin = makeIntPoint(1, 2);
|
|
|
|
clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
|
[analyzer] "Force" LazyCompoundVals on bind when they are simple enough.
The analyzer uses LazyCompoundVals to represent rvalues of aggregate types,
most importantly structs and arrays. This allows us to efficiently copy
around an entire struct, rather than doing a memberwise load every time a
struct rvalue is encountered. This can also keep memory usage down by
allowing several structs to "share" the same snapshotted bindings.
However, /lookup/ through LazyCompoundVals can be expensive, especially
since they can end up chaining back to the original value. While we try
to reuse LazyCompoundVals whenever it's safe, and cache information about
this transitivity, the fact is it's sometimes just not a good idea to
perpetuate LazyCompoundVals -- the tradeoffs just aren't worth it.
This commit changes RegionStore so that binding a LazyCompoundVal to struct
will do a memberwise copy if the struct is simple enough. Today's definition
of "simple enough" is "up to N scalar members" (see below), but that could
easily be changed in the future. This is enough to bring the test case in
PR15697 back down to a manageable analysis time (within 20% of its original
time, in an unfair test where the new analyzer is not compiled with LTO).
The actual value of "N" is controlled by a new -analyzer-config option,
'region-store-small-struct-limit'. It defaults to "2", meaning structs with
zero, one, or two scalar members will be considered "simple enough" for
this code path.
It's worth noting that a more straightforward implementation would do this
on load, not on bind, and make use of the structure we already have for this:
CompoundVal. A long time ago, this was actually how RegionStore modeled
aggregate-to-aggregate copies, but today it's only used for compound literals.
Unfortunately, it seems that we've special-cased LazyCompoundVal in certain
places (such as liveness checks) but failed to similarly special-case
CompoundVal in all of them. Until we're confident that CompoundVal is
handled properly everywhere, this solution is safer, since the entire
optimization is just an implementation detail of RegionStore.
<rdar://problem/13599304>
llvm-svn: 179767
2013-04-19 00:33:46 +08:00
|
|
|
clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
|
2013-03-20 07:01:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-27 08:05:29 +08:00
|
|
|
void rdar13292559(Circle input) {
|
|
|
|
extern void useCircle(Circle);
|
|
|
|
|
|
|
|
Circle obj = input;
|
|
|
|
useCircle(obj); // no-warning
|
|
|
|
|
|
|
|
// This generated an "uninitialized 'size' field" warning for a (short) while.
|
|
|
|
obj.origin = makePoint(0.0, 0.0);
|
|
|
|
useCircle(obj); // no-warning
|
|
|
|
}
|
|
|
|
|
[analyzer] "Force" LazyCompoundVals on bind when they are simple enough.
The analyzer uses LazyCompoundVals to represent rvalues of aggregate types,
most importantly structs and arrays. This allows us to efficiently copy
around an entire struct, rather than doing a memberwise load every time a
struct rvalue is encountered. This can also keep memory usage down by
allowing several structs to "share" the same snapshotted bindings.
However, /lookup/ through LazyCompoundVals can be expensive, especially
since they can end up chaining back to the original value. While we try
to reuse LazyCompoundVals whenever it's safe, and cache information about
this transitivity, the fact is it's sometimes just not a good idea to
perpetuate LazyCompoundVals -- the tradeoffs just aren't worth it.
This commit changes RegionStore so that binding a LazyCompoundVal to struct
will do a memberwise copy if the struct is simple enough. Today's definition
of "simple enough" is "up to N scalar members" (see below), but that could
easily be changed in the future. This is enough to bring the test case in
PR15697 back down to a manageable analysis time (within 20% of its original
time, in an unfair test where the new analyzer is not compiled with LTO).
The actual value of "N" is controlled by a new -analyzer-config option,
'region-store-small-struct-limit'. It defaults to "2", meaning structs with
zero, one, or two scalar members will be considered "simple enough" for
this code path.
It's worth noting that a more straightforward implementation would do this
on load, not on bind, and make use of the structure we already have for this:
CompoundVal. A long time ago, this was actually how RegionStore modeled
aggregate-to-aggregate copies, but today it's only used for compound literals.
Unfortunately, it seems that we've special-cased LazyCompoundVal in certain
places (such as liveness checks) but failed to similarly special-case
CompoundVal in all of them. Until we're confident that CompoundVal is
handled properly everywhere, this solution is safer, since the entire
optimization is just an implementation detail of RegionStore.
<rdar://problem/13599304>
llvm-svn: 179767
2013-04-19 00:33:46 +08:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
} IntPoint2D;
|
|
|
|
typedef struct {
|
|
|
|
IntPoint2D origin;
|
|
|
|
int size;
|
|
|
|
} IntCircle2D;
|
|
|
|
|
|
|
|
IntPoint2D makeIntPoint2D(int x, int y) {
|
|
|
|
IntPoint2D result;
|
|
|
|
result.x = x;
|
|
|
|
result.y = y;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void testSmallStructsCopiedPerField() {
|
|
|
|
IntPoint2D a;
|
|
|
|
a.x = 0;
|
|
|
|
|
|
|
|
IntPoint2D b = a;
|
|
|
|
extern void useInt(int);
|
|
|
|
useInt(b.x); // no-warning
|
|
|
|
useInt(b.y); // expected-warning{{uninitialized}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testLargeStructsNotCopiedPerField() {
|
|
|
|
IntPoint a;
|
|
|
|
a.x = 0;
|
|
|
|
|
|
|
|
IntPoint b = a;
|
|
|
|
extern void useInt(int);
|
|
|
|
useInt(b.x); // no-warning
|
|
|
|
useInt(b.y); // no-warning
|
|
|
|
}
|
|
|
|
|
|
|
|
void testSmallStructInLargerStruct() {
|
|
|
|
IntCircle2D *testObj = calloc(sizeof(IntCircle2D), 1);
|
|
|
|
|
|
|
|
clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}}
|
|
|
|
|
|
|
|
testObj->origin = makeIntPoint2D(1, 2);
|
|
|
|
if (testObj->size > 0) { ; } // warning occurs here
|
|
|
|
|
|
|
|
clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
|
|
|
|
|
|
|
|
free(testObj);
|
|
|
|
}
|
|
|
|
|
|
|
|
void testCopySmallStructIntoArgument(IntCircle2D *testObj) {
|
|
|
|
int oldSize = testObj->size;
|
|
|
|
clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
|
|
|
|
|
|
|
|
testObj->origin = makeIntPoint2D(1, 2);
|
|
|
|
clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testSmallStructBitfields() {
|
|
|
|
struct {
|
|
|
|
int x : 4;
|
|
|
|
int y : 4;
|
|
|
|
} a, b;
|
|
|
|
|
|
|
|
a.x = 1;
|
|
|
|
a.y = 2;
|
|
|
|
|
|
|
|
b = a;
|
|
|
|
clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testSmallStructBitfieldsFirstUndef() {
|
|
|
|
struct {
|
|
|
|
int x : 4;
|
|
|
|
int y : 4;
|
|
|
|
} a, b;
|
|
|
|
|
|
|
|
a.y = 2;
|
|
|
|
|
|
|
|
b = a;
|
|
|
|
clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testSmallStructBitfieldsSecondUndef() {
|
|
|
|
struct {
|
|
|
|
int x : 4;
|
|
|
|
int y : 4;
|
|
|
|
} a, b;
|
|
|
|
|
|
|
|
a.x = 1;
|
|
|
|
|
|
|
|
b = a;
|
|
|
|
clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testSmallStructBitfieldsFirstUnnamed() {
|
|
|
|
struct {
|
|
|
|
int : 4;
|
|
|
|
int y : 4;
|
|
|
|
} a, b, c;
|
|
|
|
|
|
|
|
a.y = 2;
|
|
|
|
|
|
|
|
b = a;
|
|
|
|
clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
|
|
|
|
|
|
|
|
b = c;
|
|
|
|
clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testSmallStructBitfieldsSecondUnnamed() {
|
|
|
|
struct {
|
|
|
|
int x : 4;
|
|
|
|
int : 4;
|
|
|
|
} a, b, c;
|
|
|
|
|
|
|
|
a.x = 1;
|
|
|
|
|
|
|
|
b = a;
|
|
|
|
clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
|
|
|
|
|
|
|
|
b = c;
|
|
|
|
clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}}
|
|
|
|
}
|
|
|
|
|