@@ -350,15 +350,30 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
350
350
static_def_id : Option < DefId > ,
351
351
is_write : bool ,
352
352
) -> InterpResult < ' tcx > {
353
- if is_write && allocation . mutability == Mutability :: Not {
354
- Err ( err_ub ! ( WriteToReadOnly ( alloc_id ) ) . into ( ) )
355
- } else if is_write {
356
- Err ( ConstEvalErrKind :: ModifiedGlobal . into ( ) )
357
- } else if memory_extra . can_access_statics || static_def_id . is_none ( ) {
358
- // `static_def_id.is_none()` indicates this is not a static, but a const or so.
359
- Ok ( ( ) )
353
+ if is_write {
354
+ // Write access. These are never allowed, but we give a targeted error message.
355
+ if allocation . mutability == Mutability :: Not {
356
+ Err ( err_ub ! ( WriteToReadOnly ( alloc_id ) ) . into ( ) )
357
+ } else {
358
+ Err ( ConstEvalErrKind :: ModifiedGlobal . into ( ) )
359
+ }
360
360
} else {
361
- Err ( ConstEvalErrKind :: ConstAccessesStatic . into ( ) )
361
+ // Read access. These are usually allowed, with some exceptions.
362
+ if memory_extra. can_access_statics {
363
+ // This is allowed to read from anything.
364
+ Ok ( ( ) )
365
+ } else if allocation. mutability == Mutability :: Mut || static_def_id. is_some ( ) {
366
+ // This is a potentially dangerous read.
367
+ // We *must* error on any access to a mutable global here, as the content of
368
+ // this allocation may be different now and at run-time, so if we permit reading
369
+ // now we might return the wrong value.
370
+ // We conservatively also reject all statics here, but that could be relaxed
371
+ // in the future.
372
+ Err ( ConstEvalErrKind :: ConstAccessesStatic . into ( ) )
373
+ } else {
374
+ // Immutable global, this read is fine.
375
+ Ok ( ( ) )
376
+ }
362
377
}
363
378
}
364
379
}
0 commit comments