forked from OSchip/llvm-project
Add tests for non-virtual call checking.
Differential Revision: http://reviews.llvm.org/D8792 llvm-svn: 233876
This commit is contained in:
parent
1a7488afaa
commit
7881648a4e
|
@ -0,0 +1,8 @@
|
||||||
|
The tests in this directory use a common convention for exercising the
|
||||||
|
functionality associated with bit sets of different sizes. When certain
|
||||||
|
macros are defined the tests instantiate classes that force the bit sets
|
||||||
|
to be of certain sizes.
|
||||||
|
|
||||||
|
- B32 forces 32-bit bit sets.
|
||||||
|
- B64 forces 64-bit bit sets.
|
||||||
|
- BM forces memory bit sets.
|
|
@ -0,0 +1,65 @@
|
||||||
|
// RUN: %clangxx_cfi -o %t %s
|
||||||
|
// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
|
||||||
|
|
||||||
|
// RUN: %clangxx_cfi -DB32 -o %t %s
|
||||||
|
// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
|
||||||
|
|
||||||
|
// RUN: %clangxx_cfi -DB64 -o %t %s
|
||||||
|
// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
|
||||||
|
|
||||||
|
// RUN: %clangxx_cfi -DBM -o %t %s
|
||||||
|
// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
|
||||||
|
|
||||||
|
// RUN: %clangxx -o %t %s
|
||||||
|
// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
|
||||||
|
|
||||||
|
// Tests that the CFI mechanism crashes the program when making a non-virtual
|
||||||
|
// call to an object of the wrong class, by casting a pointer to such an object
|
||||||
|
// and attempting to make a call through it.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
virtual void f();
|
||||||
|
};
|
||||||
|
|
||||||
|
void A::f() {}
|
||||||
|
|
||||||
|
struct B {
|
||||||
|
void f();
|
||||||
|
virtual void g();
|
||||||
|
};
|
||||||
|
|
||||||
|
void B::f() {}
|
||||||
|
void B::g() {}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#ifdef B32
|
||||||
|
break_optimization(new Deriver<B, 0>);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef B64
|
||||||
|
break_optimization(new Deriver<B, 0>);
|
||||||
|
break_optimization(new Deriver<B, 1>);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BM
|
||||||
|
break_optimization(new Deriver<B, 0>);
|
||||||
|
break_optimization(new Deriver<B, 1>);
|
||||||
|
break_optimization(new Deriver<B, 2>);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
A *a = new A;
|
||||||
|
break_optimization(a);
|
||||||
|
|
||||||
|
// CFI: 1
|
||||||
|
// NCFI: 1
|
||||||
|
fprintf(stderr, "1\n");
|
||||||
|
|
||||||
|
((B *)a)->f(); // UB here
|
||||||
|
|
||||||
|
// CFI-NOT: 2
|
||||||
|
// NCFI: 2
|
||||||
|
fprintf(stderr, "2\n");
|
||||||
|
}
|
|
@ -3,95 +3,119 @@
|
||||||
|
|
||||||
// Tests that the CFI mechanism does not crash the program when making various
|
// Tests that the CFI mechanism does not crash the program when making various
|
||||||
// kinds of valid calls involving classes with various different linkages and
|
// kinds of valid calls involving classes with various different linkages and
|
||||||
// types of inheritance.
|
// types of inheritance, and both virtual and non-virtual member functions.
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
struct A {
|
struct A {
|
||||||
virtual void f();
|
virtual void f();
|
||||||
|
void g();
|
||||||
};
|
};
|
||||||
|
|
||||||
void A::f() {}
|
void A::f() {}
|
||||||
|
void A::g() {}
|
||||||
|
|
||||||
struct A2 : A {
|
struct A2 : A {
|
||||||
virtual void f();
|
virtual void f();
|
||||||
|
void g();
|
||||||
};
|
};
|
||||||
|
|
||||||
void A2::f() {}
|
void A2::f() {}
|
||||||
|
void A2::g() {}
|
||||||
|
|
||||||
struct B {
|
struct B {
|
||||||
virtual void f() {}
|
virtual void f() {}
|
||||||
|
void g() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct B2 : B {
|
struct B2 : B {
|
||||||
virtual void f() {}
|
virtual void f() {}
|
||||||
|
void g() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct C {
|
struct C {
|
||||||
virtual void f();
|
virtual void f();
|
||||||
|
void g();
|
||||||
};
|
};
|
||||||
|
|
||||||
void C::f() {}
|
void C::f() {}
|
||||||
|
void C::g() {}
|
||||||
|
|
||||||
struct C2 : C {
|
struct C2 : C {
|
||||||
virtual void f();
|
virtual void f();
|
||||||
|
void g();
|
||||||
};
|
};
|
||||||
|
|
||||||
void C2::f() {}
|
void C2::f() {}
|
||||||
|
void C2::g() {}
|
||||||
|
|
||||||
struct D {
|
struct D {
|
||||||
virtual void f() {}
|
virtual void f() {}
|
||||||
|
void g() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct D2 : D {
|
struct D2 : D {
|
||||||
virtual void f() {}
|
virtual void f() {}
|
||||||
|
void g() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct E {
|
struct E {
|
||||||
virtual void f() {}
|
virtual void f() {}
|
||||||
|
void g() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct E2 : virtual E {
|
struct E2 : virtual E {
|
||||||
virtual void f() {}
|
virtual void f() {}
|
||||||
|
void g() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
A *a = new A;
|
A *a = new A;
|
||||||
break_optimization(a);
|
break_optimization(a);
|
||||||
a->f();
|
a->f();
|
||||||
|
a->g();
|
||||||
a = new A2;
|
a = new A2;
|
||||||
break_optimization(a);
|
break_optimization(a);
|
||||||
a->f();
|
a->f();
|
||||||
|
a->g();
|
||||||
|
|
||||||
B *b = new B;
|
B *b = new B;
|
||||||
break_optimization(b);
|
break_optimization(b);
|
||||||
b->f();
|
b->f();
|
||||||
|
b->g();
|
||||||
b = new B2;
|
b = new B2;
|
||||||
break_optimization(b);
|
break_optimization(b);
|
||||||
b->f();
|
b->f();
|
||||||
|
b->g();
|
||||||
|
|
||||||
C *c = new C;
|
C *c = new C;
|
||||||
break_optimization(c);
|
break_optimization(c);
|
||||||
c->f();
|
c->f();
|
||||||
|
c->g();
|
||||||
c = new C2;
|
c = new C2;
|
||||||
break_optimization(c);
|
break_optimization(c);
|
||||||
c->f();
|
c->f();
|
||||||
|
c->g();
|
||||||
|
|
||||||
D *d = new D;
|
D *d = new D;
|
||||||
break_optimization(d);
|
break_optimization(d);
|
||||||
d->f();
|
d->f();
|
||||||
|
d->g();
|
||||||
d = new D2;
|
d = new D2;
|
||||||
break_optimization(d);
|
break_optimization(d);
|
||||||
d->f();
|
d->f();
|
||||||
|
d->g();
|
||||||
|
|
||||||
E *e = new E;
|
E *e = new E;
|
||||||
break_optimization(e);
|
break_optimization(e);
|
||||||
e->f();
|
e->f();
|
||||||
|
e->g();
|
||||||
e = new E2;
|
e = new E2;
|
||||||
break_optimization(e);
|
break_optimization(e);
|
||||||
e->f();
|
e->f();
|
||||||
|
e->g();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue