@@ -2562,6 +2562,14 @@ static RValue EmitHipStdParUnsupportedBuiltin(CodeGenFunction *CGF,
25622562
25632563namespace {
25642564
2565+
2566+ // PaddingClearer is a utility class that clears padding bits in a
2567+ // c++ type. It traverses the type recursively, collecting occupied
2568+ // bit intervals, and then compute the padding intervals.
2569+ // In the end, it clears the padding bits by writing zeros
2570+ // to the padding intervals bytes-by-bytes. If a byte only contains
2571+ // some padding bits, it writes zeros to only those bits. This is
2572+ // the case for bit-fields.
25652573struct PaddingClearer {
25662574 PaddingClearer (CodeGenFunction &F)
25672575 : CGF(F), CharWidth(CGF.getContext().getCharWidth()) {}
@@ -2572,8 +2580,8 @@ struct PaddingClearer {
25722580
25732581 Queue.push_back (Data{0 , Ty, true });
25742582 while (!Queue.empty ()) {
2575- auto Current = Queue.front ();
2576- Queue.pop_front ();
2583+ auto Current = Queue.back ();
2584+ Queue.pop_back ();
25772585 Visit (Current);
25782586 }
25792587
@@ -2655,7 +2663,7 @@ struct PaddingClearer {
26552663
26562664 Queue.push_back (
26572665 Data{StartBitOffset + ArrIndex * Offset.getQuantity () * CharWidth,
2658- ElementQualType, true });
2666+ ElementQualType, /* VisitVirtualBase */ true });
26592667 }
26602668 }
26612669
@@ -2688,8 +2696,8 @@ struct PaddingClearer {
26882696
26892697 llvm::dbgs () << " visiting base at offset " << StartBitOffset << " + "
26902698 << BaseOffset * CharWidth << ' \n ' ;
2691- Queue.push_back (
2692- Data{StartBitOffset + BaseOffset * CharWidth, Base.getType (), false });
2699+ Queue.push_back (Data{StartBitOffset + BaseOffset * CharWidth,
2700+ Base.getType (), /* VisitVirtualBase */ false });
26932701 };
26942702
26952703 for (auto Base : R->bases ()) {
@@ -2718,8 +2726,8 @@ struct PaddingClearer {
27182726 StartBitOffset + FieldOffset +
27192727 Field->getBitWidthValue ()});
27202728 } else {
2721- Queue.push_back (
2722- Data{StartBitOffset + FieldOffset, Field-> getType (), true });
2729+ Queue.push_back (Data{StartBitOffset + FieldOffset, Field-> getType (),
2730+ /* VisitVirtualBase */ true });
27232731 }
27242732 }
27252733 }
@@ -2734,9 +2742,10 @@ struct PaddingClearer {
27342742 << StartBitOffset << " Img from "
27352743 << StartBitOffset + ImgOffset.getQuantity () * CharWidth
27362744 << " \n " ;
2737- Queue.push_back (Data{StartBitOffset, ElementQualType, true });
2745+ Queue.push_back (
2746+ Data{StartBitOffset, ElementQualType, /* VisitVirtualBase*/ true });
27382747 Queue.push_back (Data{StartBitOffset + ImgOffset.getQuantity () * CharWidth,
2739- ElementQualType, true });
2748+ ElementQualType, /* VisitVirtualBase */ true });
27402749 }
27412750
27422751 void MergeOccuppiedIntervals () {
@@ -5078,12 +5087,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
50785087 return RValue::get (Ptr);
50795088 }
50805089 case Builtin::BI__builtin_clear_padding: {
5081- const Expr *Op = E->getArg (0 );
5082- Value *Address = EmitScalarExpr (Op);
5083- auto PointeeTy = Op->getType ()->getPointeeType ();
5090+ Address Src = EmitPointerWithAlignment (E->getArg (0 ));
5091+ auto PointeeTy = E->getArg (0 )->getType ()->getPointeeType ();
50845092 PaddingClearer clearer{*this };
5085- clearer.run (Address, PointeeTy);
5086- // RecursivelyClearPadding(*this, Address, PointeeTy);
5093+ clearer.run (Src.getBasePointer (), PointeeTy);
50875094 return RValue::get (nullptr );
50885095 }
50895096 case Builtin::BI__sync_fetch_and_add:
0 commit comments