brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · f0eba86 Raw
213 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.CastToStruct -verify %s2 3struct s {4  int data;5  int data_array[10];6};7 8typedef struct {9  int data;10} STYPE;11 12void g(char *p);13void g1(struct s* p);14 15// Array to pointer conversion. Array in the struct field.16void f(void) {17  int a[10];18  int (*p)[10];19  p = &a;20  (*p)[3] = 1;21  22  struct s d;23  struct s *q;24  q = &d;25  q->data = 3;26  d.data_array[9] = 17;27}28 29// StringLiteral in lvalue context and pointer to array type.30// p: ElementRegion, q: StringRegion31void f2(void) {32  char *p = "/usr/local";33  char (*q)[4];34  q = &"abc";35}36 37// Typedef'ed struct definition.38void f3(void) {39  STYPE s;40}41 42// Initialize array with InitExprList.43void f4(void) {44  int a[] = { 1, 2, 3};45  int b[3] = { 1, 2 };46  struct s c[] = {{1,{1}}};47}48 49// Struct variable in lvalue context.50// Assign UnknownVal to the whole struct.51void f5(void) {52  struct s data;53  g1(&data);54}55 56// AllocaRegion test.57void f6(void) {58  char *p;59  p = __builtin_alloca(10); 60  g(p);61  char c = *p;62  p[1] = 'a';63  // Test if RegionStore::EvalBinOp converts the alloca region to element64  // region.65  p += 2;66}67 68struct s2;69 70void g2(struct s2 *p);71 72// Incomplete struct pointer used as function argument.73void f7(void) {74  struct s2 *p = __builtin_alloca(10);75  g2(p);76}77 78// sizeof() is unsigned while -1 is signed in array index.79void f8(void) {80  int a[10];81  a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning82}83 84// Initialization of struct array elements.85void f9(void) {86  struct s a[10];87}88 89// Initializing array with string literal.90void f10(void) {91  char a1[4] = "abc";92  char a3[6] = "abc";93}94 95// Retrieve the default value of element/field region.96void f11(void) {97  struct s a;98  g1(&a);99  if (a.data == 0) // no-warning100    a.data = 1;101}102 103// Convert unsigned offset to signed when creating ElementRegion from 104// SymbolicRegion.105void f12(int *list) {106  unsigned i = 0;107  list[i] = 1;108}109 110struct s1 {111  struct s2 {112    int d;113  } e;114};115 116// The binding of a.e.d should not be removed. Test recursive subregion map117// building: a->e, e->d. Only then 'a' could be added to live region roots.118void f13(double timeout) {119  struct s1 a;120  a.e.d = (int) timeout;121  if (a.e.d == 10)122    a.e.d = 4;123}124 125struct s3 {126  int a[2];127};128 129static struct s3 opt;130 131// Test if the embedded array is retrieved correctly.132void f14(void) {133  struct s3 my_opt = opt;134}135 136void bar(int*);137 138struct s3 gets3(void) {139  struct s3 s;140  return s;141}142 143void accessArrayFieldNoCrash(void) {144  bar(gets3().a);145  bar((gets3().a));146  bar(((gets3().a)));  147}148 149// Test if the array is correctly invalidated.150void f15(void) {151  int a[10];152  bar(a);153  if (a[1]) // no-warning154    (void)1;155}156 157struct s3 p[1];158 159// Code from postgresql.160// Current cast logic of region store mistakenly leaves the final result region161// an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and162// assigns to 'a'. 163void f16(struct s3 *p) {164  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}}165}166 167void inv(struct s1 *);168 169// Invalidate the struct field.170void f17(void) {171  struct s1 t;172  int x;173  inv(&t);174  if (t.e.d)175    x = 1;176}177 178void read(char*);179 180void f18(void) {181  char *q;182  char *p = (char *) __builtin_alloca(10);183  read(p);184  q = p;185  q++;186  if (*q) { // no-warning187  }188}189 190 191// [PR13927] offsetof replacement macro flagged as "dereference of a null pointer"192int offset_of_data_array(void)193{194  return ((char *)&(((struct s*)0)->data_array)) - ((char *)0); // no-warning195}196 197int testPointerArithmeticOnVoid(void *bytes) {198  int p = 0;199  if (&bytes[0] == &bytes[1])200    return 6/p; // no-warning201  return 0;202}203 204int testRValueArraySubscriptExpr(void *bytes) {205  int *p = (int*)&bytes[0];206  *p = 0;207  if (*(int*)&bytes[0] == 0)208    return 0;209  return 5/(*p); // no-warning210}211 212 213