================
@@ -0,0 +1,134 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=alignment,null \
+// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-UBSAN
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK-NO-UBSAN
+
+// Test that EmitAggregateCopy emits null and alignment checks when sanitizers
+// are enabled for aggregate copy operations with pointers.
+
+struct alignas(16) AlignedStruct {
+ int a;
+ int b;
+ int c;
+ int d;
+};
+
+struct NormalStruct {
+ int x;
+ int y;
+ int z;
+};
+
+// Stack-to-stack copies are optimized away (compiler knows they're valid)
+// CHECK-UBSAN-LABEL: define {{.*}}void @_Z19test_aligned_structv()
+// CHECK-NO-UBSAN-LABEL: define {{.*}}void @_Z19test_aligned_structv()
+void test_aligned_struct() {
+ AlignedStruct src = {1, 2, 3, 4};
+ AlignedStruct dest;
+
+ // CHECK-UBSAN: call void @llvm.memcpy
+ // CHECK-NO-UBSAN: call void @llvm.memcpy
+
+ dest = src;
+}
+
+// CHECK-UBSAN-LABEL: define {{.*}}void @_Z18test_normal_structv()
+// CHECK-NO-UBSAN-LABEL: define {{.*}}void @_Z18test_normal_structv()
+void test_normal_struct() {
+ NormalStruct src = {10, 20, 30};
+ NormalStruct dest;
+
+ // CHECK-UBSAN: call void @llvm.memcpy
+ // CHECK-NO-UBSAN: call void @llvm.memcpy
+
+ dest = src;
+}
+
+// This is the key test - copying through pointers requires runtime checks
+// CHECK-UBSAN-LABEL: define {{.*}}void
@_Z19test_pointer_to_ptrP13AlignedStructS0_(
+// CHECK-NO-UBSAN-LABEL: define {{.*}}void
@_Z19test_pointer_to_ptrP13AlignedStructS0_(
+void test_pointer_to_ptr(AlignedStruct *src, AlignedStruct *dest) {
+ // CHECK-UBSAN: %[[SRC_LOAD:.*]] = load ptr, ptr %src.addr
+ // CHECK-UBSAN: %[[DEST_LOAD:.*]] = load ptr, ptr %dest.addr
+
+ // Check source pointer is non-null and aligned
+ // CHECK-UBSAN: %[[SRC_NONNULL:.*]] = icmp ne ptr %[[SRC_LOAD]], null
+ // CHECK-UBSAN: %[[SRC_INT:.*]] = ptrtoint ptr %[[SRC_LOAD]] to i64
+ // CHECK-UBSAN: %[[SRC_MASK:.*]] = and i64 %[[SRC_INT]], 15
+ // CHECK-UBSAN: %[[SRC_ALIGNED:.*]] = icmp eq i64 %[[SRC_MASK]], 0
+ // CHECK-UBSAN: %[[SRC_OK:.*]] = and i1 %[[SRC_NONNULL]], %[[SRC_ALIGNED]]
+ // CHECK-UBSAN: br i1 %[[SRC_OK]], label %cont, label %handler.type_mismatch
+
+ // CHECK-UBSAN: handler.type_mismatch:
+ // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1_abort
+ // CHECK-UBSAN: unreachable
+
+ // CHECK-UBSAN: cont:
+ // Check destination pointer is non-null and aligned
+ // CHECK-UBSAN: %[[DEST_NONNULL:.*]] = icmp ne ptr %[[DEST_LOAD]], null
+ // CHECK-UBSAN: %[[DEST_INT:.*]] = ptrtoint ptr %[[DEST_LOAD]] to i64
+ // CHECK-UBSAN: %[[DEST_MASK:.*]] = and i64 %[[DEST_INT]], 15
+ // CHECK-UBSAN: %[[DEST_ALIGNED:.*]] = icmp eq i64 %[[DEST_MASK]], 0
+ // CHECK-UBSAN: %[[DEST_OK:.*]] = and i1 %[[DEST_NONNULL]], %[[DEST_ALIGNED]]
+ // CHECK-UBSAN: br i1 %[[DEST_OK]], label %cont{{.*}}, label
%handler.type_mismatch
+
+ // CHECK-UBSAN: handler.type_mismatch{{.*}}:
+ // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1_abort
+ // CHECK-UBSAN: unreachable
+
+ // CHECK-UBSAN: cont{{.*}}:
----------------
vasu-the-sharma wrote:
Good point! I've updated the CHECK patterns to use FileCheck variables for
capturing and
matching labels dynamically.
https://github.com/llvm/llvm-project/pull/164548
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits