brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.0 KiB · 958ad5e Raw
728 lines · cpp
1// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -fblocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare2// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -fblocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare3 4void clang_analyzer_warnIfReached();5 6// Test basic handling of references.7char &test1_aux();8char *test1() {9  return &test1_aux();10}11 12// Test test1_aux() evaluates to char &.13char test1_as_rvalue() {14  return test1_aux();15}16 17// Test passing a value as a reference.  The 'const' in test2_aux() adds18// an ImplicitCastExpr, which is evaluated as an lvalue.19int test2_aux(const int &n);20int test2(int n) {21  return test2_aux(n);22}23 24int test2_b_aux(const short &n);25int test2_b(int n) {26  return test2_b_aux(n);27}28 29// Test getting the lvalue of a derived and converting it to a base.  This30// previously crashed.31class Test3_Base {};32class Test3_Derived : public Test3_Base {};33 34int test3_aux(Test3_Base &x);35int test3(Test3_Derived x) {36  return test3_aux(x);37}38 39//===---------------------------------------------------------------------===//40// Test CFG support for C++ condition variables.41//===---------------------------------------------------------------------===//42 43int test_init_in_condition_aux();44int test_init_in_condition() {45  if (int x = test_init_in_condition_aux()) { // no-warning46    return 1;47  }48  return 0;49}50 51int test_init_in_condition_switch() {52  switch (int x = test_init_in_condition_aux()) { // no-warning53    case 1:54      return 0;55    case 2:56      if (x == 2)57        return 0;58      else {59        clang_analyzer_warnIfReached();  // unreachable60      }61    default:62      break;63  }64  return 0;65}66 67int test_init_in_condition_while() {68  int z = 0;69  while (int x = ++z) { // no-warning70    if (x == 2)71      break;72  }73  74  if (z == 2)75    return 0;76  77  clang_analyzer_warnIfReached();  // unreachable78  return 0;79}80 81 82int test_init_in_condition_for() {83  int z = 0;84  for (int x = 0; int y = ++z; ++x) {85    if (x == y) // no-warning86      break;87  }88  if (z == 1)89    return 0;90    91  clang_analyzer_warnIfReached();  // unreachable92  return 0;93}94 95//===---------------------------------------------------------------------===//96// Test handling of 'this' pointer.97//===---------------------------------------------------------------------===//98 99class TestHandleThis {100  int x;101 102  TestHandleThis();  103  int foo();104  int null_deref_negative();105  int null_deref_positive();  106};107 108int TestHandleThis::foo() {109  // Assume that 'x' is initialized.110  return x + 1; // no-warning111}112 113int TestHandleThis::null_deref_negative() {114  x = 10;115  if (x == 10) {116    return 1;117  }118  clang_analyzer_warnIfReached();  // unreachable119  return 0;  120}121 122int TestHandleThis::null_deref_positive() {123  x = 10;124  if (x == 9) {125    return 1;126  }127  clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}128  return 0;  129}130 131// PR 7675 - passing literals by-reference132void pr7675(const double &a);133void pr7675(const int &a);134void pr7675(const char &a);135void pr7675_i(const _Complex double &a);136 137void pr7675_test() {138  pr7675(10.0);139  pr7675(10);140  pr7675('c');141  pr7675_i(4.0j);142 143  // Add check to ensure we are analyzing the code up to this point.144  clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}145}146 147// CFGBuilder should handle temporaries.148struct R8375510 {149  R8375510();150  ~R8375510();151  R8375510 operator++(int);152};153 154int r8375510(R8375510 x, R8375510 y) {155  for (; ; x++) { }156}157 158// PR8419 -- this used to crash.159 160class String8419 {161 public:162  char& get(int n);163  char& operator[](int n);164};165 166char& get8419();167 168void Test8419() {169  String8419 s;170  ++(s.get(0));171  get8419()--;  // used to crash172  --s[0];       // used to crash173  s[0] &= 1;    // used to crash174  s[0]++;       // used to crash175}176 177// PR8426 -- this used to crash.178 179void Use(void* to);180 181template <class T> class Foo {182  ~Foo();183  struct Bar;184  Bar* bar_;185};186 187template <class T> Foo<T>::~Foo() {188  Use(bar_);189  T::DoSomething();190  bar_->Work();191}192 193// PR8427 -- this used to crash.194 195class Dummy {};196 197bool operator==(Dummy, int);198 199template <typename T>200class Foo2 {201  bool Bar();202};203 204template <typename T>205bool Foo2<T>::Bar() {206  return 0 == T();207}208 209// PR8433 -- this used to crash.210 211template <typename T>212class Foo3 {213 public:214  void Bar();215  void Baz();216  T value_;217};218 219template <typename T>220void Foo3<T>::Bar() {221  Baz();222  value_();223}224 225//===---------------------------------------------------------------------===//226// Handle misc. C++ constructs.227//===---------------------------------------------------------------------===//228 229namespace fum {230  int i = 3;231};232 233void test_namespace() {234  // Previously triggered a crash.235  using namespace fum;236  int x = i;237}238 239// Test handling methods that accept references as parameters, and that240// variables are properly invalidated.241class RDar9203355 {242  bool foo(unsigned valA, long long &result) const;243  bool foo(unsigned valA, int &result) const;244};245bool RDar9203355::foo(unsigned valA, int &result) const {246  long long val;247  if (foo(valA, val) ||248      (int)val != val) // no-warning249    return true;250  result = val; // no-warning251  return false;252}253 254// Test handling of new[].255void rdar9212512() {256  int *x = new int[10];257  for (unsigned i = 0 ; i < 2 ; ++i) {258    // This previously triggered an uninitialized values warning.259    x[i] = 1;  // no-warning260  }261}262 263// Test basic support for dynamic_cast<>.264struct Rdar9212495_C { virtual void bar() const; };265class Rdar9212495_B : public Rdar9212495_C {};266class Rdar9212495_A : public Rdar9212495_B {};267const Rdar9212495_A& rdar9212495(const Rdar9212495_C* ptr) {268  const Rdar9212495_A& val = dynamic_cast<const Rdar9212495_A&>(*ptr);269  270  // This is not valid C++; dynamic_cast with a reference type will throw an271  // exception if the pointer does not match the expected type. However, our272  // implementation of dynamic_cast will pass through a null pointer...or a273  // "null reference"! So this branch is actually possible.274  if (&val == 0) {275    val.bar(); // expected-warning{{Called C++ object pointer is null}}276  }277  278  return val;279}280 281const Rdar9212495_A* rdar9212495_ptr(const Rdar9212495_C* ptr) {282  const Rdar9212495_A* val = dynamic_cast<const Rdar9212495_A*>(ptr);283 284  if (val == 0) {285    val->bar(); // expected-warning{{Called C++ object pointer is null}}286  }287 288  return val;289}290 291// Test constructors invalidating arguments.  Previously this raised292// an uninitialized value warning.293extern "C" void __attribute__((noreturn)) PR9645_exit(int i);294 295class PR9645_SideEffect296{297public:298  PR9645_SideEffect(int *pi); // caches pi in i_299  void Read(int *pi); // copies *pi into *i_300private:301  int *i_;302};303 304void PR9645() {305  int i;306 307  PR9645_SideEffect se(&i);308  int j = 1;309  se.Read(&j); // this has a side-effect of initializing i.310 311  PR9645_exit(i); // no-warning312}313 314PR9645_SideEffect::PR9645_SideEffect(int *pi) : i_(pi) {}315void PR9645_SideEffect::Read(int *pi) { *i_ = *pi; }316 317// Invalidate fields during C++ method calls.318class RDar9267815 {319  int x;320  void test();321  void test_pos();322  void test2();323  void invalidate();324};325 326void RDar9267815::test_pos() {327  if (x == 42)328    return;329  clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}330}331void RDar9267815::test() {332  if (x == 42)333    return;334  if (x == 42)335    clang_analyzer_warnIfReached();  // no-warning336}337 338void RDar9267815::test2() {339  if (x == 42)340    return;341  invalidate();342  if (x == 42)343    clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}344}345 346// Test reference parameters.347void test_ref_double_aux(double &Value);348float test_ref_double() {349  double dVal;350  test_ref_double_aux(dVal);351  // This previously warned because 'dVal' was thought to be uninitialized.352  float Val = (float)dVal; // no-warning353  return Val;354}355 356// Test invalidation of class fields.357class TestInvalidateClass {358public:359  int x;360};361 362void test_invalidate_class_aux(TestInvalidateClass &x);363 364int test_invalidate_class() {365  TestInvalidateClass y;366  test_invalidate_class_aux(y);367  return y.x; // no-warning368}369 370// Test correct pointer arithmetic using 'p--'.  This is to warn that we371// were loading beyond the written characters in buf.372char *RDar9269695(char *dst, unsigned int n)373{374  char buff[40], *p;375 376  p = buff;377  do378    *p++ = '0' + n % 10;379  while (n /= 10);380 381  do382    *dst++ = *--p; // no-warning383  while (p != buff);384 385  return dst;386}387 388// Test that we invalidate byref arguments passed to constructors.389class TestInvalidateInCtor {390public:391  TestInvalidateInCtor(unsigned &x);392};393 394unsigned test_invalidate_in_ctor() {395  unsigned x;396  TestInvalidateInCtor foo(x);397  return x; // no-warning398}399unsigned test_invalidate_in_ctor_new() {400  unsigned x;401  delete (new TestInvalidateInCtor(x));402  return x; // no-warning403}404 405// Test assigning into a symbolic offset.406struct TestAssignIntoSymbolicOffset {407  int **stuff[100];408  void test(int x, int y);409};410 411void TestAssignIntoSymbolicOffset::test(int x, int y) {412  x--;413  if (x > 8 || x < 0)414    return;415  if (stuff[x])416    return;417  if (!stuff[x]) {418    stuff[x] = new int*[y+1];419    // Previously triggered a null dereference.420    stuff[x][y] = 0; // no-warning421  }422}423 424// Test loads from static fields.  This previously triggered an uninitialized425// value warning.426class ClassWithStatic {427public:428    static const unsigned value = 1;429};430 431int rdar9948787_negative() {432    ClassWithStatic classWithStatic;433    unsigned value = classWithStatic.value;434    if (value == 1)435      return 1;436    clang_analyzer_warnIfReached();  // no-warning437    return 0;438}439 440int rdar9948787_positive() {441    ClassWithStatic classWithStatic;442    unsigned value = classWithStatic.value;443    if (value == 0)444      return 1;445    clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}446    return 0;447}448 449// Regression test against global constants and switches.450enum rdar10202899_ValT { rdar10202899_ValTA, rdar10202899_ValTB, rdar10202899_ValTC };451const rdar10202899_ValT val = rdar10202899_ValTA;452void rdar10202899_test1() {453  switch (val) {454    case rdar10202899_ValTA: {}455  };456}457 458void rdar10202899_test2() {459  if (val == rdar10202899_ValTA)460   return;461  clang_analyzer_warnIfReached();  // no-warning462}463 464void rdar10202899_test3() {465  switch (val) {466    case rdar10202899_ValTA: return;467    default: ;468  };469  clang_analyzer_warnIfReached();  // no-warning470}471 472// This used to crash the analyzer because of the unnamed bitfield.473void PR11249()474{475  struct {476    char f1:4;477    char   :4;478    char f2[1];479    char f3;480  } V = { 1, {2}, 3 };481  if (V.f1 != 1)482    clang_analyzer_warnIfReached();  // no-warning483  if (V.f2[0] != 2)484    clang_analyzer_warnIfReached();  // no-warning485  if (V.f3 != 3)486    clang_analyzer_warnIfReached();  // no-warning487}488 489// Handle doing a load from the memory associated with the code for490// a function.491extern double nan( const char * );492double PR11450() {493  double NaN = *(double*) nan;494  return NaN;495}496 497// Test that 'this' is assumed non-null upon analyzing the entry to a "top-level"498// function (i.e., when not analyzing from a specific caller).499struct TestNullThis {500  int field;501  void test();502};503 504void TestNullThis::test() {505  int *p = &field;506  if (p)507    return;508  field = 2; // no-warning509}510 511// Test handling of 'catch' exception variables, and not warning512// about uninitialized values.513enum MyEnum { MyEnumValue };514MyEnum rdar10892489() {515  try {516      throw MyEnumValue;517  } catch (MyEnum e) {518      return e; // no-warning519  }520  return MyEnumValue;521}522 523MyEnum rdar10892489_positive() {524  try {525    throw MyEnumValue;526  } catch (MyEnum e) {527    int *p = 0;528    // FALSE NEGATIVE529    *p = 0xDEADBEEF; // {{null}}530    return e;531  }532  return MyEnumValue;533}534 535// Test handling of catch with no condition variable.536void PR11545() {537  try538  {539      throw;540  }541  catch (...)542  {543  }544}545 546void PR11545_positive() {547  try548  {549      throw;550  }551  catch (...)552  {553    int *p = 0;554    // FALSE NEGATIVE555    *p = 0xDEADBEEF; // {{null}}556  }557}558 559// Test handling taking the address of a field.  While the analyzer560// currently doesn't do anything intelligent here, this previously561// resulted in a crash.562class PR11146 {563public:564  struct Entry;565  void baz();566};567 568struct PR11146::Entry {569  int x;570};571 572void PR11146::baz() {573  (void) &Entry::x;574}575 576// Test symbolicating a reference.  In this example, the577// analyzer (originally) didn't know how to handle x[index - index2],578// returning an UnknownVal.  The conjured symbol wasn't a location,579// and would result in a crash.580void rdar10924675(unsigned short x[], int index, int index2) {581  unsigned short &y = x[index - index2];582  if (y == 0)583    return;584}585 586// Test handling CXXScalarValueInitExprs.587void rdar11401827() {588  int x = int();589  if (!x) {590    clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}591    ; // Suppress warning that both branches are identical592  }593  else {594    clang_analyzer_warnIfReached();  // no-warning595  }596}597 598//===---------------------------------------------------------------------===//599// Handle inlining of C++ method calls.600//===---------------------------------------------------------------------===//601 602struct A {603  int *p;604  void foo(int *q) {605    p = q;606  }607  void bar() {608    *p = 0; // expected-warning {{null pointer}}609  }610};611 612void test_inline() {613  A a;614  a.foo(0);615  a.bar();616}617 618void test_alloca_in_a_recursive_function(int p1) {619    __builtin_alloca (p1);620    test_alloca_in_a_recursive_function(1);621    test_alloca_in_a_recursive_function(2);622}623 624//===---------------------------------------------------------------------===//625// Random tests.626//===---------------------------------------------------------------------===//627 628// Tests assigning using a C-style initializer to a struct629// variable whose sub-field is also a struct.  This currently630// results in a CXXTempObjectRegion being created, but not631// properly handled.  For now, we just ignore that value632// to avoid a crash.633struct RDar12753384_ClassA {634  unsigned z;635};636struct  RDar12753384_ClassB {637  unsigned x;638  RDar12753384_ClassA y[ 8 ] ;639};640unsigned RDar12753384() {641  RDar12753384_ClassB w = { 0x00 };642  RDar12753384_ClassA y[8];643  return w.x;644}645 646// This testcase tests whether we treat the anonymous union and union647// the same way.  This previously resulted in a "return of stack address"648// warning because the anonymous union resulting in a temporary object649// getting put into the initializer.  We still aren't handling this correctly,650// but now if a temporary object appears in an initializer we just ignore it.651 652struct Rdar12755044_foo653{654    struct Rdar12755044_bar655    {656        union baz657        {658            int   i;659        };660    } aBar;661};662 663struct Rdar12755044_foo_anon664{665    struct Rdar12755044_bar666    {667        union668        {669            int   i;670        };671    } aBar;672};673 674const Rdar12755044_foo_anon *radar12755044_anon() {675  static const Rdar12755044_foo_anon Rdar12755044_foo_list[] = { { { } } };676  return Rdar12755044_foo_list; // no-warning677}678 679const Rdar12755044_foo *radar12755044() {680  static const Rdar12755044_foo Rdar12755044_foo_list[] = { { { } } };681  return Rdar12755044_foo_list; // no-warning682}683 684// Test the correct handling of integer to bool conversions.  Previously685// this resulted in a false positive because integers were being truncated686// and not tested for non-zero.687void rdar12759044() {688  int flag = 512;689  if (!(flag & 512)) {690    clang_analyzer_warnIfReached();  // no-warning691  }692}693 694// The analyzer currently does not model complex types.  Test that the load695// from 'x' is not flagged as being uninitialized.696typedef __complex__ float _ComplexT;697void rdar12964481(_ComplexT *y) {698   _ComplexT x;699   __real__ x = 1.0;700   __imag__ x = 1.0;701   *y *= x; // no-warning702}703void rdar12964481_b(_ComplexT *y) {704   _ComplexT x;705   // Eventually this should be a warning.706   *y *= x; // no-warning707}708 709// Test case for PR 12921.  This previously produced710// a bogus warning.711static const int pr12921_arr[] = { 0, 1 };712static const int pr12921_arrcount = sizeof(pr12921_arr)/sizeof(int);713 714int pr12921(int argc, char **argv) {715  int i, retval;716  for (i = 0; i < pr12921_arrcount; i++) {717    if (argc == i) {718      retval = i;719      break;720    }721  }722 723  // No match724  if (i == pr12921_arrcount) return 66;725  return pr12921_arr[retval];726}727 728