■ ■ ■ ■ ■ ■
jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java
| skipped 15 lines |
16 | 16 | | import jadx.core.dex.instructions.args.RegisterArg; |
17 | 17 | | import jadx.core.dex.instructions.args.SSAVar; |
18 | 18 | | import jadx.core.dex.nodes.BlockNode; |
19 | | - | import jadx.core.dex.nodes.DexNode; |
20 | 19 | | import jadx.core.dex.nodes.IBlock; |
21 | 20 | | import jadx.core.dex.nodes.IRegion; |
22 | 21 | | import jadx.core.dex.nodes.InsnNode; |
| skipped 209 lines |
232 | 231 | | } |
233 | 232 | | List<InsnNode> toSkip = new LinkedList<InsnNode>(); |
234 | 233 | | RegisterArg iterVar = nextCall.getResult(); |
| 234 | + | if (iterVar == null) { |
| 235 | + | return false; |
| 236 | + | } |
235 | 237 | | if (nextCall.contains(AFlag.WRAPPED)) { |
236 | 238 | | InsnArg wrapArg = BlockUtils.searchWrappedInsnParent(mth, nextCall); |
237 | 239 | | if (wrapArg != null && wrapArg.getParentInsn() != null) { |
238 | 240 | | InsnNode parentInsn = wrapArg.getParentInsn(); |
239 | 241 | | if (parentInsn.getType() != InsnType.CHECK_CAST) { |
| 242 | + | if (!fixIterableType(mth, iterableArg, iterVar)) { |
| 243 | + | return false; |
| 244 | + | } |
240 | 245 | | parentInsn.replaceArg(wrapArg, iterVar); |
241 | 246 | | } else { |
242 | 247 | | iterVar = parentInsn.getResult(); |
| 248 | + | if (iterVar == null || !fixIterableType(mth, iterableArg, iterVar)) { |
| 249 | + | return false; |
| 250 | + | } |
243 | 251 | | InsnArg castArg = BlockUtils.searchWrappedInsnParent(mth, parentInsn); |
244 | 252 | | if (castArg != null && castArg.getParentInsn() != null) { |
245 | 253 | | castArg.getParentInsn().replaceArg(castArg, iterVar); |
| skipped 8 lines |
254 | 262 | | } |
255 | 263 | | } else { |
256 | 264 | | toSkip.add(nextCall); |
257 | | - | } |
258 | | - | if (iterVar == null || !fixIterableType(mth.dex(), iterableArg, iterVar)) { |
259 | | - | return false; |
260 | 265 | | } |
261 | 266 | | |
262 | 267 | | assignInsn.add(AFlag.SKIP); |
| skipped 4 lines |
267 | 272 | | return true; |
268 | 273 | | } |
269 | 274 | | |
270 | | - | private static boolean fixIterableType(DexNode dex, InsnArg iterableArg, RegisterArg iterVar) { |
| 275 | + | private static boolean fixIterableType(MethodNode mth, InsnArg iterableArg, RegisterArg iterVar) { |
271 | 276 | | ArgType iterableType = iterableArg.getType(); |
272 | 277 | | ArgType varType = iterVar.getType(); |
273 | 278 | | if (iterableType.isGeneric()) { |
| skipped 9 lines |
283 | 288 | | iterVar.setType(gType); |
284 | 289 | | return true; |
285 | 290 | | } |
286 | | - | if (ArgType.isInstanceOf(dex, gType, varType)) { |
| 291 | + | if (ArgType.isInstanceOf(mth.dex(), gType, varType)) { |
287 | 292 | | return true; |
288 | 293 | | } |
289 | | - | LOG.warn("Generic type differs: {} and {}", gType, varType); |
| 294 | + | ArgType wildcardType = gType.getWildcardType(); |
| 295 | + | if (wildcardType != null |
| 296 | + | && gType.getWildcardBounds() == 1 |
| 297 | + | && ArgType.isInstanceOf(mth.dex(), wildcardType, varType)) { |
| 298 | + | return true; |
| 299 | + | } |
| 300 | + | LOG.warn("Generic type differs: '{}' and '{}' in {}", gType, varType, mth); |
290 | 301 | | return false; |
291 | 302 | | } |
292 | 303 | | if (!iterableArg.isRegister()) { |
| skipped 75 lines |