Skip to content

Commit 23c58b5

Browse files
committed
Add test codegen test for attribute handling
1 parent f71107f commit 23c58b5

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

clang/test/C/C23/n3037_1.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2-
// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
2+
// RUN: %clang_cc1 -std=c23 -Wno-error=odr -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
33

44
// This tests the codegen behavior of redefined tag types to ensure the
55
// generated code looks reasonable.
@@ -46,3 +46,43 @@ enum E {
4646
One,
4747
Two
4848
};
49+
50+
// Ensure that ignoring the incompatibility due to attributes does not cause a
51+
// crash. Note, this is undefined behavior in Clang until we implement
52+
// attribute structural compatibility logic, so this is not intended to verify
53+
// any particular behavior beyond "don't crash."
54+
struct T {
55+
_Alignas(double) int x;
56+
};
57+
58+
// CHECK-LABEL: define dso_local i32 @foo(
59+
// CHECK-SAME: i32 [[T_COERCE:%.*]]) #[[ATTR0]] {
60+
// CHECK-NEXT: [[ENTRY:.*:]]
61+
// CHECK-NEXT: [[T:%.*]] = alloca [[STRUCT_T:%.*]], align 8
62+
// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[T]], i32 0, i32 0
63+
// CHECK-NEXT: store i32 [[T_COERCE]], ptr [[COERCE_DIVE]], align 8
64+
// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[T]], i32 0, i32 0
65+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X]], align 8
66+
// CHECK-NEXT: ret i32 [[TMP0]]
67+
//
68+
int foo(struct T t) {
69+
return t.x;
70+
}
71+
72+
struct T {
73+
int x;
74+
};
75+
76+
// CHECK-LABEL: define dso_local i32 @bar(
77+
// CHECK-SAME: i32 [[T_COERCE:%.*]]) #[[ATTR0]] {
78+
// CHECK-NEXT: [[ENTRY:.*:]]
79+
// CHECK-NEXT: [[T:%.*]] = alloca [[STRUCT_T:%.*]], align 8
80+
// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[T]], i32 0, i32 0
81+
// CHECK-NEXT: store i32 [[T_COERCE]], ptr [[COERCE_DIVE]], align 8
82+
// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[T]], i32 0, i32 0
83+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X]], align 8
84+
// CHECK-NEXT: ret i32 [[TMP0]]
85+
//
86+
int bar(struct T t) {
87+
return t.x;
88+
}

0 commit comments

Comments
 (0)