brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.1 KiB · eef2600 Raw
434 lines · plain
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-output=text -verify %s2 3typedef unsigned int NSUInteger;4typedef __typeof__(sizeof(int)) size_t;5 6void *malloc(size_t);7void *calloc(size_t nmemb, size_t size);8void free(void *);9 10void clang_analyzer_eval(int);11 12struct s {13  int data;14};15 16struct s global;17 18void g(int);19 20void f4(void) {21  int a;22  if (global.data == 0)23    a = 3;24  if (global.data == 0) // When the true branch is feasible 'a = 3'.25    g(a); // no-warning26}27 28 29// Test uninitialized value due to part of the structure being uninitialized.30struct TestUninit { int x; int y; };31struct TestUninit test_uninit_aux(void);32void test_unit_aux2(int);33void test_uninit_pos(void) {34  struct TestUninit v1 = { 0, 0 };35  struct TestUninit v2 = test_uninit_aux();36  int z; // expected-note{{'z' declared without an initial value}}37  v1.y = z; // expected-warning{{Assigned value is uninitialized}}38            // expected-note@-1{{Assigned value is uninitialized}}39  test_unit_aux2(v2.x + v1.y);40}41void test_uninit_pos_2(void) {42  struct TestUninit v1 = { 0, 0 };43  struct TestUninit v2;44  test_unit_aux2(v2.x + v1.y);  // expected-warning{{The left operand of '+' is a garbage value}}45                                // expected-note@-1{{The left operand of '+' is a garbage value}}46}47void test_uninit_pos_3(void) {48  struct TestUninit v1 = { 0, 0 };49  struct TestUninit v2;50  test_unit_aux2(v1.y + v2.x);  // expected-warning{{The right operand of '+' is a garbage value}}51                                // expected-note@-1{{The right operand of '+' is a garbage value}}52}53 54void test_uninit_neg(void) {55  struct TestUninit v1 = { 0, 0 };56  struct TestUninit v2 = test_uninit_aux();57  test_unit_aux2(v2.x + v1.y);58}59 60extern void test_uninit_struct_arg_aux(struct TestUninit arg);61void test_uninit_struct_arg(void) {62  struct TestUninit x; // expected-note{{'x' initialized here}}63  test_uninit_struct_arg_aux(x); // expected-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}64                                 // expected-note@-1{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}65}66 67@interface Foo68- (void) passVal:(struct TestUninit)arg;69@end70void testFoo(Foo *o) {71  struct TestUninit x; // expected-note{{'x' initialized here}}72  [o passVal:x]; // expected-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}73                 // expected-note@-1{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}74}75 76// Test case shows an uninitialized value being used in the LHS of a compound77// assignment.78void rdar_7780304(void) {79  typedef struct s_r7780304 { int x; } s_r7780304;80  s_r7780304 b;81  b.x |= 1; // expected-warning{{The left expression of the compound assignment uses uninitialized memory}}82            // expected-note@-1{{The left expression of the compound assignment uses uninitialized memory}}83}84 85 86// The flip side of PR10163 -- float arrays that are actually uninitialized87void test_PR10163(float);88void PR10163 (void) {89  float x[2];90  test_PR10163(x[1]); // expected-warning{{uninitialized value}}91                      // expected-note@-1{{1st function call argument is an uninitialized value}}92}93 94// PR10163 -- don't warn for default-initialized float arrays.95void PR10163_default_initialized_arrays(void) {96  float x[2] = {0};97  test_PR10163(x[1]); // no-warning  98}99 100struct MyStr {101  int x;102  int y;103};104void swap(struct MyStr *To, struct MyStr *From) {105  // This is not really a swap but close enough for our test.106  To->x = From->x;107  To->y = From->y; // expected-note{{Uninitialized value stored to field 'y'}}108}109int test_undefined_member_assignment_in_swap(struct MyStr *s2) {110  struct MyStr s1;111  s1.x = 5;112  swap(s2, &s1); // expected-note{{Calling 'swap'}}113                 // expected-note@-1{{Returning from 'swap'}}114  return s2->y; // expected-warning{{Undefined or garbage value returned to caller}}115                // expected-note@-1{{Undefined or garbage value returned to caller}}116}117 118@interface A119- (NSUInteger)foo;120@end121 122NSUInteger f8(A* x){123  const NSUInteger n = [x foo];124  int* bogus;  125 126  if (n > 0) {    // tests const cast transfer function logic127    NSUInteger i;128    129    for (i = 0; i < n; ++i)130      bogus = 0;131 132    if (bogus)  // no-warning133      return n+1;134  }135  136  return n;137}138 139 140 141 142typedef struct {143  float x;144  float y;145  float z;146} Point;147typedef struct {148  Point origin;149  int size;150} Circle;151 152Point makePoint(float x, float y) {153  Point result;154  result.x = x;155  result.y = y;156  result.z = 0.0;157  return result;158}159 160void PR14765_test(void) {161  Circle *testObj = calloc(1, sizeof(Circle));162 163  clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}164                                           // expected-note@-1{{TRUE}}165 166  testObj->origin = makePoint(0.0, 0.0);167  if (testObj->size > 0) { ; } // expected-note{{Assuming field 'size' is <= 0}}168                               // expected-note@-1{{Taking false branch}}169 170  // FIXME: Assigning to 'testObj->origin' kills the default binding for the171  // whole region, meaning that we've forgotten that testObj->size should also172  // default to 0.173  // This should be TRUE.174  clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}}175                                           // expected-note@-1{{UNKNOWN}}176 177  free(testObj);178}179 180void PR14765_argument(Circle *testObj) {181  int oldSize = testObj->size;182  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}183                                                 // expected-note@-1{{TRUE}}184 185  testObj->origin = makePoint(0.0, 0.0);186  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}187                                                 // expected-note@-1{{TRUE}}188}189 190 191typedef struct {192  int x;193  int y;194  int z;195} IntPoint;196typedef struct {197  IntPoint origin;198  int size;199} IntCircle;200 201IntPoint makeIntPoint(int x, int y) {202  IntPoint result;203  result.x = x;204  result.y = y;205  result.z = 0;206  return result;207}208 209void PR14765_test_int(void) {210  IntCircle *testObj = calloc(1, sizeof(IntCircle));211 212  clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}213                                           // expected-note@-1{{TRUE}}214  clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}}215                                               // expected-note@-1{{TRUE}}216  clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}}217                                               // expected-note@-1{{TRUE}}218  clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}219                                               // expected-note@-1{{TRUE}}220 221  testObj->origin = makeIntPoint(1, 2);222  if (testObj->size > 0) { ; } // expected-note{{Assuming field 'size' is <= 0}}223                               // expected-note@-1{{Taking false branch}}224                               // expected-note@-2{{Assuming field 'size' is <= 0}}225                               // expected-note@-3{{Taking false branch}}226                               // expected-note@-4{{Assuming field 'size' is <= 0}}227                               // expected-note@-5{{Taking false branch}}228                               // expected-note@-6{{Assuming field 'size' is <= 0}}229                               // expected-note@-7{{Taking false branch}}230 231  // FIXME: Assigning to 'testObj->origin' kills the default binding for the232  // whole region, meaning that we've forgotten that testObj->size should also233  // default to 0.234  // This should be TRUE.235  clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}}236                                           // expected-note@-1{{UNKNOWN}}237  clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}238                                               // expected-note@-1{{TRUE}}239  clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}240                                               // expected-note@-1{{TRUE}}241  clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}242                                               // expected-note@-1{{TRUE}}243 244  free(testObj);245}246 247void PR14765_argument_int(IntCircle *testObj) {248  int oldSize = testObj->size;249  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}250                                                 // expected-note@-1{{TRUE}}251 252  testObj->origin = makeIntPoint(1, 2);253  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}254                                                 // expected-note@-1{{TRUE}}255  clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}256                                               // expected-note@-1{{TRUE}}257  clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}258                                               // expected-note@-1{{TRUE}}259  clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}260                                               // expected-note@-1{{TRUE}}261}262 263 264void rdar13292559(Circle input) {265  extern void useCircle(Circle);266 267  Circle obj = input;268  useCircle(obj); // no-warning269 270  // This generated an "uninitialized 'size' field" warning for a (short) while.271  obj.origin = makePoint(0.0, 0.0);272  useCircle(obj); // no-warning273}274 275 276typedef struct {277  int x;278  int y;279} IntPoint2D;280typedef struct {281  IntPoint2D origin;282  int size;283} IntCircle2D;284 285IntPoint2D makeIntPoint2D(int x, int y) {286  IntPoint2D result;287  result.x = x;288  result.y = y;289  return result;290}291 292void testSmallStructsCopiedPerField(void) {293  IntPoint2D a;294  a.x = 0;295 296  IntPoint2D b = a;297  extern void useInt(int);298  useInt(b.x); // no-warning299  useInt(b.y); // expected-warning{{uninitialized}}300               // expected-note@-1{{uninitialized}}301}302 303void testLargeStructsNotCopiedPerField(void) {304  IntPoint a;305  a.x = 0;306 307  IntPoint b = a;308  extern void useInt(int);309  useInt(b.x); // no-warning310  useInt(b.y); // no-warning311}312 313void testSmallStructInLargerStruct(void) {314  IntCircle2D *testObj = calloc(1, sizeof(IntCircle2D));315 316  clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}317                                           // expected-note@-1{{TRUE}}318  clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}}319                                               // expected-note@-1{{TRUE}}320  clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}}321                                               // expected-note@-1{{TRUE}}322 323  testObj->origin = makeIntPoint2D(1, 2);324  if (testObj->size > 0) { ; } // expected-note{{Field 'size' is <= 0}}325                               // expected-note@-1{{Taking false branch}}326                               // expected-note@-2{{Field 'size' is <= 0}}327                               // expected-note@-3{{Taking false branch}}328                               // expected-note@-4{{Field 'size' is <= 0}}329                               // expected-note@-5{{Taking false branch}}330 331  clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}332                                           // expected-note@-1{{TRUE}}333  clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}334                                               // expected-note@-1{{TRUE}}335  clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}336                                               // expected-note@-1{{TRUE}}337 338  free(testObj);339}340 341void testCopySmallStructIntoArgument(IntCircle2D *testObj) {342  int oldSize = testObj->size;343  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}344                                                 // expected-note@-1{{TRUE}}345 346  testObj->origin = makeIntPoint2D(1, 2);347  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}348                                                 // expected-note@-1{{TRUE}}349  clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}350                                               // expected-note@-1{{TRUE}}351  clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}352                                               // expected-note@-1{{TRUE}}353}354 355void testSmallStructBitfields(void) {356  struct {357    int x : 4;358    int y : 4;359  } a, b;360 361  a.x = 1;362  a.y = 2;363 364  b = a;365  clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}366                                 // expected-note@-1{{TRUE}}367  clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}368                                 // expected-note@-1{{TRUE}}369}370 371void testSmallStructBitfieldsFirstUndef(void) {372  struct {373    int x : 4;374    int y : 4;375  } a, b;376 377  a.y = 2;378 379  b = a;380  clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}381                                 // expected-note@-1{{TRUE}}382  clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}}383                                 // expected-note@-1{{garbage}}384}385 386void testSmallStructBitfieldsSecondUndef(void) {387  struct {388    int x : 4;389    int y : 4;390  } a, b;391 392  a.x = 1;393 394  b = a;395  clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}396                                 // expected-note@-1{{TRUE}}397  clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}398                                 // expected-note@-1{{garbage}}399}400 401void testSmallStructBitfieldsFirstUnnamed(void) {402  struct {403    int : 4;404    int y : 4;405  } a, b, c; // expected-note{{'c' initialized here}}406 407  a.y = 2;408 409  b = a;410  clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}411                                 // expected-note@-1{{TRUE}}412 413  b = c; // expected-note{{Uninitialized value stored to 'b.y'}}414  clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}415                                 // expected-note@-1{{garbage}}416}417 418void testSmallStructBitfieldsSecondUnnamed(void) {419  struct {420    int x : 4;421    int : 4;422  } a, b, c; // expected-note{{'c' initialized here}}423 424  a.x = 1;425 426  b = a;427  clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}428                                 // expected-note@-1{{TRUE}}429 430  b = c; // expected-note{{Uninitialized value stored to 'b.x'}}431  clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}}432                                 // expected-note@-1{{garbage}}433}434