@@ -2562,6 +2562,14 @@ static RValue EmitHipStdParUnsupportedBuiltin(CodeGenFunction *CGF,
2562
2562
2563
2563
namespace {
2564
2564
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.
2565
2573
struct PaddingClearer {
2566
2574
PaddingClearer (CodeGenFunction &F)
2567
2575
: CGF(F), CharWidth(CGF.getContext().getCharWidth()) {}
@@ -2572,8 +2580,8 @@ struct PaddingClearer {
2572
2580
2573
2581
Queue.push_back (Data{0 , Ty, true });
2574
2582
while (!Queue.empty ()) {
2575
- auto Current = Queue.front ();
2576
- Queue.pop_front ();
2583
+ auto Current = Queue.back ();
2584
+ Queue.pop_back ();
2577
2585
Visit (Current);
2578
2586
}
2579
2587
@@ -2655,7 +2663,7 @@ struct PaddingClearer {
2655
2663
2656
2664
Queue.push_back (
2657
2665
Data{StartBitOffset + ArrIndex * Offset.getQuantity () * CharWidth,
2658
- ElementQualType, true });
2666
+ ElementQualType, /* VisitVirtualBase */ true });
2659
2667
}
2660
2668
}
2661
2669
@@ -2688,8 +2696,8 @@ struct PaddingClearer {
2688
2696
2689
2697
llvm::dbgs () << " visiting base at offset " << StartBitOffset << " + "
2690
2698
<< 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 });
2693
2701
};
2694
2702
2695
2703
for (auto Base : R->bases ()) {
@@ -2718,8 +2726,8 @@ struct PaddingClearer {
2718
2726
StartBitOffset + FieldOffset +
2719
2727
Field->getBitWidthValue ()});
2720
2728
} else {
2721
- Queue.push_back (
2722
- Data{StartBitOffset + FieldOffset, Field-> getType (), true });
2729
+ Queue.push_back (Data{StartBitOffset + FieldOffset, Field-> getType (),
2730
+ /* VisitVirtualBase */ true });
2723
2731
}
2724
2732
}
2725
2733
}
@@ -2734,9 +2742,10 @@ struct PaddingClearer {
2734
2742
<< StartBitOffset << " Img from "
2735
2743
<< StartBitOffset + ImgOffset.getQuantity () * CharWidth
2736
2744
<< " \n " ;
2737
- Queue.push_back (Data{StartBitOffset, ElementQualType, true });
2745
+ Queue.push_back (
2746
+ Data{StartBitOffset, ElementQualType, /* VisitVirtualBase*/ true });
2738
2747
Queue.push_back (Data{StartBitOffset + ImgOffset.getQuantity () * CharWidth,
2739
- ElementQualType, true });
2748
+ ElementQualType, /* VisitVirtualBase */ true });
2740
2749
}
2741
2750
2742
2751
void MergeOccuppiedIntervals () {
@@ -5078,12 +5087,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
5078
5087
return RValue::get (Ptr);
5079
5088
}
5080
5089
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 ();
5084
5092
PaddingClearer clearer{*this };
5085
- clearer.run (Address, PointeeTy);
5086
- // RecursivelyClearPadding(*this, Address, PointeeTy);
5093
+ clearer.run (Src.getBasePointer (), PointeeTy);
5087
5094
return RValue::get (nullptr );
5088
5095
}
5089
5096
case Builtin::BI__sync_fetch_and_add:
0 commit comments