@@ -79,13 +79,18 @@ struct CIRRecordLowering final {
7979 // / Inserts padding everywhere it's needed.
8080 void insertPadding ();
8181
82+ void computeVolatileBitfields ();
8283 void accumulateBases (const CXXRecordDecl *cxxRecordDecl);
8384 void accumulateVPtrs ();
8485 void accumulateFields ();
8586 RecordDecl::field_iterator
8687 accumulateBitFields (RecordDecl::field_iterator field,
8788 RecordDecl::field_iterator fieldEnd);
8889
90+ bool isAAPCS () const {
91+ return astContext.getTargetInfo ().getABI ().starts_with (" aapcs" );
92+ }
93+
8994 CharUnits bitsToCharUnits (uint64_t bitOffset) {
9095 return astContext.toCharUnitsFromBits (bitOffset);
9196 }
@@ -239,7 +244,7 @@ void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
239244void CIRRecordLowering::lower () {
240245 if (recordDecl->isUnion ()) {
241246 lowerUnion ();
242- assert (! cir::MissingFeatures::bitfields () );
247+ computeVolatileBitfields ( );
243248 return ;
244249 }
245250
@@ -253,7 +258,7 @@ void CIRRecordLowering::lower() {
253258 accumulateBases (cxxRecordDecl);
254259 if (members.empty ()) {
255260 appendPaddingBytes (size);
256- assert (! cir::MissingFeatures::bitfields () );
261+ computeVolatileBitfields ( );
257262 return ;
258263 }
259264 assert (!cir::MissingFeatures::recordLayoutVirtualBases ());
@@ -271,6 +276,7 @@ void CIRRecordLowering::lower() {
271276
272277 calculateZeroInit ();
273278 fillOutputFields ();
279+ computeVolatileBitfields ();
274280}
275281
276282void CIRRecordLowering::fillOutputFields () {
@@ -754,6 +760,30 @@ void CIRRecordLowering::lowerUnion() {
754760 packed = true ;
755761}
756762
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+
757787void CIRRecordLowering::accumulateBases (const CXXRecordDecl *cxxRecordDecl) {
758788 // If we've got a primary virtual base, we need to add it with the bases.
759789 if (astRecordLayout.isPrimaryBaseVirtual ()) {
0 commit comments