forked from OSchip/llvm-project
136 lines
4.3 KiB
C++
136 lines
4.3 KiB
C++
// RUN: %clangxx_cfi -o %t %s
|
|
// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
|
|
|
|
// RUN: %clangxx_cfi -DB32 -o %t %s
|
|
// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
|
|
|
|
// RUN: %clangxx_cfi -DB64 -o %t %s
|
|
// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
|
|
|
|
// RUN: %clangxx_cfi -DBM -o %t %s
|
|
// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
|
|
|
|
// RUN: %clangxx_cfi -fsanitize=cfi-cast-strict -o %t %s
|
|
// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t d 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t e 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t f 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
// RUN: not --crash %t h 2>&1 | FileCheck --check-prefix=FAIL %s
|
|
|
|
// RUN: %clangxx -o %t %s
|
|
// RUN: %t a 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t b 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t c 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t g 2>&1 | FileCheck --check-prefix=PASS %s
|
|
// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
|
|
|
|
// Tests that the CFI enforcement detects bad casts.
|
|
|
|
#include <stdio.h>
|
|
#include "utils.h"
|
|
|
|
struct A {
|
|
virtual void f();
|
|
};
|
|
|
|
void A::f() {}
|
|
|
|
struct B : A {
|
|
virtual void f();
|
|
};
|
|
|
|
void B::f() {}
|
|
|
|
struct C : A {
|
|
};
|
|
|
|
int main(int argc, char **argv) {
|
|
#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
|
|
|
|
B *b = new B;
|
|
break_optimization(b);
|
|
|
|
// FAIL: 1
|
|
// PASS: 1
|
|
fprintf(stderr, "1\n");
|
|
|
|
A a;
|
|
switch (argv[1][0]) {
|
|
case 'a':
|
|
static_cast<B *>(&a); // UB
|
|
break;
|
|
case 'b':
|
|
static_cast<B &>(a); // UB
|
|
break;
|
|
case 'c':
|
|
static_cast<B &&>(a); // UB
|
|
break;
|
|
case 'd':
|
|
static_cast<C *>(&a); // UB, strict only
|
|
break;
|
|
case 'e':
|
|
static_cast<C &>(a); // UB, strict only
|
|
break;
|
|
case 'f':
|
|
static_cast<C &&>(a); // UB, strict only
|
|
break;
|
|
case 'g':
|
|
static_cast<B *>(static_cast<void *>(&a)); // Non-UB bad cast
|
|
break;
|
|
case 'h':
|
|
static_cast<C *>(static_cast<void *>(&a)); // Non-UB bad cast, strict only
|
|
break;
|
|
}
|
|
|
|
// FAIL-NOT: 2
|
|
// PASS: 2
|
|
fprintf(stderr, "2\n");
|
|
}
|