[libcxx-commits] [clang] [libcxx] [clang] Add builtin to clear padding bytes (prework for P0528R3) (PR #75371)
Eli Friedman via libcxx-commits
libcxx-commits at lists.llvm.org
Fri May 1 11:32:39 PDT 2026
================
@@ -2698,6 +2701,299 @@ RValue CodeGenFunction::emitStdcFirstBit(const CallExpr *E, Intrinsic::ID IntID,
return RValue::get(Result);
}
+namespace {
+
+// PaddingClearer is a utility class that clears padding bits in a
+// c/c++ type. It traverses the type recursively, collecting occupied
+// bit intervals, and then compute the padding intervals.
+// In the end, it clears the padding bits by writing zeros
+// to the padding intervals bytes-by-bytes. If a byte only contains
+// some padding bits, it writes zeros to only those bits. This is
+// the case for bit-fields.
+struct PaddingClearer {
+ PaddingClearer(CodeGenFunction &F)
+ : CGF(F), CharWidth(CGF.getContext().getCharWidth()) {}
+
+ void run(Address Src, QualType Ty) {
+ OccuppiedIntervals.clear();
+ Stack.clear();
+
+ Stack.push_back(Data{0, Ty, true});
+ while (!Stack.empty()) {
+ auto Current = Stack.back();
+ Stack.pop_back();
+ Visit(Current);
+ }
+
+ MergeOccuppiedIntervals();
+ auto PaddingIntervals =
+ GetPaddingIntervals(CGF.getContext().getTypeSize(Ty));
+ for (const auto &Interval : PaddingIntervals) {
+ ClearPadding(Src, Interval);
+ }
+ }
+
+private:
+ struct BitInterval {
+ // [First, Last)
+ uint64_t First;
+ uint64_t Last;
+ };
+
+ struct Data {
+ uint64_t StartBitOffset;
+ QualType Ty;
+ bool VisitVirtualBase;
+ };
+
+ void Visit(const Data &D) {
+ if (auto *AT = dyn_cast<ConstantArrayType>(D.Ty)) {
+ VisitArray(AT, D.StartBitOffset);
+ return;
+ }
+
+ if (auto *Record = D.Ty->getAsRecordDecl()) {
+ VisitStruct(Record, D.StartBitOffset, D.VisitVirtualBase);
+ return;
+ }
+
+ if (D.Ty->isAtomicType()) {
+ auto Unwrapped = D;
+ Unwrapped.Ty = D.Ty.getAtomicUnqualifiedType();
+ Stack.push_back(Unwrapped);
+ return;
+ }
+
+ if (const auto *Complex = D.Ty->getAs<ComplexType>()) {
+ VisitComplex(Complex, D.StartBitOffset);
+ return;
+ }
+
+ auto *Type = CGF.ConvertTypeForMem(D.Ty);
+ auto SizeBit = CGF.CGM.getModule()
+ .getDataLayout()
+ .getTypeSizeInBits(Type)
----------------
efriedma-quic wrote:
I don't trust this use of getTypeSizeInBits. ConvertTypeForMem is designed for in-memory struct layout. I suspect this interacts badly with the way we lower large _BitInt values.
I think I'd prefer to just list out the scalar types we know have internal padding: _BitInt, and x86 long double.
https://github.com/llvm/llvm-project/pull/75371
More information about the libcxx-commits
mailing list