brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · 0c86f81 Raw
254 lines · cpp
1// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -verify %s2 3void clang_analyzer_eval(bool);4 5class A {6public:7    virtual void f(){};8 9};10class B : public A{11public:12  int m;13};14class C : public A{};15 16class BB: public B{};17 18// A lot of the tests below have the if statement in them, which forces the19// analyzer to explore both path - when the result is 0 and not. This makes20// sure that we definitely know that the result is non-0 (as the result of21// the cast).22int testDynCastFromRadar() {23    B aa;24    A *a = &aa;25    const int* res = 0;26    B *b = dynamic_cast<B*>(a);27    static const int i = 5;28    if(b) {29        res = &i;30    } else {31        res = 0;32    }33    return *res; // no warning34}35 36int testBaseToBase1() {37  B b;38  B *pb = &b;39  B *pbb = dynamic_cast<B*>(pb);40  const int* res = 0;41  static const int i = 5;42  if (pbb) {43      res = &i;44  } else {45      res = 0;46  }47  return *res; // no warning48}49 50int testMultipleLevelsOfSubclassing1() {51  BB bb;52  B *pb = &bb;53  A *pa = pb;54  B *b = dynamic_cast<B*>(pa);55  const int* res = 0;56  static const int i = 5;57  if (b) {58      res = &i;59  } else {60      res = 0;61  }62  return *res; // no warning63}64 65int testMultipleLevelsOfSubclassing2() {66  BB bb;67  A *pbb = &bb;68  B *b = dynamic_cast<B*>(pbb);69  BB *s = dynamic_cast<BB*>(b);70  const int* res = 0;71  static const int i = 5;72  if (s) {73      res = &i;74  } else {75      res = 0;76  }77  return *res; // no warning78}79 80int testMultipleLevelsOfSubclassing3() {81  BB bb;82  A *pbb = &bb;83  B *b = dynamic_cast<B*>(pbb);84  return b->m; // no warning85}86 87int testLHS() {88    B aa;89    A *a = &aa;90    return (dynamic_cast<B*>(a))->m;91}92 93int testLHS2() {94    B aa;95    A *a = &aa;96    return (*dynamic_cast<B*>(a)).m;97}98 99int testDynCastUnknown2(class A *a) {100  B *b = dynamic_cast<B*>(a);101  return b->m; // no warning102}103 104int testDynCastUnknown(class A *a) {105  B *b = dynamic_cast<B*>(a);106  const int* res = 0;107  static const int i = 5;108  if (b) {109    res = &i;110  } else {111    res = 0;112  }113  return *res; // expected-warning {{Dereference of null pointer}}114}115 116int testDynCastFail2() {117  C c;118  A *pa = &c;119  B *b = dynamic_cast<B*>(pa);120  return b->m; // expected-warning {{dereference of a null pointer}}121}122 123int testLHSFail() {124    C c;125    A *a = &c;126    return (*dynamic_cast<B*>(a)).m; // expected-warning {{Dereference of null pointer}}127}128 129int testBaseToDerivedFail() {130  A a;131  B *b = dynamic_cast<B*>(&a);132  return b->m; // expected-warning {{dereference of a null pointer}}133}134 135int testConstZeroFail() {136  B *b = dynamic_cast<B*>((A *)0);137  return b->m; // expected-warning {{dereference of a null pointer}}138}139 140int testConstZeroFail2() {141  A *a = 0;142  B *b = dynamic_cast<B*>(a);143  return b->m; // expected-warning {{dereference of a null pointer}}144}145 146int testUpcast() {147  B b;148  A *a = dynamic_cast<A*>(&b);149  const int* res = 0;150  static const int i = 5;151  if (a) {152      res = &i;153  } else {154      res = 0;155  }156  return *res; // no warning157}158 159int testCastToVoidStar() {160  A a;161  void *b = dynamic_cast<void*>(&a);162  const int* res = 0;163  static const int i = 5;164  if (b) {165      res = &i;166  } else {167      res = 0;168  }169  return *res; // no warning170}171 172int testReferenceSuccessfulCast() {173  B rb;174  B &b = dynamic_cast<B&>(rb);175  int *x = 0;176  return *x; // expected-warning {{Dereference of null pointer}}177}178 179int testReferenceFailedCast() {180  A a;181  B &b = dynamic_cast<B&>(a);182  int *x = 0;183  return *x; // no warning (An exception is thrown by the cast.)184}185 186// Here we allow any outcome of the cast and this is good because there is a187// situation where this will fail. So if the user has written the code in this188// way, we assume they expect the cast to succeed.189// Note, this might need special handling if we track types of symbolic casts190// and use them for dynamic_cast handling.191int testDynCastMostLikelyWillFail(C *c) {192  B *b = 0;193  b = dynamic_cast<B*>(c);194  const int* res = 0;195  static const int i = 5;196  if (b) {197      res = &i;198  } else {199      res = 0;200  }201 202  // Note: IPA is turned off for this test because the code below shows how the203  // dynamic_cast could succeed.204  return *res; // expected-warning{{Dereference of null pointer}}205}206 207class M : public B, public C {};208void callTestDynCastMostLikelyWillFail() {209  M m;210  testDynCastMostLikelyWillFail(&m);211}212 213 214void testDynCastToMiddleClass () {215  class BBB : public BB {};216  BBB obj;217  A &ref = obj;218 219  // These didn't always correctly layer base regions.220  B *ptr = dynamic_cast<B*>(&ref);221  clang_analyzer_eval(ptr != 0); // expected-warning{{TRUE}}222 223  // This is actually statically resolved to be a DerivedToBase cast.224  ptr = dynamic_cast<B*>(&obj);225  clang_analyzer_eval(ptr != 0); // expected-warning{{TRUE}}226}227 228 229// -----------------------------230// False positives/negatives.231// -----------------------------232 233// Due to symbolic regions not being typed.234int testDynCastFalsePositive(BB *c) {235  B *b = 0;236  b = dynamic_cast<B*>(c);237  const int* res = 0;238  static const int i = 5;239  if (b) {240      res = &i;241  } else {242      res = 0;243  }244  return *res; // expected-warning{{Dereference of null pointer}}245}246 247// Does not work when we new an object.248int testDynCastFail3() {249  A *a = new A();250  B *b = dynamic_cast<B*>(a);251  return b->m;252}253 254