brintos

brintos / llvm-project-archived public Read only

0
0
Text · 33.0 KiB · b5f8aeb Raw
921 lines · c
1// Given code 'struct aa { char s1[4]; char * s2;} a; memcpy(a.s1, ...);',2// this test checks that the CStringChecker only invalidates the destination buffer array a.s1 (instead of a.s1 and a.s2).3// At the moment the whole of the destination array content is invalidated.4// If a.s1 region has a symbolic offset, the whole region of 'a' is invalidated.5// Specific triple set to test structures of size 0.6// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-disable-checker=core.FixedAddressDereference -Wno-error=int-conversion -verify -analyzer-config eagerly-assume=false %s7 8typedef __typeof(sizeof(int)) size_t;9 10char *strdup(const char *s);11void free(void *);12void *memcpy(void *dst, const void *src, size_t n); // expected-note{{passing argument to parameter 'dst' here}}13void *malloc(size_t n);14 15void clang_analyzer_eval(int);16 17struct aa {18    char s1[4];19    char *s2;20};21 22// Test different types of structure initialisation.23int f0(void) {24  struct aa a0 = {{1, 2, 3, 4}, 0};25  a0.s2 = strdup("hello");26  char input[] = {'a', 'b', 'c', 'd'};27  memcpy(a0.s1, input, 4);28  clang_analyzer_eval(a0.s1[0] == 'a'); // expected-warning{{UNKNOWN}}29  clang_analyzer_eval(a0.s1[1] == 'b'); // expected-warning{{UNKNOWN}}30  clang_analyzer_eval(a0.s1[2] == 'c'); // expected-warning{{UNKNOWN}}31  clang_analyzer_eval(a0.s1[3] == 'd'); // expected-warning{{UNKNOWN}}32  clang_analyzer_eval(a0.s2 == 0); // expected-warning{{UNKNOWN}}33  free(a0.s2); // no warning34  return 0;35}36 37int f1(void) {38  struct aa a1;39  a1.s2 = strdup("hello");40  char input[] = {'a', 'b', 'c', 'd'};41  memcpy(a1.s1, input, 4);42  clang_analyzer_eval(a1.s1[0] == 'a'); // expected-warning{{UNKNOWN}}43  clang_analyzer_eval(a1.s1[1] == 'b'); // expected-warning{{UNKNOWN}}44  clang_analyzer_eval(a1.s1[2] == 'c'); // expected-warning{{UNKNOWN}}45  clang_analyzer_eval(a1.s1[3] == 'd'); // expected-warning{{UNKNOWN}}46  clang_analyzer_eval(a1.s2 == 0); // expected-warning{{UNKNOWN}}47  free(a1.s2); // no warning48  return 0;49}50 51int f2(void) {52  struct aa a2 = {{1, 2}};53  a2.s2 = strdup("hello");54  char input[] = {'a', 'b', 'c', 'd'};55  memcpy(a2.s1, input, 4);56  clang_analyzer_eval(a2.s1[0] == 'a'); // expected-warning{{UNKNOWN}}57  clang_analyzer_eval(a2.s1[1] == 'b'); // expected-warning{{UNKNOWN}}58  clang_analyzer_eval(a2.s1[2] == 'c'); // expected-warning{{UNKNOWN}}59  clang_analyzer_eval(a2.s1[3] == 'd'); // expected-warning{{UNKNOWN}}60  clang_analyzer_eval(a2.s2 == 0); // expected-warning{{UNKNOWN}}61  free(a2.s2); // no warning62  return 0;63}64 65int f3(void) {66  struct aa a3 = {{1, 2, 3, 4}, 0};67  a3.s2 = strdup("hello");68  char input[] = {'a', 'b', 'c', 'd'};69  int * dest = (int*)a3.s1;70  memcpy(dest, input, 4);71  clang_analyzer_eval(a3.s1[0] == 'a'); // expected-warning{{UNKNOWN}}72  clang_analyzer_eval(dest[0] == 'a'); // expected-warning{{UNKNOWN}}73  clang_analyzer_eval(a3.s1[1] == 'b'); // expected-warning{{UNKNOWN}}74  clang_analyzer_eval(dest[1] == 'b'); // expected-warning{{UNKNOWN}}75  clang_analyzer_eval(a3.s1[2] == 'c'); // expected-warning{{UNKNOWN}}76  clang_analyzer_eval(dest[2] == 'c'); // expected-warning{{UNKNOWN}}77  clang_analyzer_eval(a3.s1[3] == 'd'); // expected-warning{{UNKNOWN}}78  clang_analyzer_eval(dest[3] == 'd'); // expected-warning{{UNKNOWN}}79  clang_analyzer_eval(a3.s2 == 0); // expected-warning{{UNKNOWN}}80  free(a3.s2); // no warning81  return 0;82}83 84struct bb {85  struct aa a;86  char * s2;87};88 89int f4(void) {90  struct bb b0 = {{1, 2, 3, 4}, 0};91  b0.s2 = strdup("hello");92  b0.a.s2 = strdup("hola");93  char input[] = {'a', 'b', 'c', 'd'};94  char * dest = (char*)(b0.a.s1);95  memcpy(dest, input, 4);96  clang_analyzer_eval(b0.a.s1[0] == 'a'); // expected-warning{{UNKNOWN}}97  clang_analyzer_eval(dest[0] == 'a'); // expected-warning{{UNKNOWN}}98  clang_analyzer_eval(b0.a.s1[1] == 'b'); // expected-warning{{UNKNOWN}}99  clang_analyzer_eval(dest[1] == 'b'); // expected-warning{{UNKNOWN}}100  clang_analyzer_eval(b0.a.s1[2] == 'c'); // expected-warning{{UNKNOWN}}101  clang_analyzer_eval(dest[2] == 'c'); // expected-warning{{UNKNOWN}}102  clang_analyzer_eval(b0.a.s1[3] == 'd'); // expected-warning{{UNKNOWN}}103  clang_analyzer_eval(dest[3] == 'd'); // expected-warning{{UNKNOWN}}104  clang_analyzer_eval(b0.s2 == 0); // expected-warning{{UNKNOWN}}105  free(b0.a.s2); // no warning106  free(b0.s2); // no warning107  return 0;108}109 110// Test that memory leaks are caught.111int f5(void) {112  struct aa a0 = {{1, 2, 3, 4}, 0};113  a0.s2 = strdup("hello");114  char input[] = {'a', 'b', 'c', 'd'};115  memcpy(a0.s1, input, 4);116  return 0; // expected-warning{{Potential leak of memory pointed to by 'a0.s2'}}117}118 119int f6(void) {120  struct aa a1;121  a1.s2 = strdup("hello");122  char input[] = {'a', 'b', 'c', 'd'};123  memcpy(a1.s1, input, 4);124  return 0; // expected-warning{{Potential leak of memory pointed to by 'a1.s2'}}125}126 127int f7(void) {128  struct aa a2 = {{1, 2}};129  a2.s2 = strdup("hello");130  char input[] = {'a', 'b', 'c', 'd'};131  memcpy(a2.s1, input, 4);132  return 0; // expected-warning{{Potential leak of memory pointed to by 'a2.s2'}}133}134 135int f8(void) {136  struct aa a3 = {{1, 2, 3, 4}, 0};137  a3.s2 = strdup("hello");138  char input[] = {'a', 'b', 'c', 'd'};139  int * dest = (int*)a3.s1;140  memcpy(dest, input, 4);141  return 0; // expected-warning{{Potential leak of memory pointed to by 'a3.s2'}}142}143 144int f9(void) {145  struct bb b0 = {{1, 2, 3, 4}, 0};146  b0.s2 = strdup("hello");147  b0.a.s2 = strdup("hola");148  char input[] = {'a', 'b', 'c', 'd'};149  char * dest = (char*)(b0.a.s1);150  memcpy(dest, input, 4);151  free(b0.a.s2); // expected-warning{{Potential leak of memory pointed to by 'b0.s2'}}152  return 0;153}154 155int f10(void) {156  struct bb b0 = {{1, 2, 3, 4}, 0};157  b0.s2 = strdup("hello");158  b0.a.s2 = strdup("hola");159  char input[] = {'a', 'b', 'c', 'd'};160  char * dest = (char*)(b0.a.s1);161  memcpy(dest, input, 4);162  free(b0.s2); // expected-warning{{Potential leak of memory pointed to by 'b0.a.s2'}}163  return 0;164}165 166// Test invalidating fields being addresses of array.167struct cc {168  char * s1;169  char * s2;170};171 172int f11(void) {173  char x[4] = {1, 2};174  x[0] = 1;175  x[1] = 2;176  struct cc c0;177  c0.s2 = strdup("hello");178  c0.s1 = &x[0];179  char input[] = {'a', 'b', 'c', 'd'};180  memcpy(c0.s1, input, 4);181  clang_analyzer_eval(x[0] == 1); // expected-warning{{UNKNOWN}}182  clang_analyzer_eval(x[1] == 2); // expected-warning{{UNKNOWN}}183  clang_analyzer_eval(c0.s1[0] == 'a'); // expected-warning{{UNKNOWN}}184  clang_analyzer_eval(c0.s1[1] == 'b'); // expected-warning{{UNKNOWN}}185  clang_analyzer_eval(c0.s1[2] == 'c'); // expected-warning{{UNKNOWN}}186  clang_analyzer_eval(c0.s1[3] == 'd'); // expected-warning{{UNKNOWN}}187  free(c0.s2); // no-warning188  return 0;189}190 191// Test inverting field position between s1 and s2.192struct dd {193  char *s2;194  char s1[4];195};196 197int f12(void) {198  struct dd d0 = {0, {1, 2, 3, 4}};199  d0.s2 = strdup("hello");200  char input[] = {'a', 'b', 'c', 'd'};201  memcpy(d0.s1, input, 4);202  clang_analyzer_eval(d0.s1[0] == 'a'); // expected-warning{{UNKNOWN}}203  clang_analyzer_eval(d0.s1[1] == 'b'); // expected-warning{{UNKNOWN}}204  clang_analyzer_eval(d0.s1[2] == 'c'); // expected-warning{{UNKNOWN}}205  clang_analyzer_eval(d0.s1[3] == 'd'); // expected-warning{{UNKNOWN}}206  clang_analyzer_eval(d0.s2 == 0); // expected-warning{{UNKNOWN}}207  free(d0.s2); // no warning208  return 0;209}210 211// Test arrays of structs.212struct ee {213  int a;214  char b;215};216 217struct EE {218  struct ee s1[2];219  char * s2;220};221 222int f13(void) {223  struct EE E0 = {{{1, 2}, {3, 4}}, 0};224  E0.s2 = strdup("hello");225  char input[] = {'a', 'b', 'c', 'd'};226  memcpy(E0.s1, input, 4);227  clang_analyzer_eval(E0.s1[0].a == 'a'); // expected-warning{{UNKNOWN}}228  clang_analyzer_eval(E0.s1[0].b == 'b'); // expected-warning{{UNKNOWN}}229  clang_analyzer_eval(E0.s1[1].a == 'c'); // expected-warning{{UNKNOWN}}230  clang_analyzer_eval(E0.s1[1].b == 'd'); // expected-warning{{UNKNOWN}}231  clang_analyzer_eval(E0.s2 == 0); // expected-warning{{UNKNOWN}}232  free(E0.s2); // no warning233  return 0;234}235 236// Test global parameters.237struct aa a15 = {{1, 2, 3, 4}, 0};238 239int f15(void) {240  a15.s2 = strdup("hello");241  char input[] = {'a', 'b', 'c', 'd'};242  memcpy(a15.s1, input, 4);243  clang_analyzer_eval(a15.s1[0] == 'a'); // expected-warning{{UNKNOWN}}244  clang_analyzer_eval(a15.s1[1] == 'b'); // expected-warning{{UNKNOWN}}245  clang_analyzer_eval(a15.s1[2] == 'c'); // expected-warning{{UNKNOWN}}246  clang_analyzer_eval(a15.s1[3] == 'd'); // expected-warning{{UNKNOWN}}247  clang_analyzer_eval(a15.s2 == 0); // expected-warning{{UNKNOWN}}248  free(a15.s2); // no warning249  return 0;250}251 252// Test array of 0 sized elements.253struct empty {};254struct gg {255  struct empty s1[4];256  char * s2;257};258 259int f16(void) {260  struct gg g0 = {{}, 0};261  g0.s2 = strdup("hello");262  char input[] = {'a', 'b', 'c', 'd'};263  memcpy(g0.s1, input, 4);264  clang_analyzer_eval(*(int*)(&g0.s1[0]) == 'a'); // expected-warning{{UNKNOWN}}\265  expected-warning{{Potential leak of memory pointed to by 'g0.s2'}}266  clang_analyzer_eval(*(int*)(&g0.s1[1]) == 'b'); // expected-warning{{UNKNOWN}}267  clang_analyzer_eval(*(int*)(&g0.s1[2]) == 'c'); // expected-warning{{UNKNOWN}}268  clang_analyzer_eval(*(int*)(&g0.s1[3]) == 'd'); // expected-warning{{UNKNOWN}}269  clang_analyzer_eval(g0.s2 == 0); // expected-warning{{UNKNOWN}}270  free(g0.s2); // no warning271  return 0;272}273 274// Test array of 0 elements.275struct hh {276  char s1[0];277  char * s2;278};279 280int f17(void) {281  struct hh h0;282  h0.s2 = strdup("hello");283  char input[] = {'a', 'b', 'c', 'd'};284  memcpy(h0.s1, input, 4);285  clang_analyzer_eval(h0.s1[0] == 'a'); // expected-warning{{UNKNOWN}}\286  expected-warning{{Potential leak of memory pointed to by 'h0.s2'}}287  clang_analyzer_eval(h0.s2 == 0); // expected-warning{{UNKNOWN}}288  free(h0.s2); // no warning289  return 0;290}291 292// Test writing past the array.293struct ii {294  char s1[4];295  int i;296  int j;297  char * s2;298};299 300int f18(void) {301  struct ii i18 = {{1, 2, 3, 4}, 5, 6};302  i18.i = 10;303  i18.j = 11;304  i18.s2 = strdup("hello");305  char input[100] = {3};306  memcpy(i18.s1, input, 100); // expected-warning {{'memcpy' will always overflow; destination buffer has size 24, but size argument is 100}}307  clang_analyzer_eval(i18.s1[0] == 1); // expected-warning{{UNKNOWN}}\308  expected-warning{{Potential leak of memory pointed to by 'i18.s2'}}309  clang_analyzer_eval(i18.s1[1] == 2); // expected-warning{{UNKNOWN}}310  clang_analyzer_eval(i18.s1[2] == 3); // expected-warning{{UNKNOWN}}311  clang_analyzer_eval(i18.s1[3] == 4); // expected-warning{{UNKNOWN}}312  clang_analyzer_eval(i18.i == 10); // expected-warning{{UNKNOWN}}313  clang_analyzer_eval(i18.j == 11); // expected-warning{{UNKNOWN}}314  return 0;315}316 317int f181(void) {318  struct ii i181 = {{1, 2, 3, 4}, 5, 6};319  i181.i = 10;320  i181.j = 11;321  i181.s2 = strdup("hello");322  char input[100] = {3};323  memcpy(i181.s1, input, 5); // invalidate the whole region of i181324  clang_analyzer_eval(i181.s1[0] == 1); // expected-warning{{UNKNOWN}}\325  expected-warning{{Potential leak of memory pointed to by 'i181.s2'}}326  clang_analyzer_eval(i181.s1[1] == 2); // expected-warning{{UNKNOWN}}327  clang_analyzer_eval(i181.s1[2] == 3); // expected-warning{{UNKNOWN}}328  clang_analyzer_eval(i181.s1[3] == 4); // expected-warning{{UNKNOWN}}329  clang_analyzer_eval(i181.i == 10); // expected-warning{{UNKNOWN}}330  clang_analyzer_eval(i181.j == 11); // expected-warning{{UNKNOWN}}331  return 0;332}333 334// Test array with a symbolic offset.335struct jj {336  char s1[2];337  char * s2;338};339 340struct JJ {341  struct jj s1[3];342  char * s2;343};344 345int f19(int i) {346  struct JJ J0 = {{{1, 2, 0}, {3, 4, 0}, {5, 6, 0}}, 0};347  J0.s2 = strdup("hello");348  J0.s1[0].s2 = strdup("hello");349  J0.s1[1].s2 = strdup("hi");350  J0.s1[2].s2 = strdup("world");351  char input[2] = {'a', 'b'};352  memcpy(J0.s1[i].s1, input, 2);353  clang_analyzer_eval(J0.s1[0].s1[0] == 1); // expected-warning{{UNKNOWN}}\354  expected-warning{{Potential leak of memory pointed to by field 's2'}}\355  expected-warning{{Potential leak of memory pointed to by field 's2'}}\356  expected-warning{{Potential leak of memory pointed to by field 's2'}}\357  expected-warning{{Potential leak of memory pointed to by 'J0.s2'}}358  clang_analyzer_eval(J0.s1[0].s1[1] == 2); // expected-warning{{UNKNOWN}}359  clang_analyzer_eval(J0.s1[1].s1[0] == 3); // expected-warning{{UNKNOWN}}360  clang_analyzer_eval(J0.s1[1].s1[1] == 4); // expected-warning{{UNKNOWN}}361  clang_analyzer_eval(J0.s1[2].s1[0] == 5); // expected-warning{{UNKNOWN}}362  clang_analyzer_eval(J0.s1[2].s1[1] == 6); // expected-warning{{UNKNOWN}}363  clang_analyzer_eval(J0.s1[i].s1[0] == 5); // expected-warning{{UNKNOWN}}364  clang_analyzer_eval(J0.s1[i].s1[1] == 6); // expected-warning{{UNKNOWN}}365  // FIXME: memory leak warning for J0.s2 should be emitted here instead of after memcpy call.366  return 0; // no warning367}368 369// Test array with its super region having symbolic offseted regions.370int f20(int i) {371  struct aa * a20 = malloc(sizeof(struct aa) * 2);372  a20[0].s1[0] = 1;373  a20[0].s1[1] = 2;374  a20[0].s1[2] = 3;375  a20[0].s1[3] = 4;376  a20[0].s2 = strdup("hello");377  a20[1].s1[0] = 5;378  a20[1].s1[1] = 6;379  a20[1].s1[2] = 7;380  a20[1].s1[3] = 8;381  a20[1].s2 = strdup("world");382  a20[i].s2 = strdup("hola");383  char input[] = {'a', 'b', 'c', 'd'};384  memcpy(a20[0].s1, input, 4);385  clang_analyzer_eval(a20[0].s1[0] == 1); // expected-warning{{UNKNOWN}}386  clang_analyzer_eval(a20[0].s1[1] == 1); // expected-warning{{UNKNOWN}}387  clang_analyzer_eval(a20[0].s1[2] == 1); // expected-warning{{UNKNOWN}}388  clang_analyzer_eval(a20[0].s1[3] == 1); // expected-warning{{UNKNOWN}}389  clang_analyzer_eval(a20[0].s2 == 0); // expected-warning{{UNKNOWN}}390  clang_analyzer_eval(a20[1].s1[0] == 1); // expected-warning{{UNKNOWN}}391  clang_analyzer_eval(a20[1].s1[1] == 1); // expected-warning{{UNKNOWN}}392  clang_analyzer_eval(a20[1].s1[2] == 1); // expected-warning{{UNKNOWN}}393  clang_analyzer_eval(a20[1].s1[3] == 1); // expected-warning{{UNKNOWN}}394  clang_analyzer_eval(a20[1].s2 == 0); // expected-warning{{UNKNOWN}}395  clang_analyzer_eval(a20[i].s1[0] == 1); // expected-warning{{UNKNOWN}}396  clang_analyzer_eval(a20[i].s1[1] == 1); // expected-warning{{UNKNOWN}}397  clang_analyzer_eval(a20[i].s1[2] == 1); // expected-warning{{UNKNOWN}}398  clang_analyzer_eval(a20[i].s1[3] == 1); // expected-warning{{UNKNOWN}}399  clang_analyzer_eval(a20[i].s2 == 0); // expected-warning{{UNKNOWN}}\400  expected-warning{{Potential leak of memory pointed to by 'a20'}}401 402  return 0;403}404 405// Test array's region and super region both having symbolic offsets.406int f21(int i) {407  struct aa * a21 = malloc(sizeof(struct aa) * 2);408  a21[0].s1[0] = 1;409  a21[0].s1[1] = 2;410  a21[0].s1[2] = 3;411  a21[0].s1[3] = 4;412  a21[0].s2 = 0;413  a21[1].s1[0] = 5;414  a21[1].s1[1] = 6;415  a21[1].s1[2] = 7;416  a21[1].s1[3] = 8;417  a21[1].s2 = 0;418  a21[i].s2 = strdup("hello");419  a21[i].s1[0] = 1;420  a21[i].s1[1] = 2;421  a21[i].s1[2] = 3;422  a21[i].s1[3] = 4;423  char input[] = {'a', 'b', 'c', 'd'};424  memcpy(a21[i].s1, input, 4);425  clang_analyzer_eval(a21[0].s1[0] == 1); // expected-warning{{UNKNOWN}}426  clang_analyzer_eval(a21[0].s1[1] == 1); // expected-warning{{UNKNOWN}}427  clang_analyzer_eval(a21[0].s1[2] == 1); // expected-warning{{UNKNOWN}}428  clang_analyzer_eval(a21[0].s1[3] == 1); // expected-warning{{UNKNOWN}}429  clang_analyzer_eval(a21[0].s2 == 0); // expected-warning{{UNKNOWN}}430  clang_analyzer_eval(a21[1].s1[0] == 1); // expected-warning{{UNKNOWN}}431  clang_analyzer_eval(a21[1].s1[1] == 1); // expected-warning{{UNKNOWN}}432  clang_analyzer_eval(a21[1].s1[2] == 1); // expected-warning{{UNKNOWN}}433  clang_analyzer_eval(a21[1].s1[3] == 1); // expected-warning{{UNKNOWN}}434  clang_analyzer_eval(a21[1].s2 == 0); // expected-warning{{UNKNOWN}}435  clang_analyzer_eval(a21[i].s1[0] == 1); // expected-warning{{UNKNOWN}}436  clang_analyzer_eval(a21[i].s1[1] == 1); // expected-warning{{UNKNOWN}}437  clang_analyzer_eval(a21[i].s1[2] == 1); // expected-warning{{UNKNOWN}}438  clang_analyzer_eval(a21[i].s1[3] == 1); // expected-warning{{UNKNOWN}}439  clang_analyzer_eval(a21[i].s2 == 0); // expected-warning{{UNKNOWN}}\440  expected-warning{{Potential leak of memory pointed to by 'a21'}}441 442  return 0;443}444 445// Test regions aliasing other regions.446struct ll {447  char s1[4];448  char * s2;449};450 451struct mm {452  char s3[4];453  char * s4;454};455 456int f24(void) {457  struct ll l24 = {{1, 2, 3, 4}, 0};458  struct mm * m24 = (struct mm *)&l24;459  m24->s4 = strdup("hello");460  char input[] = {1, 2, 3, 4};461  memcpy(m24->s3, input, 4);462  clang_analyzer_eval(m24->s3[0] == 1); // expected-warning{{UNKNOWN}}463  clang_analyzer_eval(m24->s3[1] == 1); // expected-warning{{UNKNOWN}}464  clang_analyzer_eval(m24->s3[2] == 1); // expected-warning{{UNKNOWN}}465  clang_analyzer_eval(m24->s3[3] == 1); // expected-warning{{UNKNOWN}}466  clang_analyzer_eval(l24.s1[0] == 1); // expected-warning{{UNKNOWN}}467  clang_analyzer_eval(l24.s1[1] == 1); // expected-warning{{UNKNOWN}}468  clang_analyzer_eval(l24.s1[2] == 1); // expected-warning{{UNKNOWN}}469  clang_analyzer_eval(l24.s1[3] == 1); // expected-warning{{UNKNOWN}}\470  expected-warning{{Potential leak of memory pointed to by field 's4'}}471  return 0;472}473 474// Test region with potential aliasing and symbolic offsets.475// Store assumes no aliasing.476int f25(int i, int j, struct ll * l, struct mm * m) {477  m->s4 = strdup("hola"); // m->s4 not tracked478  m->s3[0] = 1;479  m->s3[1] = 2;480  m->s3[2] = 3;481  m->s3[3] = 4;482  m->s3[j] = 5; // invalidates m->s3483  l->s2 = strdup("hello"); // l->s2 not tracked484  l->s1[0] = 6;485  l->s1[1] = 7;486  l->s1[2] = 8;487  l->s1[3] = 9;488  l->s1[i] = 10; // invalidates l->s1489  char input[] = {1, 2, 3, 4};490  memcpy(m->s3, input, 4); // does not invalidate l->s1[i]491  clang_analyzer_eval(m->s3[0] == 1); // expected-warning{{UNKNOWN}}492  clang_analyzer_eval(m->s3[1] == 1); // expected-warning{{UNKNOWN}}493  clang_analyzer_eval(m->s3[2] == 1); // expected-warning{{UNKNOWN}}494  clang_analyzer_eval(m->s3[3] == 1); // expected-warning{{UNKNOWN}}495  clang_analyzer_eval(m->s3[i] == 1); // expected-warning{{UNKNOWN}}496  clang_analyzer_eval(m->s3[j] == 1); // expected-warning{{UNKNOWN}}497  clang_analyzer_eval(l->s1[0] == 1); // expected-warning{{UNKNOWN}}498  clang_analyzer_eval(l->s1[1] == 1); // expected-warning{{UNKNOWN}}499  clang_analyzer_eval(l->s1[2] == 1); // expected-warning{{UNKNOWN}}500  clang_analyzer_eval(l->s1[3] == 1); // expected-warning{{UNKNOWN}}501  clang_analyzer_eval(l->s1[i] == 1); // expected-warning{{FALSE}}502  clang_analyzer_eval(l->s1[j] == 1); // expected-warning{{UNKNOWN}}503  return 0;504}505 506// Test size with symbolic size argument.507int f26(int i) {508  struct aa a26 = {{1, 2, 3, 4}, 0};509  a26.s2 = strdup("hello");510  char input[] = {'a', 'b', 'c', 'd'};511  memcpy(a26.s1, input, i); // i assumed in bound512  clang_analyzer_eval(a26.s1[0] == 1); // expected-warning{{UNKNOWN}}513  clang_analyzer_eval(a26.s1[1] == 1); // expected-warning{{UNKNOWN}}514  clang_analyzer_eval(a26.s1[2] == 1); // expected-warning{{UNKNOWN}}515  clang_analyzer_eval(a26.s1[3] == 1); // expected-warning{{UNKNOWN}}\516  expected-warning{{Potential leak of memory pointed to by 'a26.s2'}}517  return 0;518}519 520// Test sizeof as a size argument.521int f261(void) {522  struct aa a261 = {{1, 2, 3, 4}, 0};523  a261.s2 = strdup("hello");524  char input[] = {'a', 'b', 'c', 'd'};525  memcpy(a261.s1, input, sizeof(a261.s1));526  clang_analyzer_eval(a261.s1[0] == 1); // expected-warning{{UNKNOWN}}527  clang_analyzer_eval(a261.s1[1] == 1); // expected-warning{{UNKNOWN}}528  clang_analyzer_eval(a261.s1[2] == 1); // expected-warning{{UNKNOWN}}529  clang_analyzer_eval(a261.s1[3] == 1); // expected-warning{{UNKNOWN}}\530  expected-warning{{Potential leak of memory pointed to by 'a261.s2'}}531  return 0;532}533 534// Test negative size argument.535int f262(void) {536  struct aa a262 = {{1, 2, 3, 4}, 0};537  a262.s2 = strdup("hello");538  char input[] = {'a', 'b', 'c', 'd'};539  memcpy(a262.s1, input, -1); // expected-warning{{'memcpy' will always overflow; destination buffer has size 16, but size argument is 18446744073709551615}}540  clang_analyzer_eval(a262.s1[0] == 1); // expected-warning{{UNKNOWN}}\541  expected-warning{{Potential leak of memory pointed to by 'a262.s2'}}542  clang_analyzer_eval(a262.s1[1] == 1); // expected-warning{{UNKNOWN}}543  clang_analyzer_eval(a262.s1[2] == 1); // expected-warning{{UNKNOWN}}544  clang_analyzer_eval(a262.s1[3] == 1); // expected-warning{{UNKNOWN}}545  return 0;546}547 548// Test size argument being an unknown value.549struct xx {550  char s1[4];551  char * s2;552};553 554int f263(int n, char * len) {555  struct xx x263 = {0};556  x263.s2 = strdup("hello");557  char input[] = {'a', 'b', 'c', 'd'};558  memcpy(x263.s1, input, *(len + n));559  clang_analyzer_eval(x263.s1[0] == 0); // expected-warning{{UNKNOWN}}\560  expected-warning{{Potential leak of memory pointed to by 'x263.s2'}}561  clang_analyzer_eval(x263.s1[1] == 0); // expected-warning{{UNKNOWN}}562  clang_analyzer_eval(x263.s1[2] == 0); // expected-warning{{UNKNOWN}}563  clang_analyzer_eval(x263.s1[3] == 0); // expected-warning{{UNKNOWN}}564  clang_analyzer_eval(x263.s2 == 0); // expected-warning{{UNKNOWN}}565  return 0;566}567 568 569// Test casting regions with symbolic offseted sub regions.570int f27(int i) {571  struct mm m27 = {{1, 2, 3, 4}, 0};572  m27.s4 = strdup("hello");573  m27.s3[i] = 5;574  char input[] = {'a', 'b', 'c', 'd'};575  memcpy(((struct ll*)(&m27))->s1, input, 4);576  clang_analyzer_eval(m27.s3[0] == 1); // expected-warning{{UNKNOWN}}577  clang_analyzer_eval(m27.s3[1] == 1); // expected-warning{{UNKNOWN}}578  clang_analyzer_eval(m27.s3[2] == 1); // expected-warning{{UNKNOWN}}579  clang_analyzer_eval(m27.s3[3] == 1); // expected-warning{{UNKNOWN}}580  clang_analyzer_eval(m27.s3[i] == 1); // expected-warning{{UNKNOWN}}\581  expected-warning{{Potential leak of memory pointed to by 'm27.s4'}}582  return 0;583}584 585int f28(int i, int j, int k, int l) {586  struct mm m28[2];587  m28[i].s4 = strdup("hello");588  m28[j].s3[k] = 1;589  struct ll * l28 = (struct ll*)(&m28[1]);590  l28->s1[l] = 2;591  char input[] = {'a', 'b', 'c', 'd'}; // expected-warning{{Potential leak of memory pointed to by field 's4'}}592  memcpy(l28->s1, input, 4);593  clang_analyzer_eval(m28[0].s3[0] == 1); // expected-warning{{UNKNOWN}}594  clang_analyzer_eval(m28[0].s3[1] == 1); // expected-warning{{UNKNOWN}}595  clang_analyzer_eval(m28[0].s3[2] == 1); // expected-warning{{UNKNOWN}}596  clang_analyzer_eval(m28[0].s3[3] == 1); // expected-warning{{UNKNOWN}}597  clang_analyzer_eval(m28[1].s3[0] == 1); // expected-warning{{UNKNOWN}}598  clang_analyzer_eval(m28[1].s3[1] == 1); // expected-warning{{UNKNOWN}}599  clang_analyzer_eval(m28[1].s3[2] == 1); // expected-warning{{UNKNOWN}}600  clang_analyzer_eval(m28[1].s3[3] == 1); // expected-warning{{UNKNOWN}}601  clang_analyzer_eval(m28[i].s3[0] == 1); // expected-warning{{UNKNOWN}}602  clang_analyzer_eval(m28[i].s3[1] == 1); // expected-warning{{UNKNOWN}}603  clang_analyzer_eval(m28[i].s3[2] == 1); // expected-warning{{UNKNOWN}}604  clang_analyzer_eval(m28[i].s3[3] == 1); // expected-warning{{UNKNOWN}}605  clang_analyzer_eval(m28[j].s3[k] == 1); // expected-warning{{UNKNOWN}}606  clang_analyzer_eval(l28->s1[l] == 2); // expected-warning{{UNKNOWN}}607  return 0;608}609 610int f29(int i, int j, int k, int l, int m) {611  struct mm m29[2];612  m29[i].s4 = strdup("hello");613  m29[j].s3[k] = 1;614  struct ll * l29 = (struct ll*)(&m29[l]);615  l29->s1[m] = 2;616  char input[] = {'a', 'b', 'c', 'd'};617  memcpy(l29->s1, input, 4);618  clang_analyzer_eval(m29[0].s3[0] == 1); // expected-warning{{UNKNOWN}}619  clang_analyzer_eval(m29[0].s3[1] == 1); // expected-warning{{UNKNOWN}}620  clang_analyzer_eval(m29[0].s3[2] == 1); // expected-warning{{UNKNOWN}}621  clang_analyzer_eval(m29[0].s3[3] == 1); // expected-warning{{UNKNOWN}}622  clang_analyzer_eval(m29[1].s3[0] == 1); // expected-warning{{UNKNOWN}}623  clang_analyzer_eval(m29[1].s3[1] == 1); // expected-warning{{UNKNOWN}}624  clang_analyzer_eval(m29[1].s3[2] == 1); // expected-warning{{UNKNOWN}}625  clang_analyzer_eval(m29[1].s3[3] == 1); // expected-warning{{UNKNOWN}}626  clang_analyzer_eval(m29[i].s3[0] == 1); // expected-warning{{UNKNOWN}}627  clang_analyzer_eval(m29[i].s3[1] == 1); // expected-warning{{UNKNOWN}}628  clang_analyzer_eval(m29[i].s3[2] == 1); // expected-warning{{UNKNOWN}}629  clang_analyzer_eval(m29[i].s3[3] == 1); // expected-warning{{UNKNOWN}}630  clang_analyzer_eval(m29[j].s3[k] == 1); // expected-warning{{TRUE}}631  clang_analyzer_eval(l29->s1[m] == 2); // expected-warning{{UNKNOWN}}632  // FIXME: Should warn that m29[i].s4 leaks. But not on the previous line,633  // because l29 and m29 alias.634  return 0;635}636 637// Test unions' fields.638union uu {639  char x;640  char s1[4];641};642 643int f30(void) {644  union uu u30 = { .s1 = {1, 2, 3, 4}};645  char input[] = {1, 2, 3, 4};646  memcpy(u30.s1, input, 4);647  clang_analyzer_eval(u30.s1[0] == 1); // expected-warning{{UNKNOWN}}648  clang_analyzer_eval(u30.s1[1] == 1); // expected-warning{{UNKNOWN}}649  clang_analyzer_eval(u30.s1[2] == 1); // expected-warning{{UNKNOWN}}650  clang_analyzer_eval(u30.s1[3] == 1); // expected-warning{{UNKNOWN}}651  clang_analyzer_eval(u30.x == 1); // expected-warning{{UNKNOWN}}652  return 0;653}654 655struct kk {656  union uu u;657  char * s2;658};659 660int f31(void) {661  struct kk k31;662  k31.s2 = strdup("hello");663  k31.u.x = 1;664  char input[] = {'a', 'b', 'c', 'd'};665  memcpy(k31.u.s1, input, 4);666  clang_analyzer_eval(k31.u.s1[0] == 1); // expected-warning{{UNKNOWN}}\667  expected-warning{{Potential leak of memory pointed to by 'k31.s2'}}668  clang_analyzer_eval(k31.u.s1[1] == 1); // expected-warning{{UNKNOWN}}669  clang_analyzer_eval(k31.u.s1[2] == 1); // expected-warning{{UNKNOWN}}670  clang_analyzer_eval(k31.u.s1[3] == 1); // expected-warning{{UNKNOWN}}671  clang_analyzer_eval(k31.u.x == 1); // expected-warning{{UNKNOWN}}672  // FIXME: memory leak warning for k31.s2 should be emitted here.673  return 0;674}675 676union vv {677  int x;678  char * s2;679};680 681int f32(void) {682  union vv v32;683  v32.s2 = strdup("hello");684  char input[] = {'a', 'b', 'c', 'd'};685  memcpy(v32.s2, input, 4);686  clang_analyzer_eval(v32.s2[0] == 1); // expected-warning{{UNKNOWN}}687  clang_analyzer_eval(v32.s2[1] == 1); // expected-warning{{UNKNOWN}}688  clang_analyzer_eval(v32.s2[2] == 1); // expected-warning{{UNKNOWN}}689  clang_analyzer_eval(v32.s2[3] == 1); // expected-warning{{UNKNOWN}}\690  expected-warning{{Potential leak of memory pointed to by 'v32.s2'}}691  return 0;692}693 694struct nn {695  int s1;696  int i;697  int j;698  int k;699  char * s2;700};701 702// Test bad types to dest buffer.703int f33(void) {704  struct nn n33 = {1, 2, 3, 4, 0};705  n33.s2 = strdup("hello");706  char input[] = {'a', 'b', 'c', 'd'};707  memcpy(n33.s1, input, 4); // expected-warning{{incompatible integer to pointer conversion passing 'int' to parameter of type 'void *'}}708  clang_analyzer_eval(n33.i == 2); // expected-warning{{TRUE}}709  clang_analyzer_eval(n33.j == 3); // expected-warning{{TRUE}}710  clang_analyzer_eval(n33.k == 4); // expected-warning{{TRUE}}711  clang_analyzer_eval(((char*)(n33.s1))[0] == 1); // expected-warning{{UNKNOWN}}\712  expected-warning{{cast to 'char *' from smaller integer type 'int'}}713  clang_analyzer_eval(((char*)(n33.s1))[1] == 1); // expected-warning{{UNKNOWN}}\714  expected-warning{{cast to 'char *' from smaller integer type 'int'}}715  clang_analyzer_eval(((char*)(n33.s1))[2] == 1); // expected-warning{{UNKNOWN}}\716  expected-warning{{cast to 'char *' from smaller integer type 'int'}}717  clang_analyzer_eval(((char*)(n33.s1))[3] == 1); // expected-warning{{UNKNOWN}}\718  expected-warning{{cast to 'char *' from smaller integer type 'int'}}719  clang_analyzer_eval(n33.s2 == 0); //expected-warning{{UNKNOWN}}720  return 0; // expected-warning{{Potential leak of memory pointed to by 'n33.s2'}}721}722 723// Test destination buffer being an unknown value.724struct ww {725  int s1[4];726  char s2;727};728 729int f34(struct ww * w34, int n) {730  w34->s2 = 3;731  char input[] = {'a', 'b', 'c', 'd'};732  memcpy(w34->s1 + n, input , 4);733  clang_analyzer_eval(w34->s1[0] == 0); // expected-warning{{UNKNOWN}}734  clang_analyzer_eval(w34->s1[1] == 0); // expected-warning{{UNKNOWN}}735  clang_analyzer_eval(w34->s1[2] == 0); // expected-warning{{UNKNOWN}}736  clang_analyzer_eval(w34->s1[3] == 0); // expected-warning{{UNKNOWN}}737  clang_analyzer_eval(w34->s1[n] == 0); // expected-warning{{UNKNOWN}}738  clang_analyzer_eval(w34->s2 == 3); // expected-warning{{TRUE}}739  return 0;740}741 742// Test dest buffer as an element region with a symbolic index and size parameter as a symbolic value.743struct yy {744  char s1[4];745  char * s2;746};747 748int f35(int i, int n) {749  struct yy y35 = {{1, 2, 3, 4}, 0};750  y35.s2 = strdup("hello");751  char input[] = {'a', 'b', 'c', 'd'};752  memcpy(&(y35.s1[i]), input, n);753  clang_analyzer_eval(y35.s1[0] == 0); // expected-warning{{UNKNOWN}}754  clang_analyzer_eval(y35.s1[1] == 0); // expected-warning{{UNKNOWN}}755  clang_analyzer_eval(y35.s1[2] == 0); // expected-warning{{UNKNOWN}}756  clang_analyzer_eval(y35.s1[3] == 0); // expected-warning{{UNKNOWN}}757  clang_analyzer_eval(y35.s1[i] == 0); // expected-warning{{UNKNOWN}}758  clang_analyzer_eval(y35.s2 == 0); // expected-warning{{UNKNOWN}}759  return 0; // expected-warning{{Potential leak of memory pointed to by 'y35.s2'}}760}761 762// Test regions with negative offsets.763struct zz {764  char s1[4];765  int s2;766};767 768int f36(struct zz * z36) {769 770  char input[] = {'a', 'b', 'c', 'd'};771  z36->s1[0] = 0;772  z36->s1[1] = 1;773  z36->s1[2] = 2;774  z36->s1[3] = 3;775  z36->s2 = 10;776 777  z36 = z36 - 1; // Decrement by 8 bytes (struct zz is 8 bytes).778 779  z36->s1[0] = 4;780  z36->s1[1] = 5;781  z36->s1[2] = 6;782  z36->s1[3] = 7;783  z36->s2 = 11;784 785  memcpy(z36->s1, input, 4);786 787  clang_analyzer_eval(z36->s1[0] == 1); // expected-warning{{UNKNOWN}}788  clang_analyzer_eval(z36->s1[1] == 1); // expected-warning{{UNKNOWN}}789  clang_analyzer_eval(z36->s1[2] == 1); // expected-warning{{UNKNOWN}}790  clang_analyzer_eval(z36->s1[3] == 1); // expected-warning{{UNKNOWN}}791  clang_analyzer_eval(z36->s2 == 11); // expected-warning{{TRUE}}792 793  z36 = z36 + 1; // Increment back.794 795  clang_analyzer_eval(z36->s1[0] == 0); // expected-warning{{TRUE}}796  clang_analyzer_eval(z36->s1[1] == 1); // expected-warning{{TRUE}}797  clang_analyzer_eval(z36->s1[2] == 2); // expected-warning{{TRUE}}798  clang_analyzer_eval(z36->s1[3] == 3); // expected-warning{{TRUE}}799  clang_analyzer_eval(z36->s2 == 10); // expected-warning{{TRUE}}800 801  return 0;802}803 804int f37(struct zz * z37) {805 806  char input[] = {'a', 'b', 'c', 'd'};807  z37->s1[0] = 0;808  z37->s1[1] = 1;809  z37->s1[2] = 2;810  z37->s1[3] = 3;811  z37->s2 = 10;812 813  z37 = (struct zz *)((char*)(z37) - 4); // Decrement by 4 bytes (struct zz is 8 bytes).814 815  z37->s1[0] = 4;816  z37->s1[1] = 5;817  z37->s1[2] = 6;818  z37->s1[3] = 7;819  z37->s2 = 11;820 821  memcpy(z37->s1, input, 4);822 823  clang_analyzer_eval(z37->s1[0] == 1); // expected-warning{{UNKNOWN}}824  clang_analyzer_eval(z37->s1[1] == 1); // expected-warning{{UNKNOWN}}825  clang_analyzer_eval(z37->s1[2] == 1); // expected-warning{{UNKNOWN}}826  clang_analyzer_eval(z37->s1[3] == 1); // expected-warning{{UNKNOWN}}827  clang_analyzer_eval(z37->s2 == 11); // expected-warning{{TRUE}}828 829  z37 = (struct zz *)((char*)(z37) + 4); // Increment back.830 831  clang_analyzer_eval(z37->s1[0] == 11); // expected-warning{{TRUE}}832  clang_analyzer_eval(z37->s1[1] == 1); // expected-warning{{UNKNOWN}}833  clang_analyzer_eval(z37->s1[2] == 1); // expected-warning{{UNKNOWN}}834  clang_analyzer_eval(z37->s1[3] == 1); // expected-warning{{UNKNOWN}}835  clang_analyzer_eval(z37->s2 == 10); // expected-warning{{TRUE}}836 837  return 0;838}839 840int f38(struct zz * z38) {841 842  char input[] = {'a', 'b', 'c', 'd'};843  z38->s1[0] = 0;844  z38->s1[1] = 1;845  z38->s1[2] = 2;846  z38->s1[3] = 3;847  z38->s2 = 10;848 849  z38 = (struct zz *)((char*)(z38) - 2); // Decrement by 2 bytes (struct zz is 8 bytes).850 851  z38->s1[0] = 4;852  z38->s1[1] = 5;853  z38->s1[2] = 6;854  z38->s1[3] = 7;855  z38->s2 = 11;856 857  memcpy(z38->s1, input, 4);858 859  clang_analyzer_eval(z38->s1[0] == 1); // expected-warning{{UNKNOWN}}860  clang_analyzer_eval(z38->s1[1] == 1); // expected-warning{{UNKNOWN}}861  clang_analyzer_eval(z38->s1[2] == 1); // expected-warning{{UNKNOWN}}862  clang_analyzer_eval(z38->s1[3] == 1); // expected-warning{{UNKNOWN}}863  clang_analyzer_eval(z38->s2 == 11); // expected-warning{{TRUE}}864 865  z38 = (struct zz *)((char*)(z38) + 2); // Increment back.866 867  clang_analyzer_eval(z38->s1[0] == 1); // expected-warning{{UNKNOWN}}868  clang_analyzer_eval(z38->s1[1] == 1); // expected-warning{{UNKNOWN}}869  clang_analyzer_eval(z38->s1[2] == 11); // expected-warning{{TRUE}}870  clang_analyzer_eval(z38->s1[3] == 1); // expected-warning{{UNKNOWN}}871  clang_analyzer_eval(z38->s2 == 10); // expected-warning{{UNKNOWN}}872 873  return 0;874}875 876// Test negative offsets with a different structure layout.877struct z0 {878  int s2;879  char s1[4];880};881 882int f39(struct z0 * d39) {883 884  char input[] = {'a', 'b', 'c', 'd'};885  d39->s1[0] = 0;886  d39->s1[1] = 1;887  d39->s1[2] = 2;888  d39->s1[3] = 3;889  d39->s2 = 10;890 891  d39 = (struct z0 *)((char*)(d39) - 2); // Decrement by 2 bytes (struct z0 is 8 bytes).892 893  d39->s1[0] = 4;894  d39->s1[1] = 5;895  d39->s1[2] = 6;896  d39->s1[3] = 7;897  d39->s2 = 11;898 899  memcpy(d39->s1, input, 4);900 901  clang_analyzer_eval(d39->s1[0] == 1); // expected-warning{{UNKNOWN}}902  clang_analyzer_eval(d39->s1[1] == 1); // expected-warning{{UNKNOWN}}903  clang_analyzer_eval(d39->s1[2] == 1); // expected-warning{{UNKNOWN}}904  clang_analyzer_eval(d39->s1[3] == 1); // expected-warning{{UNKNOWN}}905  clang_analyzer_eval(d39->s2 == 11); // expected-warning{{TRUE}}906 907  d39 = (struct z0 *)((char*)(d39) + 2); // Increment back.908 909  clang_analyzer_eval(d39->s1[0] == 1); // expected-warning{{UNKNOWN}}910  clang_analyzer_eval(d39->s1[1] == 1); // expected-warning{{UNKNOWN}}911  clang_analyzer_eval(d39->s1[2] == 2); // expected-warning{{TRUE}}912  clang_analyzer_eval(d39->s1[3] == 3); // expected-warning{{TRUE}}913  // FIXME: d39->s2 should evaluate to at least UNKNOWN or FALSE,914  // 'collectSubRegionBindings(...)' in RegionStore.cpp will need to915  // handle a regions' upper boundary overflowing.916  clang_analyzer_eval(d39->s2 == 10); // expected-warning{{TRUE}}917 918  return 0;919}920 921