@@ -328,28 +328,70 @@ public static void Verify_AccessAllFields_CorElementType()
328
328
extern static ref delegate * < void > GetFPtr ( ref AllFields f ) ;
329
329
}
330
330
331
- // Contains fields that have modopts/modreqs
332
- struct FieldsWithModifiers
331
+ // Contains fields that are volatile
332
+ struct VolatileFields
333
333
{
334
334
private static volatile int s_vInt ;
335
335
private volatile int _vInt ;
336
336
}
337
337
338
+ // Accessors for fields that are volatile
339
+ static class AccessorsVolatile
340
+ {
341
+ [ UnsafeAccessor ( UnsafeAccessorKind . StaticField , Name = "s_vInt" ) ]
342
+ public extern static ref int GetStaticVolatileInt ( ref VolatileFields f ) ;
343
+
344
+ [ UnsafeAccessor ( UnsafeAccessorKind . Field , Name = "_vInt" ) ]
345
+ public extern static ref int GetVolatileInt ( ref VolatileFields f ) ;
346
+ }
347
+
338
348
[ Fact ]
339
- public static void Verify_AccessFieldsWithModifiers ( )
349
+ public static void Verify_AccessFieldsWithVolatile ( )
340
350
{
341
- Console . WriteLine ( $ "Running { nameof ( Verify_AccessFieldsWithModifiers ) } ") ;
351
+ Console . WriteLine ( $ "Running { nameof ( Verify_AccessFieldsWithVolatile ) } ") ;
342
352
343
- FieldsWithModifiers fieldsWithModifiers = default ;
353
+ VolatileFields fieldsWithVolatile = default ;
344
354
345
- GetStaticVolatileInt ( ref fieldsWithModifiers ) = default ;
346
- GetVolatileInt ( ref fieldsWithModifiers ) = default ;
355
+ AccessorsVolatile . GetStaticVolatileInt ( ref fieldsWithVolatile ) = default ;
356
+ AccessorsVolatile . GetVolatileInt ( ref fieldsWithVolatile ) = default ;
357
+ }
347
358
348
- [ UnsafeAccessor ( UnsafeAccessorKind . StaticField , Name = "s_vInt" ) ]
349
- extern static ref int GetStaticVolatileInt ( ref FieldsWithModifiers f ) ;
359
+ // Contains fields that are readonly
360
+ readonly struct ReadOnlyFields
361
+ {
362
+ public static readonly int s_rInt ;
363
+ public readonly int _rInt ;
364
+ }
350
365
351
- [ UnsafeAccessor ( UnsafeAccessorKind . Field , Name = "_vInt" ) ]
352
- extern static ref int GetVolatileInt ( ref FieldsWithModifiers f ) ;
366
+ // Accessors for fields that are readonly
367
+ static class AccessorsReadOnly
368
+ {
369
+ [ UnsafeAccessor ( UnsafeAccessorKind . StaticField , Name = "s_rInt" ) ]
370
+ public extern static ref readonly int GetStaticReadOnlyInt ( ref readonly ReadOnlyFields f ) ;
371
+
372
+ [ UnsafeAccessor ( UnsafeAccessorKind . Field , Name = "_rInt" ) ]
373
+ public extern static ref readonly int GetReadOnlyInt ( ref readonly ReadOnlyFields f ) ;
374
+ }
375
+
376
+ [ Fact ]
377
+ public static void Verify_AccessFieldsWithReadOnlyRefs ( )
378
+ {
379
+ Console . WriteLine ( $ "Running { nameof ( Verify_AccessFieldsWithReadOnlyRefs ) } ") ;
380
+
381
+ ReadOnlyFields readOnlyFields = default ;
382
+
383
+ Assert . True ( Unsafe . AreSame ( in AccessorsReadOnly . GetStaticReadOnlyInt ( in readOnlyFields ) , in ReadOnlyFields . s_rInt ) ) ;
384
+ Assert . True ( Unsafe . AreSame ( in AccessorsReadOnly . GetReadOnlyInt ( in readOnlyFields ) , in readOnlyFields . _rInt ) ) ;
385
+
386
+ // Test the local declaration of the signature since it places modopts/modreqs differently.
387
+ Assert . True ( Unsafe . AreSame ( in GetStaticReadOnlyIntLocal ( in readOnlyFields ) , in ReadOnlyFields . s_rInt ) ) ;
388
+ Assert . True ( Unsafe . AreSame ( in GetReadOnlyIntLocal ( in readOnlyFields ) , in readOnlyFields . _rInt ) ) ;
389
+
390
+ [ UnsafeAccessor ( UnsafeAccessorKind . StaticField , Name = "s_rInt" ) ]
391
+ extern static ref readonly int GetStaticReadOnlyIntLocal ( ref readonly ReadOnlyFields f ) ;
392
+
393
+ [ UnsafeAccessor ( UnsafeAccessorKind . Field , Name = "_rInt" ) ]
394
+ extern static ref readonly int GetReadOnlyIntLocal ( ref readonly ReadOnlyFields f ) ;
353
395
}
354
396
355
397
[ Fact ]
0 commit comments