brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.3 KiB · ef30f97 Raw
478 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s2// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -DCONSTRUCTORS=1 -analyzer-config c++-inlining=constructors -verify %s3 4void clang_analyzer_eval(bool);5void clang_analyzer_checkInlined(bool);6 7class A {8protected:9  int x;10};11 12class B : public A {13public:14  void f();15};16 17void B::f() {18  x = 3;19}20 21 22class C : public B {23public:24  void g() {25    // This used to crash because we are upcasting through two bases.26    x = 5;27  }28};29 30 31namespace VirtualBaseClasses {32  class A {33  protected:34    int x;35  };36 37  class B : public virtual A {38  public:39    int getX() { return x; }40  };41 42  class C : public virtual A {43  public:44    void setX() { x = 42; }45  };46 47  class D : public B, public C {};48  class DV : virtual public B, public C {};49  class DV2 : public B, virtual public C {};50 51  void test() {52    D d;53    d.setX();54    clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}55 56    DV dv;57    dv.setX();58    clang_analyzer_eval(dv.getX() == 42); // expected-warning{{TRUE}}59 60    DV2 dv2;61    dv2.setX();62    clang_analyzer_eval(dv2.getX() == 42); // expected-warning{{TRUE}}63  }64 65 66  // Make sure we're consistent about the offset of the A subobject within an67  // Intermediate virtual base class.68  class Padding1 { int unused; };69  class Padding2 { int unused; };70  class Intermediate : public Padding1, public A, public Padding2 {};71 72  class BI : public virtual Intermediate {73  public:74    int getX() { return x; }75  };76 77  class CI : public virtual Intermediate {78  public:79    void setX() { x = 42; }80  };81 82  class DI : public BI, public CI {};83 84  void testIntermediate() {85    DI d;86    d.setX();87    clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}88  }89}90 91 92namespace DynamicVirtualUpcast {93  class A {94  public:95    virtual ~A();96  };97 98  class B : virtual public A {};99  class C : virtual public B {};100  class D : virtual public C {};101 102  bool testCast(A *a) {103    return dynamic_cast<B*>(a) && dynamic_cast<C*>(a);104  }105 106  void test() {107    D d;108    clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}109  }110}111 112namespace DynamicMultipleInheritanceUpcast {113  class B {114  public:115    virtual ~B();116  };117  class C {118  public:119    virtual ~C();120  };121  class D : public B, public C {};122 123  bool testCast(B *a) {124    return dynamic_cast<C*>(a);125  }126 127  void test() {128    D d;129    clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}130  }131 132 133  class DV : virtual public B, virtual public C {};134 135  void testVirtual() {136    DV d;137    clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}138  }139}140 141namespace LazyBindings {142  struct Base {143    int x;144  };145 146  struct Derived : public Base {147    int y;148  };149 150  struct DoubleDerived : public Derived {151    int z;152  };153 154  int getX(const Base &obj) {155    return obj.x;156  }157 158  int getY(const Derived &obj) {159    return obj.y;160  }161 162  void testDerived() {163    Derived d;164    d.x = 1;165    d.y = 2;166    clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}167    clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}168 169    Base b(d);170    clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}171 172    Derived d2(d);173    clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}174    clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}175  }176 177  void testDoubleDerived() {178    DoubleDerived d;179    d.x = 1;180    d.y = 2;181    clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}182    clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}183 184    Base b(d);185    clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}186 187    Derived d2(d);188    clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}189    clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}190 191    DoubleDerived d3(d);192    clang_analyzer_eval(getX(d3) == 1); // expected-warning{{TRUE}}193    clang_analyzer_eval(getY(d3) == 2); // expected-warning{{TRUE}}194  }195 196  namespace WithOffset {197    struct Offset {198      int padding;199    };200 201    struct OffsetDerived : private Offset, public Base {202      int y;203    };204 205    struct DoubleOffsetDerived : public OffsetDerived {206      int z;207    };208 209    int getY(const OffsetDerived &obj) {210      return obj.y;211    }212 213    void testDerived() {214      OffsetDerived d;215      d.x = 1;216      d.y = 2;217      clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}218      clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}219 220      Base b(d);221      clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}222 223      OffsetDerived d2(d);224      clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}225      clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}226    }227 228    void testDoubleDerived() {229      DoubleOffsetDerived d;230      d.x = 1;231      d.y = 2;232      clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}233      clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}234 235      Base b(d);236      clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}237 238      OffsetDerived d2(d);239      clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}240      clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}241 242      DoubleOffsetDerived d3(d);243      clang_analyzer_eval(getX(d3) == 1); // expected-warning{{TRUE}}244      clang_analyzer_eval(getY(d3) == 2); // expected-warning{{TRUE}}245    }246  }247 248  namespace WithVTable {249    struct DerivedVTBL : public Base {250      int y;251      virtual void method();252    };253 254    struct DoubleDerivedVTBL : public DerivedVTBL {255      int z;256    };257 258    int getY(const DerivedVTBL &obj) {259      return obj.y;260    }261 262    int getZ(const DoubleDerivedVTBL &obj) {263      return obj.z;264    }265 266    void testDerived() {267      DerivedVTBL d;268      d.x = 1;269      d.y = 2;270      clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}271      clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}272 273      Base b(d);274      clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}275 276#if CONSTRUCTORS277      DerivedVTBL d2(d);278      clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}279      clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}280#endif281    }282 283#if CONSTRUCTORS284    void testDoubleDerived() {285      DoubleDerivedVTBL d;286      d.x = 1;287      d.y = 2;288      d.z = 3;289      clang_analyzer_eval(getX(d) == 1); // expected-warning{{TRUE}}290      clang_analyzer_eval(getY(d) == 2); // expected-warning{{TRUE}}291      clang_analyzer_eval(getZ(d) == 3); // expected-warning{{TRUE}}292 293      Base b(d);294      clang_analyzer_eval(getX(b) == 1); // expected-warning{{TRUE}}295 296      DerivedVTBL d2(d);297      clang_analyzer_eval(getX(d2) == 1); // expected-warning{{TRUE}}298      clang_analyzer_eval(getY(d2) == 2); // expected-warning{{TRUE}}299 300      DoubleDerivedVTBL d3(d);301      clang_analyzer_eval(getX(d3) == 1); // expected-warning{{TRUE}}302      clang_analyzer_eval(getY(d3) == 2); // expected-warning{{TRUE}}303      clang_analyzer_eval(getZ(d3) == 3); // expected-warning{{TRUE}}304    }305#endif306  }307 308#if CONSTRUCTORS309  namespace Nested {310    struct NonTrivialCopy {311      int padding;312      NonTrivialCopy() {}313      NonTrivialCopy(const NonTrivialCopy &) {}314    };315 316    struct FullyDerived : private NonTrivialCopy, public Derived {317      int z;318    };319 320    struct Wrapper {321      FullyDerived d;322      int zz;323 324      Wrapper(const FullyDerived &d) : d(d), zz(0) {}325    };326 327    void test5() {328      Wrapper w((FullyDerived()));329      w.d.x = 1;330 331      Wrapper w2(w);332      clang_analyzer_eval(getX(w2.d) == 1); // expected-warning{{TRUE}}333    }334  }335#endif336}337 338namespace Redeclaration {339  class Base;340 341  class Base {342  public:343    virtual int foo();344    int get() { return value; }345 346    int value;347  };348 349  class Derived : public Base {350  public:351    virtual int bar();352  };353 354  void test(Derived d) {355    d.foo(); // don't crash356    d.bar(); // basic correctness check357 358    Base &b = d;359    b.foo(); // don't crash360 361    d.value = 42; // don't crash362    clang_analyzer_eval(d.get() == 42); // expected-warning{{TRUE}}363    clang_analyzer_eval(b.get() == 42); // expected-warning{{TRUE}}364  }365};366 367namespace PR15394 {368  namespace Original {369    class Base {370    public:371      virtual int f() = 0;372      int i;373    };374 375    class Derived1 : public Base {376    public:377      int j;378    };379 380    class Derived2 : public Derived1 {381    public:382      virtual int f() {383        clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}384        return i + j;385      }386    };387 388    void testXXX() {389      Derived1 *d1p = reinterpret_cast<Derived1*>(new Derived2);390      d1p->i = 1;391      d1p->j = 2;392      clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}}393    }394  }395 396  namespace VirtualInDerived {397    class Base {398    public:399      int i;400    };401 402    class Derived1 : public Base {403    public:404      virtual int f() = 0;405      int j;406    };407 408    class Derived2 : public Derived1 {409    public:410      virtual int f() {411        clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}412        return i + j;413      }414    };415 416    void test() {417      Derived1 *d1p = reinterpret_cast<Derived1*>(new Derived2);418      d1p->i = 1;419      d1p->j = 2;420      clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}}421    }422  }423 424  namespace NoCast {425    class Base {426    public:427      int i;428    };429 430    class Derived1 : public Base {431    public:432      virtual int f() = 0;433      int j;434    };435 436    class Derived2 : public Derived1 {437    public:438      virtual int f() {439        clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}440        return i + j;441      }442    };443 444    void test() {445      Derived1 *d1p = new Derived2;446      d1p->i = 1;447      d1p->j = 2;448      clang_analyzer_eval(d1p->f() == 3); // expected-warning{{TRUE}}449    }450  }451};452 453namespace Bug16309 {454  struct Incomplete;455 456  struct Base { virtual ~Base(); };457 458  struct Derived : public Base { int x; };459 460  void* f(Incomplete *i) {461    Base *b = reinterpret_cast<Base *>(i);462    // This used to crash because of the reinterpret_cast above.463    Derived *d = dynamic_cast<Derived *>(b);464    return d;465  }466 467  // And check that reinterpret+dynamic casts work correctly after the fix.468  void g() {469    Derived d;470    d.x = 47;471    Base *b = &d;472    Incomplete *i = reinterpret_cast<Incomplete *>(b);473    Base *b2 = reinterpret_cast<Base *>(i);474    Derived *d2 = dynamic_cast<Derived *>(b2);475    clang_analyzer_eval(d2->x == 47); // expected-warning{{TRUE}}476  }477}478