@@ -139,7 +139,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
139
139
Entry :: Occupied ( e) => e. into_mut ( ) ,
140
140
Entry :: Vacant ( e) => {
141
141
// Find it if it was not cached.
142
- let mut instance_and_crate: Option < ( ty:: Instance < ' _ > , CrateNum , bool ) > = None ;
142
+
143
+ struct SymbolTarget < ' tcx > {
144
+ instance : ty:: Instance < ' tcx > ,
145
+ cnum : CrateNum ,
146
+ is_weak : bool ,
147
+ }
148
+ let mut symbol_target: Option < SymbolTarget < ' tcx > > = None ;
143
149
helpers:: iter_exported_symbols ( tcx, |cnum, def_id| {
144
150
let attrs = tcx. codegen_fn_attrs ( def_id) ;
145
151
// Skip over imports of items.
@@ -158,23 +164,31 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
158
164
let symbol_name = tcx. symbol_name ( instance) . name ;
159
165
let is_weak = attrs. linkage == Some ( Linkage :: WeakAny ) ;
160
166
if symbol_name == link_name. as_str ( ) {
161
- if let Some ( ( original_instance, original_cnum, original_is_weak) ) =
162
- instance_and_crate
167
+ if let Some ( SymbolTarget {
168
+ instance : original_instance,
169
+ cnum : original_cnum,
170
+ is_weak : original_is_weak,
171
+ } ) = symbol_target
163
172
{
173
+ // There is more than one definition with this name. What we do now
174
+ // depends on whether one or both definitions are weak.
164
175
match ( is_weak, original_is_weak) {
165
176
( false , true ) => {
166
177
// Original definition is a weak definition. Override it.
167
178
168
- instance_and_crate =
169
- Some ( ( ty:: Instance :: mono ( tcx, def_id) , cnum, is_weak) ) ;
179
+ symbol_target = Some ( SymbolTarget {
180
+ instance : ty:: Instance :: mono ( tcx, def_id) ,
181
+ cnum,
182
+ is_weak,
183
+ } ) ;
170
184
}
171
185
( true , false ) => {
172
186
// Current definition is a weak definition. Keep the original one.
173
187
}
174
188
( true , true ) | ( false , false ) => {
175
189
// Either both definitions are non-weak or both are weak. In
176
190
// either case return an error. For weak definitions we error
177
- // because it is undefined which definition would have been
191
+ // because it is unspecified which definition would have been
178
192
// picked by the linker.
179
193
180
194
// Make sure we are consistent wrt what is 'first' and 'second'.
@@ -205,22 +219,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
205
219
}
206
220
}
207
221
} else {
208
- instance_and_crate =
209
- Some ( ( ty:: Instance :: mono ( tcx, def_id) , cnum, is_weak) ) ;
222
+ symbol_target = Some ( SymbolTarget {
223
+ instance : ty:: Instance :: mono ( tcx, def_id) ,
224
+ cnum,
225
+ is_weak,
226
+ } ) ;
210
227
}
211
228
}
212
229
interp_ok ( ( ) )
213
230
} ) ?;
214
231
215
- if let Some ( ( instance, _ , _ ) ) = instance_and_crate {
232
+ if let Some ( SymbolTarget { instance, .. } ) = symbol_target {
216
233
if !matches ! ( tcx. def_kind( instance. def_id( ) ) , DefKind :: Fn | DefKind :: AssocFn ) {
217
234
throw_ub_format ! (
218
235
"attempt to call an exported symbol that is not defined as a function"
219
236
) ;
220
237
}
221
238
}
222
239
223
- e. insert ( instance_and_crate . map ( |ic| ic. 0 ) )
240
+ e. insert ( symbol_target . map ( |ic| ic. 0 ) )
224
241
}
225
242
} ;
226
243
match instance {
0 commit comments