@@ -79,13 +79,18 @@ struct CIRRecordLowering final {
79
79
// / Inserts padding everywhere it's needed.
80
80
void insertPadding ();
81
81
82
+ void computeVolatileBitfields ();
82
83
void accumulateBases (const CXXRecordDecl *cxxRecordDecl);
83
84
void accumulateVPtrs ();
84
85
void accumulateFields ();
85
86
RecordDecl::field_iterator
86
87
accumulateBitFields (RecordDecl::field_iterator field,
87
88
RecordDecl::field_iterator fieldEnd);
88
89
90
+ bool isAAPCS () const {
91
+ return astContext.getTargetInfo ().getABI ().starts_with (" aapcs" );
92
+ }
93
+
89
94
CharUnits bitsToCharUnits (uint64_t bitOffset) {
90
95
return astContext.toCharUnitsFromBits (bitOffset);
91
96
}
@@ -239,7 +244,7 @@ void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
239
244
void CIRRecordLowering::lower () {
240
245
if (recordDecl->isUnion ()) {
241
246
lowerUnion ();
242
- assert (! cir::MissingFeatures::bitfields () );
247
+ computeVolatileBitfields ( );
243
248
return ;
244
249
}
245
250
@@ -253,7 +258,7 @@ void CIRRecordLowering::lower() {
253
258
accumulateBases (cxxRecordDecl);
254
259
if (members.empty ()) {
255
260
appendPaddingBytes (size);
256
- assert (! cir::MissingFeatures::bitfields () );
261
+ computeVolatileBitfields ( );
257
262
return ;
258
263
}
259
264
assert (!cir::MissingFeatures::recordLayoutVirtualBases ());
@@ -271,6 +276,7 @@ void CIRRecordLowering::lower() {
271
276
272
277
calculateZeroInit ();
273
278
fillOutputFields ();
279
+ computeVolatileBitfields ();
274
280
}
275
281
276
282
void CIRRecordLowering::fillOutputFields () {
@@ -754,6 +760,30 @@ void CIRRecordLowering::lowerUnion() {
754
760
packed = true ;
755
761
}
756
762
763
+ // / The AAPCS that defines that, when possible, bit-fields should
764
+ // / be accessed using containers of the declared type width:
765
+ // / When a volatile bit-field is read, and its container does not overlap with
766
+ // / any non-bit-field member or any zero length bit-field member, its container
767
+ // / must be read exactly once using the access width appropriate to the type of
768
+ // / the container. When a volatile bit-field is written, and its container does
769
+ // / not overlap with any non-bit-field member or any zero-length bit-field
770
+ // / member, its container must be read exactly once and written exactly once
771
+ // / using the access width appropriate to the type of the container. The two
772
+ // / accesses are not atomic.
773
+ // /
774
+ // / Enforcing the width restriction can be disabled using
775
+ // / -fno-aapcs-bitfield-width.
776
+ void CIRRecordLowering::computeVolatileBitfields () {
777
+ if (!isAAPCS () ||
778
+ !cirGenTypes.getCGModule ().getCodeGenOpts ().AAPCSBitfieldWidth )
779
+ return ;
780
+
781
+ for ([[maybe_unused]] auto &I : bitFields) {
782
+ assert (!cir::MissingFeatures::armComputeVolatileBitfields ());
783
+ cirGenTypes.getCGModule ().errorNYI (" NYI AAPCS bit-fields" );
784
+ }
785
+ }
786
+
757
787
void CIRRecordLowering::accumulateBases (const CXXRecordDecl *cxxRecordDecl) {
758
788
// If we've got a primary virtual base, we need to add it with the bases.
759
789
if (astRecordLayout.isPrimaryBaseVirtual ()) {
0 commit comments