@@ -28,6 +28,21 @@ function should_infer_for_effects(sv::InferenceState)
28
28
sv. ipo_effects. effect_free === ALWAYS_TRUE
29
29
end
30
30
31
+ function merge_statement_effect! (sv:: InferenceState , effects:: Effects )
32
+ stmt_inbounds = get_curr_ssaflag (sv) & IR_FLAG_INBOUNDS != 0
33
+ propagate_inbounds = sv. src. propagate_inbounds
34
+ # Look at inbounds state and see what we need to do about :nothrow_if_inbounds
35
+ adjusted_effects = Effects (
36
+ effects. consistent,
37
+ effects. effect_free,
38
+ stmt_inbounds ? effects. nothrow_if_inbounds : effects. nothrow,
39
+ propagate_inbounds ? effects. nothrow_if_inbounds :
40
+ (effects. nothrow === ALWAYS_TRUE ? ALWAYS_TRUE : TRISTATE_UNKNOWN),
41
+ effects. terminates
42
+ )
43
+ tristate_merge! (sv, adjusted_effects)
44
+ end
45
+
31
46
function abstract_call_gf_by_type (interp:: AbstractInterpreter , @nospecialize (f),
32
47
arginfo:: ArgInfo , @nospecialize (atype),
33
48
sv:: InferenceState , max_methods:: Int = get_max_methods (sv. mod, interp))
@@ -40,7 +55,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
40
55
# aren't any in the throw block either to enable other optimizations.
41
56
add_remark! (interp, sv, " Skipped call in throw block" )
42
57
tristate_merge! (sv, Effects (ALWAYS_TRUE, TRISTATE_UNKNOWN,
43
- TRISTATE_UNKNOWN, TRISTATE_UNKNOWN))
58
+ TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN ))
44
59
return CallMeta (Any, false )
45
60
end
46
61
@@ -106,7 +121,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
106
121
rt = const_rt
107
122
end
108
123
end
109
- tristate_merge ! (sv, effects)
124
+ merge_statement_effect ! (sv, effects)
110
125
push! (const_results, const_result)
111
126
if const_result != = nothing
112
127
any_const_result = true
@@ -148,7 +163,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
148
163
this_rt = const_this_rt
149
164
end
150
165
end
151
- tristate_merge ! (sv, effects)
166
+ merge_statement_effect ! (sv, effects)
152
167
push! (const_results, const_result)
153
168
if const_result != = nothing
154
169
any_const_result = true
@@ -185,7 +200,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
185
200
tristate_merge! (sv, Effects ())
186
201
elseif ! (atype <: merged_sig )
187
202
# Account for the fact that we may encounter a non-covered signature.
188
- tristate_merge! (sv, Effects (ALWAYS_TRUE, ALWAYS_TRUE, TRISTATE_UNKNOWN, ALWAYS_TRUE))
203
+ tristate_merge! (sv, Effects (ALWAYS_TRUE, ALWAYS_TRUE, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, ALWAYS_TRUE))
189
204
end
190
205
191
206
rettype = from_interprocedural! (rettype, sv, arginfo, conditionals)
@@ -599,7 +614,7 @@ function abstract_call_method(interp::AbstractInterpreter, method::Method, @nosp
599
614
# Some sort of recursion was detected. Even if we did not limit types,
600
615
# we cannot guarantee that the call will terminate.
601
616
edge_effects = tristate_merge (edge_effects,
602
- Effects (ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, TRISTATE_UNKNOWN))
617
+ Effects (ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, TRISTATE_UNKNOWN))
603
618
end
604
619
return MethodCallResult (rt, edgecycle, edgelimited, edge, edge_effects)
605
620
end
@@ -1472,7 +1487,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
1472
1487
return abstract_modifyfield! (interp, argtypes, sv)
1473
1488
end
1474
1489
rt = abstract_call_builtin (interp, f, arginfo, sv, max_methods)
1475
- tristate_merge! (sv, builtin_effects (f, argtypes , rt))
1490
+ tristate_merge! (sv, builtin_effects (f, arginfo , rt))
1476
1491
return CallMeta (rt, false )
1477
1492
elseif isa (f, Core. OpaqueClosure)
1478
1493
# calling an OpaqueClosure about which we have no information returns no information
@@ -1792,7 +1807,9 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
1792
1807
end
1793
1808
tristate_merge! (sv, Effects (
1794
1809
! ismutabletype (t) ? ALWAYS_TRUE : ALWAYS_FALSE,
1795
- ALWAYS_TRUE, is_nothrow ? ALWAYS_TRUE : ALWAYS_FALSE, ALWAYS_TRUE))
1810
+ ALWAYS_TRUE, is_nothrow ? ALWAYS_TRUE : ALWAYS_FALSE,
1811
+ is_nothrow ? ALWAYS_TRUE : ALWAYS_FALSE,
1812
+ ALWAYS_TRUE))
1796
1813
elseif ehead === :splatnew
1797
1814
t, isexact = instanceof_tfunc (abstract_eval_value (interp, e. args[1 ], vtypes, sv))
1798
1815
is_nothrow = false # TODO : More precision
@@ -1812,6 +1829,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
1812
1829
tristate_merge! (sv, Effects (
1813
1830
ismutabletype (t) ? ALWAYS_FALSE : ALWAYS_TRUE,
1814
1831
ALWAYS_TRUE, is_nothrow ? ALWAYS_TRUE : ALWAYS_FALSE,
1832
+ is_nothrow ? ALWAYS_TRUE : ALWAYS_FALSE,
1815
1833
ALWAYS_TRUE))
1816
1834
elseif ehead === :new_opaque_closure
1817
1835
tristate_merge! (sv, Effects ()) # TODO
@@ -1850,6 +1868,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
1850
1868
effects. consistent ? ALWAYS_TRUE : TRISTATE_UNKNOWN,
1851
1869
effects. effect_free ? ALWAYS_TRUE : TRISTATE_UNKNOWN,
1852
1870
effects. nothrow ? ALWAYS_TRUE : TRISTATE_UNKNOWN,
1871
+ effects. nothrow_if_inbounds ? ALWAYS_TRUE : TRISTATE_UNKNOWN,
1853
1872
effects. terminates ? ALWAYS_TRUE : TRISTATE_UNKNOWN,
1854
1873
))
1855
1874
else
@@ -1931,10 +1950,10 @@ function abstract_eval_global(M::Module, s::Symbol, frame::InferenceState)
1931
1950
if isconst (M,s)
1932
1951
return Const (getfield (M,s))
1933
1952
else
1934
- tristate_merge! (frame, Effects (ALWAYS_FALSE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE))
1953
+ tristate_merge! (frame, Effects (ALWAYS_FALSE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE ))
1935
1954
end
1936
1955
else
1937
- tristate_merge! (frame, Effects (ALWAYS_FALSE, ALWAYS_TRUE, ALWAYS_FALSE, ALWAYS_TRUE))
1956
+ tristate_merge! (frame, Effects (ALWAYS_FALSE, ALWAYS_TRUE, ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_TRUE))
1938
1957
end
1939
1958
return Any
1940
1959
end
@@ -2020,7 +2039,7 @@ end
2020
2039
2021
2040
function handle_backedge! (frame:: InferenceState , from, to)
2022
2041
if from > to
2023
- tristate_merge! (frame, Effects (ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, TRISTATE_UNKNOWN))
2042
+ tristate_merge! (frame, Effects (ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, TRISTATE_UNKNOWN))
2024
2043
end
2025
2044
end
2026
2045
@@ -2176,7 +2195,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
2176
2195
if isa (lhs, SlotNumber)
2177
2196
changes = StateUpdate (lhs, VarState (t, false ), changes, false )
2178
2197
elseif isa (lhs, GlobalRef)
2179
- tristate_merge! (frame, Effects (ALWAYS_TRUE, ALWAYS_FALSE, TRISTATE_UNKNOWN, ALWAYS_TRUE))
2198
+ tristate_merge! (frame, Effects (ALWAYS_TRUE, ALWAYS_FALSE, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, ALWAYS_TRUE))
2180
2199
elseif ! isa (lhs, SSAValue)
2181
2200
tristate_merge! (frame, Effects ())
2182
2201
end
0 commit comments