Index: test/asan/TestCases/pass-object-byval.cc =================================================================== --- /dev/null +++ test/asan/TestCases/pass-object-byval.cc @@ -0,0 +1,40 @@ +// Verify that objects passed by value get red zones. +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-REDZONE %s +// +// Verify that objects are passed via pointer-to-copy and not via byval args. +// Otherwise we would have issues with the self-referential pointer "me" in +// class A below when ASan does a memcpy on the byval arg. +// RUN: %clangxx_asan %s -emit-llvm -S -o %t.ll +// RUN: cat %t.ll | FileCheck --check-prefix=CHECK-BYVAL %s +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 *ptr = &a->a[0]; + return *((int *) (ptr - 1)); +} + +void foo(A a) { + bar(&a); +} + +int main() { + A a; + foo(a); +} + +// CHECK-REDZONE: ERROR: AddressSanitizer: stack-buffer-overflow +// CHECK-REDZONE: READ of size 4 at +// CHECK-REDZONE: is located in stack of thread + +// CHECK-BYVAL: define void @_Z3foo1A(%class.A* %a) + Index: test/asan/TestCases/pass-struct-byval.cc =================================================================== --- /dev/null +++ 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 *ptr = &a->a[0]; + return *((int *) (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