diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -914,6 +914,8 @@ } void addMemcpyableField(FieldDecl *F) { + if (F->isZeroSize(CGF.getContext())) + return; if (!FirstField) addInitialField(F); else diff --git a/clang/test/CodeGenCXX/no-unique-address-2.cpp b/clang/test/CodeGenCXX/no-unique-address-2.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/no-unique-address-2.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s + +struct TriviallyCopyable {}; + +struct NonTriviallyCopyable { + NonTriviallyCopyable() = default; + NonTriviallyCopyable(const NonTriviallyCopyable&) = default; + NonTriviallyCopyable(NonTriviallyCopyable &&) {} +}; + +struct Foo { + int i; + [[no_unique_address]] TriviallyCopyable m; + [[no_unique_address]] NonTriviallyCopyable n; +}; + +void call() { + Foo foo; + Foo foo2(static_cast(foo)); +} + +// The memcpy call should copy exact 4 bytes for member 'int i' +// CHECK: define {{.*}} void @_ZN3FooC2EOS_ +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.+}}, i8* {{.+}}, i64 4, i1 false) +// CHECK: call void @_ZN20NonTriviallyCopyableC2EOS_