@@ -1094,6 +1094,17 @@ precompile_test_harness("invoke") do dir
1094
1094
f44320(::Any) = 2
1095
1095
g44320() = invoke(f44320, Tuple{Any}, 0)
1096
1096
g44320()
1097
+ # Issue #57115
1098
+ f57115(@nospecialize(::Any)) = error("unimplemented")
1099
+ function g57115(@nospecialize(x))
1100
+ if @noinline rand(Bool)
1101
+ # Add an 'invoke' edge from 'foo' to 'bar'
1102
+ Core.invoke(f57115, Tuple{Any}, x)
1103
+ else
1104
+ # ... and also an identical 'call' edge
1105
+ @noinline f57115(x)
1106
+ end
1107
+ end
1097
1108
1098
1109
# Adding new specializations should not invalidate `invoke`s
1099
1110
function getlast(itr)
@@ -1110,6 +1121,8 @@ precompile_test_harness("invoke") do dir
1110
1121
"""
1111
1122
module $CallerModule
1112
1123
using $InvokeModule
1124
+ import $InvokeModule : f57115, g57115
1125
+
1113
1126
# involving external modules
1114
1127
callf(x) = f(x)
1115
1128
callg(x) = x < 5 ? g(x) : invoke(g, Tuple{Real}, x)
@@ -1130,6 +1143,8 @@ precompile_test_harness("invoke") do dir
1130
1143
1131
1144
# Issue #44320
1132
1145
f44320(::Real) = 3
1146
+ # Issue #57115
1147
+ f57115(::Int) = 1
1133
1148
1134
1149
call_getlast(x) = getlast(x)
1135
1150
@@ -1150,6 +1165,7 @@ precompile_test_harness("invoke") do dir
1150
1165
@noinline internalnc(3)
1151
1166
@noinline call_getlast([1,2,3])
1152
1167
end
1168
+ precompile(g57115, (Any,))
1153
1169
1154
1170
# Now that we've precompiled, invalidate with a new method that overrides the `invoke` dispatch
1155
1171
$InvokeModule .h(x::Integer) = -1
@@ -1217,6 +1233,30 @@ precompile_test_harness("invoke") do dir
1217
1233
m = only (methods (M. g44320))
1218
1234
@test (m. specializations:: Core.MethodInstance ). cache. max_world == typemax (UInt)
1219
1235
1236
+ m = only (methods (M. g57115))
1237
+ mi = m. specializations:: Core.MethodInstance
1238
+
1239
+ f_m = get_method_for_type (M. f57115, Any)
1240
+ f_mi = f_m. specializations:: Core.MethodInstance
1241
+
1242
+ # Make sure that f57115(::Any) has a 'call' backedge to 'g57115'
1243
+ has_f_call_backedge = false
1244
+ i = 1
1245
+ while i ≤ length (f_mi. backedges)
1246
+ if f_mi. backedges[i] isa DataType
1247
+ # invoke edge - skip
1248
+ i += 2
1249
+ else
1250
+ caller = f_mi. backedges[i]:: Core.CodeInstance
1251
+ if caller. def === mi
1252
+ has_f_call_backedge = true
1253
+ break
1254
+ end
1255
+ i += 1
1256
+ end
1257
+ end
1258
+ @test has_f_call_backedge
1259
+
1220
1260
m = which (MI. getlast, (Any,))
1221
1261
@test (m. specializations:: Core.MethodInstance ). cache. max_world == typemax (UInt)
1222
1262
0 commit comments