void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);
class A {
public:
~A() {
int *x = 0;
*x = 3; }
};
int main() {
A a;
}
typedef __typeof(sizeof(int)) size_t;
void *malloc(size_t);
void free(void *);
class SmartPointer {
void *X;
public:
SmartPointer(void *x) : X(x) {}
~SmartPointer() {
free(X);
}
};
void testSmartPointer() {
char *mem = (char*)malloc(4);
{
SmartPointer Deleter(mem);
}
*mem = 0; }
void doSomething();
void testSmartPointer2() {
char *mem = (char*)malloc(4);
{
SmartPointer Deleter(mem);
doSomething();
}
*mem = 0; }
class Subclass : public SmartPointer {
public:
Subclass(void *x) : SmartPointer(x) {}
};
void testSubclassSmartPointer() {
char *mem = (char*)malloc(4);
{
Subclass Deleter(mem);
doSomething();
}
*mem = 0; }
class MultipleInheritance : public Subclass, public SmartPointer {
public:
MultipleInheritance(void *a, void *b) : Subclass(a), SmartPointer(b) {}
};
void testMultipleInheritance1() {
char *mem = (char*)malloc(4);
{
MultipleInheritance Deleter(mem, 0);
doSomething();
}
*mem = 0; }
void testMultipleInheritance2() {
char *mem = (char*)malloc(4);
{
MultipleInheritance Deleter(0, mem);
doSomething();
}
*mem = 0; }
void testMultipleInheritance3() {
char *mem = (char*)malloc(4);
{
MultipleInheritance Deleter(mem, mem);
doSomething();
}
}
class SmartPointerMember {
SmartPointer P;
public:
SmartPointerMember(void *x) : P(x) {}
};
void testSmartPointerMember() {
char *mem = (char*)malloc(4);
{
SmartPointerMember Deleter(mem);
doSomething();
}
*mem = 0; }
struct IntWrapper {
IntWrapper() : x(0) {}
~IntWrapper();
int *x;
};
void testArrayInvalidation() {
int i = 42;
int j = 42;
{
IntWrapper arr[2];
clang_analyzer_eval(arr[0].x == 0); clang_analyzer_eval(arr[1].x == 0);
arr[0].x = &i;
arr[1].x = &j;
clang_analyzer_eval(*arr[0].x == 42); clang_analyzer_eval(*arr[1].x == 42); }
clang_analyzer_eval(i == 42); clang_analyzer_eval(j == 42); }
struct DefaultArg {
DefaultArg(int x = 0) {}
~DefaultArg();
};
struct InheritsDefaultArg : DefaultArg {
InheritsDefaultArg() {}
virtual ~InheritsDefaultArg();
};
void testDefaultArg() {
InheritsDefaultArg a;
*(char *)0 = 1; }
namespace DestructorVirtualCalls {
class A {
public:
int *out1, *out2, *out3;
virtual int get() { return 1; }
~A() {
*out1 = get();
}
};
class B : public A {
public:
virtual int get() { return 2; }
~B() {
*out2 = get();
}
};
class C : public B {
public:
virtual int get() { return 3; }
~C() {
*out3 = get();
}
};
void test() {
int a, b, c;
{
C obj;
clang_analyzer_eval(obj.get() == 3);
A *base = &obj;
clang_analyzer_eval(base->get() == 3);
obj.out1 = &a;
obj.out2 = &b;
obj.out3 = &c;
}
clang_analyzer_eval(a == 1); clang_analyzer_eval(b == 2); clang_analyzer_eval(c == 3); }
}
namespace DestructorsShouldNotAffectReturnValues {
class Dtor {
public:
~Dtor() {
clang_analyzer_checkInlined(true); }
};
void *allocate() {
Dtor d;
return malloc(4); }
void test() {
void *p = allocate();
free(p); }
}
namespace MultipleInheritanceVirtualDtors {
class VirtualDtor {
protected:
virtual ~VirtualDtor() {
clang_analyzer_checkInlined(true); }
};
class NonVirtualDtor {
protected:
~NonVirtualDtor() {
clang_analyzer_checkInlined(true); }
};
class SubclassA : public VirtualDtor, public NonVirtualDtor {
public:
virtual ~SubclassA() {}
};
class SubclassB : public NonVirtualDtor, public VirtualDtor {
public:
virtual ~SubclassB() {}
};
void test() {
SubclassA a;
SubclassB b;
}
}
namespace ExplicitDestructorCall {
class VirtualDtor {
public:
virtual ~VirtualDtor() {
clang_analyzer_checkInlined(true); }
};
class Subclass : public VirtualDtor {
public:
virtual ~Subclass() {
clang_analyzer_checkInlined(false); }
};
void destroy(Subclass *obj) {
obj->VirtualDtor::~VirtualDtor();
}
}