leonardchan created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This may result in the entire union not being initialized. For example: union U { uint32_t x; uint64_t y; }; void func() { U u = {}; ... } Some might assume that `U u = {}` zero-initializes the whole union whereas only the bits that compose `U.x` are zero-inited. Oddly enough (mostly from what I've seen personally), this seems to only matter in the case we use `-ftrivial-auto-var-init=pattern` where llvm `undef`s are replaced with non-zero values. In any normal case, it seems that these `undef`s just get lowered to zeros. See: http://lists.llvm.org/pipermail/cfe-dev/2019-September/063383.html Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D67971 Files: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaInit.cpp Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ 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; } } Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ 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.
Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ 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; } } Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ 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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits