brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.3 KiB · a1adaa7 Raw
323 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s2 3void clang_analyzer_eval(bool);4 5struct A {6  // This conversion operator allows implicit conversion to bool but not to other integer types.7  typedef A * (A::*MemberPointer);8  operator MemberPointer() const { return m_ptr ? &A::m_ptr : 0; }9 10  A *m_ptr;11 12  A *getPtr();13  typedef A * (A::*MemberFnPointer)(void);14};15 16void testConditionalUse() {17  A obj;18 19  obj.m_ptr = &obj;20  clang_analyzer_eval(obj.m_ptr); // expected-warning{{TRUE}}21  clang_analyzer_eval(&A::m_ptr); // expected-warning{{TRUE}}22  clang_analyzer_eval(obj); // expected-warning{{TRUE}}23 24  obj.m_ptr = 0;25  clang_analyzer_eval(obj.m_ptr); // expected-warning{{FALSE}}26  clang_analyzer_eval(A::MemberPointer(0)); // expected-warning{{FALSE}}27  clang_analyzer_eval(obj); // expected-warning{{FALSE}}28 29  clang_analyzer_eval(&A::getPtr); // expected-warning{{TRUE}}30  clang_analyzer_eval(A::MemberFnPointer(0)); // expected-warning{{FALSE}}31}32 33 34void testComparison() {35  clang_analyzer_eval(&A::getPtr == &A::getPtr); // expected-warning{{TRUE}}36  clang_analyzer_eval(&A::getPtr == 0); // expected-warning{{FALSE}}37 38  clang_analyzer_eval(&A::m_ptr == &A::m_ptr); // expected-warning{{TRUE}}39}40 41namespace PR15742 {42  template <class _T1, class _T2> struct A {43    A (const _T1 &, const _T2 &);44  };45  46  typedef void *NPIdentifier;47 48  template <class T> class B {49  public:50    typedef A<NPIdentifier, bool (T::*) (const NPIdentifier *, unsigned,51                                         NPIdentifier *)> MethodMapMember;52  };53 54  class C : public B<C> {55  public:56    bool Find(const NPIdentifier *, unsigned, NPIdentifier *);57  };58 59  void InitStaticData () {60    C::MethodMapMember(0, &C::Find); // don't crash61  }62}63 64bool testDereferencing() {65  A obj;66  obj.m_ptr = 0;67 68  A::MemberPointer member = &A::m_ptr;69 70  clang_analyzer_eval(obj.*member == 0); // expected-warning{{TRUE}}71 72  member = 0;73 74  return obj.*member; // expected-warning{{The result of the '.*' expression is undefined}}75}76 77namespace testPointerToMemberFunction {78  struct A {79    virtual int foo() { return 1; }80    int bar() { return 2; }81    int static staticMemberFunction(int p) { return p + 1; };82  };83 84  struct B : public A {85    virtual int foo() { return 3; }86  };87 88  typedef int (A::*AFnPointer)();89  typedef int (B::*BFnPointer)();90 91  void testPointerToMemberCasts() {92    AFnPointer AFP = &A::bar;93    BFnPointer StaticCastedBase2Derived = static_cast<BFnPointer>(&A::bar),94               CCastedBase2Derived = (BFnPointer) (&A::bar);95    A a;96    B b;97 98    clang_analyzer_eval((a.*AFP)() == 2); // expected-warning{{TRUE}}99    clang_analyzer_eval((b.*StaticCastedBase2Derived)() == 2); // expected-warning{{TRUE}}100    clang_analyzer_eval(((b.*CCastedBase2Derived)() == 2)); // expected-warning{{TRUE}}101  }102 103  void testPointerToMemberVirtualCall() {104    A a;105    B b;106    A *APtr = &a;107    AFnPointer AFP = &A::foo;108 109    clang_analyzer_eval((APtr->*AFP)() == 1); // expected-warning{{TRUE}}110 111    APtr = &b;112 113    clang_analyzer_eval((APtr->*AFP)() == 3); // expected-warning{{TRUE}}114  }115 116  void testPointerToStaticMemberCall() {117    int (*fPtr)(int) = &A::staticMemberFunction;118    if (fPtr != 0) { // no-crash119      clang_analyzer_eval(fPtr(2) == 3); // expected-warning{{TRUE}}120    }121  }122} // end of testPointerToMemberFunction namespace123 124namespace testPointerToMemberData {125  struct A {126    int i;127    static int j;128  };129 130  void testPointerToMemberData() {131    int A::*AMdPointer = &A::i;132    A a;133 134    a.i = 42;135    a.*AMdPointer += 1;136 137    clang_analyzer_eval(a.i == 43); // expected-warning{{TRUE}}138 139    int *ptrToStaticField = &A::j;140    if (ptrToStaticField != 0) {141      *ptrToStaticField = 7;142      clang_analyzer_eval(*ptrToStaticField == 7); // expected-warning{{TRUE}}143      clang_analyzer_eval(A::j == 7); // expected-warning{{TRUE}}144    }145  }146} // end of testPointerToMemberData namespace147 148namespace testPointerToMemberMiscCasts {149struct B {150  int f;151};152 153struct D : public B {154  int g;155};156 157void foo() {158  D d;159  d.f = 7;160 161  int B::* pfb = &B::f;162  int D::* pfd = pfb;163  int v = d.*pfd;164 165  clang_analyzer_eval(v == 7); // expected-warning{{TRUE}}166}167} // end of testPointerToMemberMiscCasts namespace168 169namespace testPointerToMemberMiscCasts2 {170struct B {171  int f;172};173struct L : public B { };174struct R : public B { };175struct D : public L, R { };176 177void foo() {178  D d;179 180  int B::* pb = &B::f;181  int L::* pl = pb;182  int R::* pr = pb;183 184  int D::* pdl = pl;185  int D::* pdr = pr;186 187  clang_analyzer_eval(pdl == pdr); // expected-warning{{FALSE}}188  clang_analyzer_eval(pb == pl); // expected-warning{{TRUE}}189}190} // end of testPointerToMemberMiscCasts2 namespace191 192namespace testPointerToMemberDiamond {193struct B {194  int f;195};196struct L1 : public B { };197struct R1 : public B { };198struct M : public L1, R1 { };199struct L2 : public M { };200struct R2 : public M { };201struct D2 : public L2, R2 { };202 203void diamond() {204  M m;205 206  static_cast<L1 *>(&m)->f = 7;207  static_cast<R1 *>(&m)->f = 16;208 209  int L1::* pl1 = &B::f;210  int M::* pm_via_l1 = pl1;211 212  int R1::* pr1 = &B::f;213  int M::* pm_via_r1 = pr1;214 215  clang_analyzer_eval(m.*(pm_via_l1) == 7); // expected-warning {{TRUE}}216  clang_analyzer_eval(m.*(pm_via_r1) == 16); // expected-warning {{TRUE}}217}218 219void double_diamond() {220  D2 d2;221 222  static_cast<L1 *>(static_cast<L2 *>(&d2))->f = 1;223  static_cast<L1 *>(static_cast<R2 *>(&d2))->f = 2;224  static_cast<R1 *>(static_cast<L2 *>(&d2))->f = 3;225  static_cast<R1 *>(static_cast<R2 *>(&d2))->f = 4;226 227  clang_analyzer_eval(d2.*(static_cast<int D2::*>(static_cast<int L2::*>(static_cast<int L1::*>(&B::f)))) == 1); // expected-warning {{TRUE}}228  clang_analyzer_eval(d2.*(static_cast<int D2::*>(static_cast<int R2::*>(static_cast<int L1::*>(&B::f)))) == 2); // expected-warning {{TRUE}}229  clang_analyzer_eval(d2.*(static_cast<int D2::*>(static_cast<int L2::*>(static_cast<int R1::*>(&B::f)))) == 3); // expected-warning {{TRUE}}230  clang_analyzer_eval(d2.*(static_cast<int D2::*>(static_cast<int R2::*>(static_cast<int R1::*>(&B::f)))) == 4); // expected-warning {{TRUE}}231}232} // end of testPointerToMemberDiamond namespace233 234namespace testAnonymousMember {235struct A {236  int a;237  struct {238    int b;239    int c;240  };241  struct {242    struct {243      int d;244      int e;245    };246  };247  struct {248    union {249      int f;250    };251  };252};253 254void test() {255  clang_analyzer_eval(&A::a); // expected-warning{{TRUE}}256  clang_analyzer_eval(&A::b); // expected-warning{{TRUE}}257  clang_analyzer_eval(&A::c); // expected-warning{{TRUE}}258  clang_analyzer_eval(&A::d); // expected-warning{{TRUE}}259  clang_analyzer_eval(&A::e); // expected-warning{{TRUE}}260  clang_analyzer_eval(&A::f); // expected-warning{{TRUE}}261 262  int A::*ap = &A::a,263      A::*bp = &A::b,264      A::*cp = &A::c,265      A::*dp = &A::d,266      A::*ep = &A::e,267      A::*fp = &A::f;268 269  clang_analyzer_eval(ap); // expected-warning{{TRUE}}270  clang_analyzer_eval(bp); // expected-warning{{TRUE}}271  clang_analyzer_eval(cp); // expected-warning{{TRUE}}272  clang_analyzer_eval(dp); // expected-warning{{TRUE}}273  clang_analyzer_eval(ep); // expected-warning{{TRUE}}274  clang_analyzer_eval(fp); // expected-warning{{TRUE}}275 276  A a;277  a.a = 1;278  a.b = 2;279  a.c = 3;280  a.d = 4;281  a.e = 5;282 283  clang_analyzer_eval(a.*ap == 1); // expected-warning{{TRUE}}284  clang_analyzer_eval(a.*bp == 2); // expected-warning{{TRUE}}285  clang_analyzer_eval(a.*cp == 3); // expected-warning{{TRUE}}286  clang_analyzer_eval(a.*dp == 4); // expected-warning{{TRUE}}287  clang_analyzer_eval(a.*ep == 5); // expected-warning{{TRUE}}288}289} // namespace testAnonymousMember290 291namespace testStaticCasting {292// From bug #48739293struct Grandfather {294  int field;295};296 297struct Father : public Grandfather {};298struct Son : public Father {};299 300void test() {301  int Son::*sf = &Son::field;302  Grandfather grandpa;303  grandpa.field = 10;304  int Grandfather::*gpf1 = static_cast<int Grandfather::*>(sf);305  int Grandfather::*gpf2 = static_cast<int Grandfather::*>(static_cast<int Father::*>(sf));306  int Grandfather::*gpf3 = static_cast<int Grandfather::*>(static_cast<int Son::*>(static_cast<int Father::*>(sf)));307  clang_analyzer_eval(grandpa.*gpf1 == 10); // expected-warning{{TRUE}}308  clang_analyzer_eval(grandpa.*gpf2 == 10); // expected-warning{{TRUE}}309  clang_analyzer_eval(grandpa.*gpf3 == 10); // expected-warning{{TRUE}}310}311} // namespace testStaticCasting312 313namespace D126198 {314class Base {};315class Derived : public Base {};316int foo(int Derived::*);317 318int test() {319  int Base::*p = nullptr;320  return foo(p); // no-crash321}322} // namespace D126198323