@@ -1974,6 +1974,14 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
19741974 end
19751975 rt = abstract_call_builtin (interp, f, arginfo, sv, max_methods)
19761976 effects = builtin_effects (𝕃ᵢ, f, arginfo, rt)
1977+ if f === getfield && (fargs != = nothing && isexpr (fargs[end ], :boundscheck )) && ! is_nothrow (effects) && isa (sv, InferenceState)
1978+ # As a special case, we delayed tainting `noinbounds` for getfield calls in case we can prove
1979+ # in-boundedness indepedently. Here we need to put that back in other cases.
1980+ # N.B.: This isn't about the effects of the call itself, but a delayed contribution of the :boundscheck
1981+ # statement, so we need to merge this directly into sv, rather than modifying thte effects.
1982+ merge_effects! (interp, sv, Effects (EFFECTS_TOTAL; noinbounds= false ,
1983+ consistent = (get_curr_ssaflag (sv) & IR_FLAG_INBOUNDS) != 0 ? ALWAYS_FALSE : ALWAYS_TRUE))
1984+ end
19771985 return CallMeta (rt, effects, NoCallInfo ())
19781986 elseif isa (f, Core. OpaqueClosure)
19791987 # calling an OpaqueClosure about which we have no information returns no information
@@ -2195,6 +2203,15 @@ function abstract_eval_value_expr(interp::AbstractInterpreter, e::Expr, vtypes::
21952203 return rt
21962204 elseif head === :boundscheck
21972205 if isa (sv, InferenceState)
2206+ stmt = sv. src. code[sv. currpc]
2207+ if isexpr (stmt, :call )
2208+ f = abstract_eval_value (interp, stmt. args[1 ], vtypes, sv)
2209+ if f isa Const && f. val === getfield
2210+ # boundscheck of `getfield` call is analyzed by tfunc potentially without
2211+ # tainting :inbounds or :consistent when it's known to be nothrow
2212+ @goto delay_effects_analysis
2213+ end
2214+ end
21982215 # If there is no particular `@inbounds` for this function, then we only taint `:noinbounds`,
21992216 # which will subsequently taint `:consistent`-cy if this function is called from another
22002217 # function that uses `@inbounds`. However, if this `:boundscheck` is itself within an
@@ -2203,6 +2220,7 @@ function abstract_eval_value_expr(interp::AbstractInterpreter, e::Expr, vtypes::
22032220 merge_effects! (interp, sv, Effects (EFFECTS_TOTAL; noinbounds= false ,
22042221 consistent = (get_curr_ssaflag (sv) & IR_FLAG_INBOUNDS) != 0 ? ALWAYS_FALSE : ALWAYS_TRUE))
22052222 end
2223+ @label delay_effects_analysis
22062224 rt = Bool
22072225 elseif head === :inbounds
22082226 @assert false && " Expected this to have been moved into flags"
0 commit comments