diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9898,4 +9898,7 @@ "__builtin_bit_cast %select{source|destination}0 type must be trivially copyable">; def err_bit_cast_type_size_mismatch : Error< "__builtin_bit_cast source size does not equal destination size (%0 vs %1)">; + +def warn_union_zero_init : Warning< + "zero-initializing union '%0' whose first non-static named data member '%1' is not the largest in the union will leave uninitialized bits in the rest of the union">; } // end of sema component. diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -2041,8 +2041,16 @@ CheckEmptyInitializable( InitializedEntity::InitializeMember(*Field, &Entity), IList->getEndLoc()); - if (StructuredList) + if (StructuredList) { StructuredList->setInitializedFieldInUnion(*Field); + + ASTContext &Ctx = SemaRef.Context; + unsigned UnionSize = Ctx.getTypeSize(Ctx.getRecordType(RD)); + unsigned FieldSize = Ctx.getTypeSize(Field->getType()); + if (UnionSize > FieldSize) + SemaRef.Diag(IList->getLBraceLoc(), diag::warn_union_zero_init) + << RD->getName() << Field->getName(); + } break; } }