diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp index 7483bf6d6d1e8e..bc508a99da9ced 100644 --- a/clang/lib/CodeGen/Targets/LoongArch.cpp +++ b/clang/lib/CodeGen/Targets/LoongArch.cpp @@ -308,12 +308,14 @@ ABIArgInfo LoongArchABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, CGCXXABI::RAA_DirectInMemory); } - // Ignore empty structs/unions. - if (isEmptyRecord(getContext(), Ty, true)) - return ABIArgInfo::getIgnore(); - uint64_t Size = getContext().getTypeSize(Ty); + // Ignore empty struct or union whose size is zero, e.g. `struct { }` in C or + // `struct { int a[0]; }` in C++. In C++, `struct { }` is empty but it's size + // is 1 byte and g++ doesn't ignore it; clang++ matches this behaviour. + if (isEmptyRecord(getContext(), Ty, true) && Size == 0) + return ABIArgInfo::getIgnore(); + // Pass floating point values via FARs if possible. if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() && FRLen >= Size && FARsLeft) { diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c index d0daafac336ec0..281b7b15841a99 100644 --- a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c +++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c @@ -93,7 +93,7 @@ struct s9 test_s9(struct s9 a) { } // CHECK-C: define{{.*}} void @test_s10() -// CHECK-CXX: define{{.*}} void @_Z8test_s103s10() +// CHECK-CXX: define{{.*}} i64 @_Z8test_s103s10(i64 {{.*}}) struct s10 { }; struct s10 test_s10(struct s10 a) { return a; @@ -128,14 +128,14 @@ struct s14 test_s14(struct s14 a) { } // CHECK-C: define{{.*}} void @test_s15() -// CHECK-CXX: define{{.*}} void @_Z8test_s153s15() +// CHECK-CXX: define{{.*}} i64 @_Z8test_s153s15(i64 {{.*}}) struct s15 { int : 0; }; struct s15 test_s15(struct s15 a) { return a; } -// CHECK-C: define{{.*}} void @test_s16() -// CHECK-CXX: define{{.*}} void @_Z8test_s163s16() +// CHECK-C: define{{.*}} i64 @test_s16(i64 {{.*}}) +// CHECK-CXX: define{{.*}} i64 @_Z8test_s163s16(i64 {{.*}}) struct s16 { int : 1; }; struct s16 test_s16(struct s16 a) { return a;