-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix :noub inference for pointerset/pointerref, getfield with bounds checking disabled #57295
base: master
Are you sure you want to change the base?
Conversation
@@ -1033,7 +1033,7 @@ end | |||
# we may assume that we don't throw | |||
@assert !boundscheck | |||
ismod && return false | |||
name ⊑ Int || name ⊑ Symbol || return false | |||
name ⊑ Int || return false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was under the impression that boundscheck=false
was a no-op when name
is a symbol, since we always throw a FieldError
if it doesn't exist. Pre-change:
julia> Base.infer_effects(x -> getfield(x, :foo, false), (Pair{String, Bool},))
(+c,+e,+n,+t,+s,+m,+u,+o,+r)
julia> (x -> getfield(x, :foo, false))(Pair("abc", false))
ERROR: type Pair has no field foo
Stacktrace:
[1] (::var"#15#16")(x::Pair{String, Bool})
@ Main ./REPL[6]:1
[2] top-level scope
@ REPL[6]:1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Post change:
julia> Base.infer_effects(x -> getfield(x, :foo, false), (Pair{String, Bool},))
(+c,+e,!n,+t,+s,+m,!u,+o,+r)
julia> Base.infer_effects(x -> getfield(x, :foo, true), (Pair{String, Bool},))
(+c,+e,!n,+t,+s,+m,+u,+o,+r)
julia> Base.infer_effects(x -> getfield(x, 1, false), (Pair{String, Bool},))
(+c,+e,+n,+t,+s,+m,+u,+o,+r)
julia> Base.infer_effects(x -> getfield(x, 3, false), (Pair{String, Bool},))
(+c,+e,+n,+t,+s,+m,!u,+o,+r)
# If we cannot independently prove inboundsness, taint `:noub`. | ||
# The inbounds-ness assertion requires dynamic reachability, | ||
# while `:noub` needs to be true for all input values. | ||
# However, as a special exception, we do allow literal `:boundscheck`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look like it's true anymore (and wasn't before?)
Also document the bounds check disabling flag on getfield, add docs for pointerref/pointerset/memorynew. getfield with symbol will throw even if boundschecking is turned off.
578466d
to
10516f8
Compare
:noub
forpointerref
(andpointerset
), fixingunsafe_load
does not taint:noub
effect #56056pointerset
,pointerref
.unsafe_load
does not taint:noub
effect #56056 (comment), namely thatgetfield
with bounds checking off didn't taint:noub
.:nothrow
when bounds checking is off but the field name is a symbol, since we'll throw aFieldError
.Int
instead ofSymbol
.getfield
to document the boundscheck argument.builtins.md