@@ -221,34 +221,50 @@ function InferenceState(result::InferenceResult, cached::Symbol, interp::GPUInte
221
221
src === nothing && return nothing
222
222
validate_code_in_debug_mode (result. linfo, src, " lowered" )
223
223
validate_globalrefs (interp, result. linfo, src)
224
+ validate_code_in_debug_mode (result. linfo, src, " validated" )
225
+ errors = Core. Compiler. validate_code (result. linfo, src)
226
+ @safe_info " errors" errors src. code
224
227
return InferenceState (result, src, cached, interp)
225
228
end
226
229
227
230
function validate_globalrefs (interp, mi, src)
228
- function validate (x)
231
+ # pseudo (single-frame) backtrace pointing to a source code location
232
+ function backtrace (i)
233
+ loc = src. linetable[i]
234
+ [StackTraces. StackFrame (loc. method, loc. file, loc. line, mi, false , false , C_NULL )]
235
+ end
236
+
237
+ function validate (i, x, errors:: Vector{IRError} )
229
238
if x isa Expr
230
- return Expr (x. head, validate .(x. args))
239
+ for y in x. args
240
+ validate (i, y, errors)
241
+ end
231
242
elseif x isa GlobalRef
232
243
Base. isbindingresolved (x. mod, x. name) || return
233
244
# XXX : when does this happen? do we miss any cases by bailing out early?
234
245
# why doesn't calling `Base.resolve(x, force=true)` work?
235
246
if ! Base. isdefined (x. mod, x. name)
236
- throw ( KernelError (interp . job, " using undefined global: $(x. mod) .$(x. name) " ))
247
+ push! (errors, ( " using undefined global: $(x. mod) .$(x. name) " , backtrace (i), nothing ))
237
248
end
238
249
if ! Base. isconst (x. mod, x. name)
239
- throw ( KernelError (interp . job, " using mutable global: $(x. mod) .$(x. name) " ))
250
+ push! (errors, ( " using mutable global: $(x. mod) .$(x. name) " , backtrace (i), nothing ))
240
251
end
241
- # XXX : can we use KernelError? and make the validation conditional? both are
242
- # complicated by the fact that we don't have the CompilerJob here,
243
- # and that inference results can be cached across jobs.
252
+
253
+ # TODO : make the validation conditional, but make sure we don't cache invalid IR
244
254
245
255
# TODO : perform more validation? e.g. disallow Arrays and other CPU values?
246
- # probably requires an interface, so again access to the CompilerJob
247
- # (as a CPU-back-end would still support such values).
248
256
end
257
+
258
+ return
249
259
end
250
260
251
- validate .(src. code)
261
+ errors = IRError[]
262
+ for (i, x) in enumerate (src. code)
263
+ validate (i, x, errors)
264
+ end
265
+ if ! isempty (errors)
266
+ throw (InvalidIRError (interp. job, errors))
267
+ end
252
268
253
269
return
254
270
end
0 commit comments