123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.CastToStruct -analyzer-store=region -analyzer-constraints=range -verify %s
- struct s {
- int data;
- int data_array[10];
- };
- typedef struct {
- int data;
- } STYPE;
- void g(char *p);
- void g1(struct s* p);
- // Array to pointer conversion. Array in the struct field.
- void f(void) {
- int a[10];
- int (*p)[10];
- p = &a;
- (*p)[3] = 1;
-
- struct s d;
- struct s *q;
- q = &d;
- q->data = 3;
- d.data_array[9] = 17;
- }
- // StringLiteral in lvalue context and pointer to array type.
- // p: ElementRegion, q: StringRegion
- void f2() {
- char *p = "/usr/local";
- char (*q)[4];
- q = &"abc";
- }
- // Typedef'ed struct definition.
- void f3() {
- STYPE s;
- }
- // Initialize array with InitExprList.
- void f4() {
- int a[] = { 1, 2, 3};
- int b[3] = { 1, 2 };
- struct s c[] = {{1,{1}}};
- }
- // Struct variable in lvalue context.
- // Assign UnknownVal to the whole struct.
- void f5() {
- struct s data;
- g1(&data);
- }
- // AllocaRegion test.
- void f6() {
- char *p;
- p = __builtin_alloca(10);
- g(p);
- char c = *p;
- p[1] = 'a';
- // Test if RegionStore::EvalBinOp converts the alloca region to element
- // region.
- p += 2;
- }
- struct s2;
- void g2(struct s2 *p);
- // Incomplete struct pointer used as function argument.
- void f7() {
- struct s2 *p = __builtin_alloca(10);
- g2(p);
- }
- // sizeof() is unsigned while -1 is signed in array index.
- void f8() {
- int a[10];
- a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning
- }
- // Initialization of struct array elements.
- void f9() {
- struct s a[10];
- }
- // Initializing array with string literal.
- void f10() {
- char a1[4] = "abc";
- char a3[6] = "abc";
- }
- // Retrieve the default value of element/field region.
- void f11() {
- struct s a;
- g1(&a);
- if (a.data == 0) // no-warning
- a.data = 1;
- }
- // Convert unsigned offset to signed when creating ElementRegion from
- // SymbolicRegion.
- void f12(int *list) {
- unsigned i = 0;
- list[i] = 1;
- }
- struct s1 {
- struct s2 {
- int d;
- } e;
- };
- // The binding of a.e.d should not be removed. Test recursive subregion map
- // building: a->e, e->d. Only then 'a' could be added to live region roots.
- void f13(double timeout) {
- struct s1 a;
- a.e.d = (int) timeout;
- if (a.e.d == 10)
- a.e.d = 4;
- }
- struct s3 {
- int a[2];
- };
- static struct s3 opt;
- // Test if the embedded array is retrieved correctly.
- void f14() {
- struct s3 my_opt = opt;
- }
- void bar(int*);
- struct s3 gets3() {
- struct s3 s;
- return s;
- }
- void accessArrayFieldNoCrash() {
- bar(gets3().a);
- bar((gets3().a));
- bar(((gets3().a)));
- }
- // Test if the array is correctly invalidated.
- void f15() {
- int a[10];
- bar(a);
- if (a[1]) // no-warning
- (void)1;
- }
- struct s3 p[1];
- // Code from postgresql.
- // Current cast logic of region store mistakenly leaves the final result region
- // an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and
- // assigns to 'a'.
- void f16(struct s3 *p) {
- struct s3 a = *((struct s3*) ((char*) &p[0])); // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}}
- }
- void inv(struct s1 *);
- // Invalidate the struct field.
- void f17() {
- struct s1 t;
- int x;
- inv(&t);
- if (t.e.d)
- x = 1;
- }
- void read(char*);
- void f18() {
- char *q;
- char *p = (char *) __builtin_alloca(10);
- read(p);
- q = p;
- q++;
- if (*q) { // no-warning
- }
- }
- // [PR13927] offsetof replacement macro flagged as "dereference of a null pointer"
- int offset_of_data_array(void)
- {
- return ((char *)&(((struct s*)0)->data_array)) - ((char *)0); // no-warning
- }
- int testPointerArithmeticOnVoid(void *bytes) {
- int p = 0;
- if (&bytes[0] == &bytes[1])
- return 6/p; // no-warning
- return 0;
- }
- int testRValueArraySubscriptExpr(void *bytes) {
- int *p = (int*)&bytes[0];
- *p = 0;
- if (*(int*)&bytes[0] == 0)
- return 0;
- return 5/(*p); // no-warning
- }
|