@@ -2600,6 +2600,14 @@ static RValue EmitHipStdParUnsupportedBuiltin(CodeGenFunction *CGF,
26002600
26012601namespace {
26022602
2603+
2604+ // PaddingClearer is a utility class that clears padding bits in a
2605+ // c++ type. It traverses the type recursively, collecting occupied
2606+ // bit intervals, and then compute the padding intervals.
2607+ // In the end, it clears the padding bits by writing zeros
2608+ // to the padding intervals bytes-by-bytes. If a byte only contains
2609+ // some padding bits, it writes zeros to only those bits. This is
2610+ // the case for bit-fields.
26032611struct PaddingClearer {
26042612 PaddingClearer (CodeGenFunction &F)
26052613 : CGF(F), CharWidth(CGF.getContext().getCharWidth()) {}
@@ -2610,8 +2618,8 @@ struct PaddingClearer {
26102618
26112619 Queue.push_back (Data{0 , Ty, true });
26122620 while (!Queue.empty ()) {
2613- auto Current = Queue.front ();
2614- Queue.pop_front ();
2621+ auto Current = Queue.back ();
2622+ Queue.pop_back ();
26152623 Visit (Current);
26162624 }
26172625
@@ -2693,7 +2701,7 @@ struct PaddingClearer {
26932701
26942702 Queue.push_back (
26952703 Data{StartBitOffset + ArrIndex * Offset.getQuantity () * CharWidth,
2696- ElementQualType, true });
2704+ ElementQualType, /* VisitVirtualBase */ true });
26972705 }
26982706 }
26992707
@@ -2726,8 +2734,8 @@ struct PaddingClearer {
27262734
27272735 llvm::dbgs () << " visiting base at offset " << StartBitOffset << " + "
27282736 << BaseOffset * CharWidth << ' \n ' ;
2729- Queue.push_back (
2730- Data{StartBitOffset + BaseOffset * CharWidth, Base.getType (), false });
2737+ Queue.push_back (Data{StartBitOffset + BaseOffset * CharWidth,
2738+ Base.getType (), /* VisitVirtualBase */ false });
27312739 };
27322740
27332741 for (auto Base : R->bases ()) {
@@ -2756,8 +2764,8 @@ struct PaddingClearer {
27562764 StartBitOffset + FieldOffset +
27572765 Field->getBitWidthValue ()});
27582766 } else {
2759- Queue.push_back (
2760- Data{StartBitOffset + FieldOffset, Field-> getType (), true });
2767+ Queue.push_back (Data{StartBitOffset + FieldOffset, Field-> getType (),
2768+ /* VisitVirtualBase */ true });
27612769 }
27622770 }
27632771 }
@@ -2772,9 +2780,10 @@ struct PaddingClearer {
27722780 << StartBitOffset << " Img from "
27732781 << StartBitOffset + ImgOffset.getQuantity () * CharWidth
27742782 << " \n " ;
2775- Queue.push_back (Data{StartBitOffset, ElementQualType, true });
2783+ Queue.push_back (
2784+ Data{StartBitOffset, ElementQualType, /* VisitVirtualBase*/ true });
27762785 Queue.push_back (Data{StartBitOffset + ImgOffset.getQuantity () * CharWidth,
2777- ElementQualType, true });
2786+ ElementQualType, /* VisitVirtualBase */ true });
27782787 }
27792788
27802789 void MergeOccuppiedIntervals () {
@@ -5151,12 +5160,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
51515160 return RValue::get (Ptr);
51525161 }
51535162 case Builtin::BI__builtin_clear_padding: {
5154- const Expr *Op = E->getArg (0 );
5155- Value *Address = EmitScalarExpr (Op);
5156- auto PointeeTy = Op->getType ()->getPointeeType ();
5163+ Address Src = EmitPointerWithAlignment (E->getArg (0 ));
5164+ auto PointeeTy = E->getArg (0 )->getType ()->getPointeeType ();
51575165 PaddingClearer clearer{*this };
5158- clearer.run (Address, PointeeTy);
5159- // RecursivelyClearPadding(*this, Address, PointeeTy);
5166+ clearer.run (Src.getBasePointer (), PointeeTy);
51605167 return RValue::get (nullptr );
51615168 }
51625169 case Builtin::BI__sync_fetch_and_add:
0 commit comments