Index: compiler-rt/test/asan/TestCases/pass-object-byval.cc =================================================================== --- /dev/null +++ compiler-rt/test/asan/TestCases/pass-object-byval.cc @@ -0,0 +1,36 @@ +// Verify that objects passed by value get red zones and that the copy +// constructor is called. +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s --implicit-check-not \ +// RUN: Assertion{{.*}}failed +#include + +class A { + public: + A() : me(this) {} + A(const A &other) : me(this) { + for (int i = 0; i < 8; ++i) a[i] = other.a[i]; + } + + int a[8]; + A *me; +}; + +int bar(A *a) { + int *volatile ptr = &a->a[0]; + return *(ptr - 1); +} + +void foo(A a) { + assert(a.me == &a); + bar(&a); +} + +int main() { + A a; + foo(a); +} + +// CHECK: ERROR: AddressSanitizer: stack-buffer-overflow +// CHECK: READ of size 4 at +// CHECK: is located in stack of thread Index: compiler-rt/test/asan/TestCases/pass-struct-byval-uar.cc =================================================================== --- /dev/null +++ compiler-rt/test/asan/TestCases/pass-struct-byval-uar.cc @@ -0,0 +1,38 @@ +// Test that use-after-return works with arguments passed by value. +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-NO-UAR %s +// RUN: not %env_asan_opts=detect_stack_use_after_return=1 %run %t 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-UAR %s +// +// On several architectures, the IR does not use byval arguments for foo() and +// instead creates a copy in main() and gives foo() a pointer to the copy. In +// that case, ASAN has nothing to poison on return from foo() and will not +// detect the UAR. +// REQUIRES: x86_64-target-arch, linux, not-android + +#include + +struct A { + int a[8]; +}; + +A *foo(A a) { + return &a; +} + +int main() { + A *a = foo(A()); + a->a[0] = 7; + std::fprintf(stderr, "\n"); // Ensures some output is generated for FileCheck + // to verify in the case where UAR is not + // detected. +} + +// CHECK-NO-UAR-NOT: ERROR: AddressSanitizer: stack-use-after-return +// CHECK-NO-UAR-NOT: WRITE of size 4 at +// CHECK-NO-UAR-NOT: Memory access at offset {{[0-9]+}} is inside this variable +// +// CHECK-UAR: ERROR: AddressSanitizer: stack-use-after-return +// CHECK-UAR: WRITE of size 4 at +// CHECK-UAR: Memory access at offset {{[0-9]+}} is inside this variable Index: compiler-rt/test/asan/TestCases/pass-struct-byval.cc =================================================================== --- /dev/null +++ compiler-rt/test/asan/TestCases/pass-struct-byval.cc @@ -0,0 +1,23 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s + +struct A { + int a[8]; +}; + +int bar(A *a) { + int *volatile ptr = &a->a[0]; + return *(ptr - 1); +} + +void foo(A a) { + bar(&a); +} + +int main() { + foo(A()); +} + +// CHECK: ERROR: AddressSanitizer: stack-buffer-underflow +// CHECK: READ of size 4 at +// CHECK: is located in stack of thread