mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-03 19:32:35 +00:00
4d9fbd7ec4
The actual change here is a little more complicated than the summary above. What we want to do is have our generic inlining tests run under whatever mode is the default. However, there are some tests that depend on the presence of C++ inlining, which still has some rough edges. These tests have been explicitly marked as -analyzer-ipa=inlining in preparation for a new mode that limits inlining to C functions and blocks. This will be the default until the false positives for C++ have been brought down to manageable levels. llvm-svn: 162317
138 lines
2.4 KiB
C++
138 lines
2.4 KiB
C++
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
|
|
|
|
void clang_analyzer_eval(bool);
|
|
|
|
class A {
|
|
protected:
|
|
int x;
|
|
};
|
|
|
|
class B : public A {
|
|
public:
|
|
void f();
|
|
};
|
|
|
|
void B::f() {
|
|
x = 3;
|
|
}
|
|
|
|
|
|
class C : public B {
|
|
public:
|
|
void g() {
|
|
// This used to crash because we are upcasting through two bases.
|
|
x = 5;
|
|
}
|
|
};
|
|
|
|
|
|
namespace VirtualBaseClasses {
|
|
class A {
|
|
protected:
|
|
int x;
|
|
};
|
|
|
|
class B : public virtual A {
|
|
public:
|
|
int getX() { return x; }
|
|
};
|
|
|
|
class C : public virtual A {
|
|
public:
|
|
void setX() { x = 42; }
|
|
};
|
|
|
|
class D : public B, public C {};
|
|
class DV : virtual public B, public C {};
|
|
class DV2 : public B, virtual public C {};
|
|
|
|
void test() {
|
|
D d;
|
|
d.setX();
|
|
clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
|
|
|
|
DV dv;
|
|
dv.setX();
|
|
clang_analyzer_eval(dv.getX() == 42); // expected-warning{{TRUE}}
|
|
|
|
DV2 dv2;
|
|
dv2.setX();
|
|
clang_analyzer_eval(dv2.getX() == 42); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
|
|
// Make sure we're consistent about the offset of the A subobject within an
|
|
// Intermediate virtual base class.
|
|
class Padding1 { int unused; };
|
|
class Padding2 { int unused; };
|
|
class Intermediate : public Padding1, public A, public Padding2 {};
|
|
|
|
class BI : public virtual Intermediate {
|
|
public:
|
|
int getX() { return x; }
|
|
};
|
|
|
|
class CI : public virtual Intermediate {
|
|
public:
|
|
void setX() { x = 42; }
|
|
};
|
|
|
|
class DI : public BI, public CI {};
|
|
|
|
void testIntermediate() {
|
|
DI d;
|
|
d.setX();
|
|
clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
|
|
}
|
|
}
|
|
|
|
|
|
namespace DynamicVirtualUpcast {
|
|
class A {
|
|
public:
|
|
virtual ~A();
|
|
};
|
|
|
|
class B : virtual public A {};
|
|
class C : virtual public B {};
|
|
class D : virtual public C {};
|
|
|
|
bool testCast(A *a) {
|
|
return dynamic_cast<B*>(a) && dynamic_cast<C*>(a);
|
|
}
|
|
|
|
void test() {
|
|
D d;
|
|
clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
|
|
}
|
|
}
|
|
|
|
namespace DynamicMultipleInheritanceUpcast {
|
|
class B {
|
|
public:
|
|
virtual ~B();
|
|
};
|
|
class C {
|
|
public:
|
|
virtual ~C();
|
|
};
|
|
class D : public B, public C {};
|
|
|
|
bool testCast(B *a) {
|
|
return dynamic_cast<C*>(a);
|
|
}
|
|
|
|
void test() {
|
|
D d;
|
|
clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
|
|
class DV : virtual public B, virtual public C {};
|
|
|
|
void testVirtual() {
|
|
DV d;
|
|
clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
|
|
}
|
|
}
|