mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Fix alignment for uint128 to 16 with WASM targets.
- Incorrect assert in struct alignment checking #2841 - Packed structs sometimes not lowered as such.
This commit is contained in:
@@ -154,12 +154,13 @@ const bool FREEBSD = LIBC && OS_TYPE == FREEBSD;
|
||||
const bool NETBSD = LIBC && OS_TYPE == NETBSD;
|
||||
const bool BSD_FAMILY = env::FREEBSD || env::OPENBSD || env::NETBSD;
|
||||
const bool WASI = LIBC && OS_TYPE == WASI;
|
||||
const bool WASM = ARCH_TYPE == ArchType.WASM32 || ARCH_TYPE == ArchType.WASM64;
|
||||
const bool ANDROID = LIBC && OS_TYPE == ANDROID;
|
||||
const bool WASM_NOLIBC @builtin @deprecated("Use 'FREESTANDING_WASM' instead") = !LIBC && ARCH_TYPE == ArchType.WASM32 || ARCH_TYPE == ArchType.WASM64;
|
||||
const bool FREESTANDING_PE32 = NO_LIBC && OS_TYPE == WIN32;
|
||||
const bool FREESTANDING_MACHO = NO_LIBC && OS_TYPE == MACOS;
|
||||
const bool FREESTANDING_ELF = NO_LIBC && !env::FREESTANDING_PE32 && !env::FREESTANDING_MACHO && !env::FREESTANDING_WASM;
|
||||
const bool FREESTANDING_WASM = NO_LIBC && (ARCH_TYPE == ArchType.WASM32 || ARCH_TYPE == ArchType.WASM64);
|
||||
const bool FREESTANDING_WASM = NO_LIBC && WASM;
|
||||
const bool FREESTANDING = env::FREESTANDING_PE32 || env::FREESTANDING_MACHO || env::FREESTANDING_ELF || env::FREESTANDING_WASM;
|
||||
const bool ADDRESS_SANITIZER = $$ADDRESS_SANITIZER;
|
||||
const bool MEMORY_SANITIZER = $$MEMORY_SANITIZER;
|
||||
|
||||
@@ -7,7 +7,7 @@ import std::os::posix, std::os::win32;
|
||||
import std::math;
|
||||
|
||||
const MAX_MEMORY_ALIGNMENT = 0x1000_0000;
|
||||
const DEFAULT_MEM_ALIGNMENT = (void*.alignof) * 2;
|
||||
const DEFAULT_MEM_ALIGNMENT = env::WASM ? 16 : (void*.alignof) * 2;
|
||||
const ulong KB = 1024;
|
||||
const ulong MB = KB * 1024;
|
||||
const ulong GB = MB * 1024;
|
||||
|
||||
@@ -134,6 +134,9 @@
|
||||
- Lowering of optional in && was incorrect #2843
|
||||
- Resolving &X.b when X is a const incorrectly checked for runtime constness #2842
|
||||
- Alignment param on $$unaligned_* not checked for zero #2844
|
||||
- Fix alignment for uint128 to 16 with WASM targets.
|
||||
- Incorrect assert in struct alignment checking #2841
|
||||
- Packed structs sometimes not lowered as such.
|
||||
|
||||
### Stdlib changes
|
||||
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.
|
||||
|
||||
@@ -49,6 +49,7 @@ static inline LLVMTypeRef llvm_type_from_decl(GenContext *c, Decl *decl)
|
||||
vec_add(types, llvm_const_padding_type(c, decl->strukt.padding));
|
||||
}
|
||||
LLVMStructSetBody(type, types, vec_size(types), decl->is_packed);
|
||||
ASSERT_SPAN(decl, llvm_abi_size(c, type) == type_size(decl->type));
|
||||
return type;
|
||||
}
|
||||
case DECL_UNION:
|
||||
|
||||
@@ -679,7 +679,7 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl)
|
||||
}
|
||||
if (is_unaligned && size > offset)
|
||||
{
|
||||
ASSERT(!decl->strukt.padding);
|
||||
ASSERT(!decl->strukt.padding || decl->strukt.padding == size - offset);
|
||||
decl->strukt.padding = size - offset;
|
||||
}
|
||||
|
||||
@@ -703,7 +703,7 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl)
|
||||
}
|
||||
}
|
||||
|
||||
decl->is_packed = is_unaligned;
|
||||
decl->is_packed |= is_unaligned;
|
||||
// Strip padding if we are aligned.
|
||||
if (!decl->is_packed && is_naturally_aligned)
|
||||
{
|
||||
|
||||
@@ -1683,9 +1683,7 @@ static AlignData os_target_alignment_of_int(OsType os, ArchType arch, uint32_t b
|
||||
case ARCH_TYPE_PPC64:
|
||||
case ARCH_TYPE_PPC:
|
||||
case ARCH_TYPE_PPC64LE:
|
||||
case ARCH_TYPE_WASM64:
|
||||
case ARCH_TYPE_RISCV32:
|
||||
case ARCH_TYPE_WASM32:
|
||||
case ARCH_TYPE_XTENSA:
|
||||
return (AlignData) { MIN(64u, bits), MIN(64u, bits) };
|
||||
case ARCH_TYPE_X86_64:
|
||||
@@ -1694,6 +1692,8 @@ static AlignData os_target_alignment_of_int(OsType os, ArchType arch, uint32_t b
|
||||
#else
|
||||
FALLTHROUGH;
|
||||
#endif
|
||||
case ARCH_TYPE_WASM64:
|
||||
case ARCH_TYPE_WASM32:
|
||||
case ARCH_TYPE_RISCV64:
|
||||
return (AlignData) { bits, bits };
|
||||
case ARCH_TYPE_AARCH64:
|
||||
|
||||
@@ -58,7 +58,7 @@ fn int test5(ichar x)
|
||||
return y.foo + y.bar;
|
||||
}
|
||||
|
||||
// { i32, i16, i16 }
|
||||
// <{ i32, i16, i16 }>
|
||||
struct Foo6 @packed
|
||||
{
|
||||
int a;
|
||||
@@ -76,16 +76,15 @@ Foo6 foo6 = { 1, 2, 3 };
|
||||
%Foo3 = type <{ i8, i64, [7 x i8] }>
|
||||
%Foo4 = type <{ i8, i64 }>
|
||||
%Foo5 = type { i32, [12 x i8], i8, [15 x i8] }
|
||||
%Foo6 = type { i32, i16, i16 }
|
||||
%Foo6 = type <{ i32, i16, i16 }>
|
||||
|
||||
@struct2.foo1 = local_unnamed_addr global %Foo1 <{ i64 1, i8 2, [3 x i8] undef }>, align 4
|
||||
@struct2.foo2 = local_unnamed_addr global %Foo2 <{ i8 1, i64 2, [3 x i8] undef }>, align 4
|
||||
@struct2.foo3 = local_unnamed_addr global %Foo3 <{ i8 1, i64 2, [7 x i8] undef }>, align 8
|
||||
@struct2.foo4 = local_unnamed_addr global %Foo4 <{ i8 1, i64 2 }>, align 1
|
||||
@struct2.foo5 = local_unnamed_addr global %Foo5 { i32 1, [12 x i8] undef, i8 2, [15 x i8] undef }, align 16
|
||||
@struct2.foo6 = local_unnamed_addr global %Foo6 { i32 1, i16 2, i16 3 }, align 1
|
||||
@struct2.foo6 = local_unnamed_addr global %Foo6 <{ i32 1, i16 2, i16 3 }>, align 1
|
||||
|
||||
; Function Attrs:
|
||||
define i32 @struct2.test5(i8 signext %0) #0 {
|
||||
entry:
|
||||
%y = alloca %Foo5, align 16
|
||||
|
||||
@@ -36,7 +36,7 @@ fn void main()
|
||||
/* #expect: test.ll
|
||||
|
||||
%Client = type <{ i32, %MsgHeader, i16, [2 x i8], %"ElasticArray{ulong, 1}" }>
|
||||
%MsgHeader = type { i64 }
|
||||
%MsgHeader = type <{ i64 }>
|
||||
%"ElasticArray{ulong, 1}" = type { i64, [1 x i64] }
|
||||
|
||||
define void @test.main() #0 {
|
||||
|
||||
35
test/test_suite/struct/struct_packed.c3t
Normal file
35
test/test_suite/struct/struct_packed.c3t
Normal file
@@ -0,0 +1,35 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
struct Foo3 @align(8)
|
||||
{
|
||||
char foo;
|
||||
Foo6 bar;
|
||||
}
|
||||
struct Foo6 @packed
|
||||
{
|
||||
short c;
|
||||
}
|
||||
|
||||
fn int main()
|
||||
{
|
||||
Foo3 x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
%Foo3 = type <{ i8, %Foo6, [5 x i8] }>
|
||||
%Foo6 = type <{ i16 }>
|
||||
|
||||
@"$ct.test.Foo3" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
|
||||
@"$ct.test.Foo6" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 2, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8
|
||||
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%x = alloca %Foo3, align 8
|
||||
store i8 0, ptr %x, align 8
|
||||
%ptradd = getelementptr inbounds i8, ptr %x, i64 1
|
||||
store i16 0, ptr %ptradd, align 1
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user