diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2602,9 +2602,12 @@ } for (const auto *Field : RD->fields()) { - if (!Field->getType()->isReferenceType() && - !Context.hasUniqueObjectRepresentations(Field->getType())) - return llvm::None; + if (!Field->getType()->isReferenceType()) { + if (Field->isZeroSize(Context)) + continue; + else if (!Context.hasUniqueObjectRepresentations(Field->getType())) + return llvm::None; + } int64_t FieldSizeInBits = Context.toBits(Context.getTypeSizeInChars(Field->getType())); diff --git a/clang/test/SemaCXX/has_unique_object_reps_no_unique_addr.cpp b/clang/test/SemaCXX/has_unique_object_reps_no_unique_addr.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/has_unique_object_reps_no_unique_addr.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify -std=c++2a %s +// expected-no-diagnostics + +struct Empty {}; + +struct A { + [[no_unique_address]] Empty e; + char x; +}; + +static_assert(__has_unique_object_representations(A)); + +struct B { + char x; + [[no_unique_address]] Empty e; +}; + +static_assert(__has_unique_object_representations(B)); + +struct C { + char x; + [[no_unique_address]] Empty e1; + [[no_unique_address]] Empty e2; +}; + +static_assert(!__has_unique_object_representations(C));