@@ -350,15 +350,30 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
350350 static_def_id : Option < DefId > ,
351351 is_write : bool ,
352352 ) -> 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+ }
360360 } 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+ }
362377 }
363378 }
364379}
0 commit comments