brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · 611e1d8 Raw
441 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \2// RUN:   -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \3// RUN:   -analyzer-config optin.cplusplus.UninitializedObject:IgnoreGuardedFields=true \4// RUN:   -std=c++11 -verify  %s5 6//===----------------------------------------------------------------------===//7// Helper functions for tests.8//===----------------------------------------------------------------------===//9 10[[noreturn]] void halt();11 12void assert(int b) {13  if (!b)14    halt();15}16 17int rand();18 19//===----------------------------------------------------------------------===//20// Tests for fields properly guarded by asserts.21//===----------------------------------------------------------------------===//22 23class NoUnguardedFieldsTest {24public:25  enum Kind {26    V,27    A28  };29 30private:31  int Volume, Area;32  Kind K;33 34public:35  NoUnguardedFieldsTest(Kind K) : K(K) {36    switch (K) {37    case V:38      Volume = 0;39      break;40    case A:41      Area = 0;42      break;43    }44  }45 46  void operator-() {47    assert(K == Kind::A);48    (void)Area;49  }50 51  void operator+() {52    assert(K == Kind::V);53    (void)Volume;54  }55};56 57void fNoUnguardedFieldsTest() {58  NoUnguardedFieldsTest T1(NoUnguardedFieldsTest::Kind::A);59  NoUnguardedFieldsTest T2(NoUnguardedFieldsTest::Kind::V);60}61 62class NoUngardedFieldsNoReturnFuncCalledTest {63public:64  enum Kind {65    V,66    A67  };68 69private:70  int Volume, Area;71  Kind K;72 73public:74  NoUngardedFieldsNoReturnFuncCalledTest(Kind K) : K(K) {75    switch (K) {76    case V:77      Volume = 0;78      break;79    case A:80      Area = 0;81      break;82    }83  }84 85  void operator-() {86    halt();87    (void)Area;88  }89 90  void operator+() {91    halt();92    (void)Volume;93  }94};95 96void fNoUngardedFieldsNoReturnFuncCalledTest() {97  NoUngardedFieldsNoReturnFuncCalledTest98    T1(NoUngardedFieldsNoReturnFuncCalledTest::Kind::A);99  NoUngardedFieldsNoReturnFuncCalledTest100    T2(NoUngardedFieldsNoReturnFuncCalledTest::Kind::V);101}102 103class NoUnguardedFieldsWithUndefMethodTest {104public:105  enum Kind {106    V,107    A108  };109 110private:111  int Volume, Area;112  Kind K;113 114public:115  NoUnguardedFieldsWithUndefMethodTest(Kind K) : K(K) {116    switch (K) {117    case V:118      Volume = 0;119      break;120    case A:121      Area = 0;122      break;123    }124  }125 126  void operator-() {127    assert(K == Kind::A);128    (void)Area;129  }130 131  void operator+() {132    assert(K == Kind::V);133    (void)Volume;134  }135 136  // We're checking method definitions for guards, so this is a no-crash test137  // whether we handle methods without definitions.138  void methodWithoutDefinition();139};140 141void fNoUnguardedFieldsWithUndefMethodTest() {142  NoUnguardedFieldsWithUndefMethodTest143      T1(NoUnguardedFieldsWithUndefMethodTest::Kind::A);144  NoUnguardedFieldsWithUndefMethodTest145      T2(NoUnguardedFieldsWithUndefMethodTest::Kind::V);146}147 148class UnguardedFieldThroughMethodTest {149public:150  enum Kind {151    V,152    A153  };154 155private:156  int Volume, Area; // expected-note {{uninitialized field 'this->Volume'}}157  Kind K;158 159public:160  UnguardedFieldThroughMethodTest(Kind K) : K(K) {161    switch (K) {162    case V:163      Volume = 0;164      break;165    case A:166      Area = 0;167      break; // expected-warning {{1 uninitialized field}}168    }169  }170 171  void operator-() {172    assert(K == Kind::A);173    (void)Area;174  }175 176  void operator+() {177    (void)Volume;178  }179};180 181void fUnguardedFieldThroughMethodTest() {182  UnguardedFieldThroughMethodTest T1(UnguardedFieldThroughMethodTest::Kind::A);183}184 185class UnguardedPublicFieldsTest {186public:187  enum Kind {188    V,189    A190  };191 192public:193  // Note that fields are public.194  int Volume, Area; // expected-note {{uninitialized field 'this->Volume'}}195  Kind K;196 197public:198  UnguardedPublicFieldsTest(Kind K) : K(K) {199    switch (K) {200    case V:201      Volume = 0;202      break;203    case A:204      Area = 0;205      break; // expected-warning {{1 uninitialized field}}206    }207  }208 209  void operator-() {210    assert(K == Kind::A);211    (void)Area;212  }213 214  void operator+() {215    assert(K == Kind::V);216    (void)Volume;217  }218};219 220void fUnguardedPublicFieldsTest() {221  UnguardedPublicFieldsTest T1(UnguardedPublicFieldsTest::Kind::A);222}223 224//===----------------------------------------------------------------------===//225// Highlights of some false negatives due to syntactic checking.226//===----------------------------------------------------------------------===//227 228class UnguardedFalseNegativeTest1 {229public:230  enum Kind {231    V,232    A233  };234 235private:236  int Volume, Area;237  Kind K;238 239public:240  UnguardedFalseNegativeTest1(Kind K) : K(K) {241    switch (K) {242    case V:243      Volume = 0;244      break;245    case A:246      Area = 0;247      break;248    }249  }250 251  void operator-() {252    if (rand())253      assert(K == Kind::A);254    (void)Area;255  }256 257  void operator+() {258    if (rand())259      assert(K == Kind::V);260    (void)Volume;261  }262};263 264void fUnguardedFalseNegativeTest1() {265  UnguardedFalseNegativeTest1 T1(UnguardedFalseNegativeTest1::Kind::A);266}267 268class UnguardedFalseNegativeTest2 {269public:270  enum Kind {271    V,272    A273  };274 275private:276  int Volume, Area;277  Kind K;278 279public:280  UnguardedFalseNegativeTest2(Kind K) : K(K) {281    switch (K) {282    case V:283      Volume = 0;284      break;285    case A:286      Area = 0;287      break;288    }289  }290 291  void operator-() {292    assert(rand());293    (void)Area;294  }295 296  void operator+() {297    assert(rand());298    (void)Volume;299  }300};301 302void fUnguardedFalseNegativeTest2() {303  UnguardedFalseNegativeTest2 T1(UnguardedFalseNegativeTest2::Kind::A);304}305 306//===----------------------------------------------------------------------===//307// Tests for other guards. These won't be as thorough, as other guards are308// matched the same way as asserts, so if they are recognized, they are expected309// to work as well as asserts do.310//311// None of these tests expect warnings, since the flag works correctly if these312// fields are regarded properly guarded.313//===----------------------------------------------------------------------===//314 315class IfGuardedFieldsTest {316public:317  enum Kind {318    V,319    A320  };321 322private:323  int Volume, Area;324  Kind K;325 326public:327  IfGuardedFieldsTest(Kind K) : K(K) {328    switch (K) {329    case V:330      Volume = 0;331      break;332    case A:333      Area = 0;334      break;335    }336  }337 338  void operator-() {339    if (K != Kind::A)340      return;341    (void)Area;342  }343 344  void operator+() {345    if (K != Kind::V)346      return;347    (void)Volume;348  }349};350 351void fIfGuardedFieldsTest() {352  IfGuardedFieldsTest T1(IfGuardedFieldsTest::Kind::A);353  IfGuardedFieldsTest T2(IfGuardedFieldsTest::Kind::V);354}355 356class SwitchGuardedFieldsTest {357public:358  enum Kind {359    V,360    A361  };362 363private:364  int Volume, Area;365  Kind K;366 367public:368  SwitchGuardedFieldsTest(Kind K) : K(K) {369    switch (K) {370    case V:371      Volume = 0;372      break;373    case A:374      Area = 0;375      break;376    }377  }378 379  int operator-() {380    switch (K) {381    case Kind::A:382      return Area;383    case Kind::V:384      return -1;385    }386  }387 388  int operator+() {389    switch (K) {390    case Kind::A:391      return Area;392    case Kind::V:393      return -1;394    }395  }396};397 398void fSwitchGuardedFieldsTest() {399  SwitchGuardedFieldsTest T1(SwitchGuardedFieldsTest::Kind::A);400  SwitchGuardedFieldsTest T2(SwitchGuardedFieldsTest::Kind::V);401}402 403class ConditionalOperatorGuardedFieldsTest {404public:405  enum Kind {406    V,407    A408  };409 410private:411  int Volume, Area;412  Kind K;413 414public:415  ConditionalOperatorGuardedFieldsTest(Kind K) : K(K) {416    switch (K) {417    case V:418      Volume = 0;419      break;420    case A:421      Area = 0;422      break;423    }424  }425 426  int operator-() {427    return K == Kind::A ? Area : -1;428  }429 430  int operator+() {431    return K == Kind::V ? Volume : -1;432  }433};434 435void fConditionalOperatorGuardedFieldsTest() {436  ConditionalOperatorGuardedFieldsTest437      T1(ConditionalOperatorGuardedFieldsTest::Kind::A);438  ConditionalOperatorGuardedFieldsTest439      T2(ConditionalOperatorGuardedFieldsTest::Kind::V);440}441