Index: test/Instrumentation/AddressSanitizer/OptKnownBounds/struct-byval.ll |
diff --git a/test/Instrumentation/AddressSanitizer/OptKnownBounds/struct-byval.ll b/test/Instrumentation/AddressSanitizer/OptKnownBounds/struct-byval.ll |
new file mode 100644 |
index 0000000000000000000000000000000000000000..23dc540ce188abca63145775a5254b9a0f13aee5 |
--- /dev/null |
+++ b/test/Instrumentation/AddressSanitizer/OptKnownBounds/struct-byval.ll |
@@ -0,0 +1,37 @@ |
+; Valid access to a part of a byval argument. |
+ |
+; RUN: opt < %s -asan -S -asan-opt=1 -asan-opt-known-bounds=1 | FileCheck %s -check-prefix=OPT1 |
+; RUN: opt < %s -asan -S -asan-opt=0 | FileCheck %s -check-prefix=OPT0 |
+ |
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" |
+target triple = "x86_64-unknown-linux-gnu" |
+ |
+%struct.state_type = type { i64, [50 x i32] } |
+ |
+define i32 @_Z7example10state_type(%struct.state_type* nocapture byval align 8 %state) address_safety nounwind uwtable readonly { |
+entry: |
+ %size = getelementptr inbounds %struct.state_type* %state, i64 0, i32 0 |
+ %0 = load i64* %size, align 8 |
+ %conv = trunc i64 %0 to i32 |
+ ret i32 %conv |
+} |
+ |
+; OPT1: @_Z7example10state_type |
+; OPT1-NOT: call void @__asan_report_ |
+; OPT1: @asan.module_ctor |
+ |
+; OPT0: @_Z7example10state_type |
+; OPT0: call void @__asan_report_ |
+; OPT0-NOT: call void @__asan_report_ |
+; OPT0: @asan.module_ctor |
+ |
+; C++-example: #include <cstring> |
+; C++-example: |
+; C++-example: struct state_type { |
+; C++-example: size_t size; |
+; C++-example: int array[50]; |
+; C++-example: }; |
+; C++-example: |
+; C++-example: int example(state_type state) { |
+; C++-example: return state.size; // ok because state has the byval attribute |
+; C++-example: } |