From b0686b1ea71a4651461f640d4803ec0800a182bb Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sun, 28 Feb 2021 19:22:53 -0500 Subject: [PATCH] fix decompiler crash (#294) --- decompiler/IR2/Env.h | 12 ++++++++++-- decompiler/analysis/cfg_builder.cpp | 28 +++++++++++++++------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/decompiler/IR2/Env.h b/decompiler/IR2/Env.h index f29ad150a..00993bc7b 100644 --- a/decompiler/IR2/Env.h +++ b/decompiler/IR2/Env.h @@ -114,9 +114,17 @@ class Env { } const UseDefInfo& get_use_def_info(const RegisterAccess& ra) const; - void disable_use(const RegisterAccess& access) { m_var_names.disable_use(access); } + void disable_use(const RegisterAccess& access) { + if (has_local_vars()) { + m_var_names.disable_use(access); + } + } - void disable_def(const RegisterAccess& access) { m_var_names.disable_def(access); } + void disable_def(const RegisterAccess& access) { + if (has_local_vars()) { + m_var_names.disable_def(access); + } + } LinkedObjectFile* file = nullptr; DecompilerTypeSystem* dts = nullptr; diff --git a/decompiler/analysis/cfg_builder.cpp b/decompiler/analysis/cfg_builder.cpp index f13d971b9..badf03889 100644 --- a/decompiler/analysis/cfg_builder.cpp +++ b/decompiler/analysis/cfg_builder.cpp @@ -453,22 +453,24 @@ bool try_clean_up_sc_as_or(FormPool& pool, Function& func, ShortCircuitElement* // we also want to fix up the use/def info for the result. // it's somewhat arbitrary, but we use the convention that the short-circuit defs // are eliminated: - auto& ud_info = func.ir2.env.get_use_def_info(as_set->dst()); - if (i == int(ir->entries.size()) - 2) { - if (ud_info.def_count() == 1) { - // the final case of the or doesn't explicitly set the destination register. - // this can happen if the move is eliminated during coloring. - // for now, let's leave this last def here, just so it looks like _something_ sets it. - // TODO - what if this isn't a def in the last slot? Does it matter? + if (func.ir2.env.has_local_vars()) { + auto& ud_info = func.ir2.env.get_use_def_info(as_set->dst()); + if (i == int(ir->entries.size()) - 2) { + if (ud_info.def_count() == 1) { + // the final case of the or doesn't explicitly set the destination register. + // this can happen if the move is eliminated during coloring. + // for now, let's leave this last def here, just so it looks like _something_ sets it. + // TODO - what if this isn't a def in the last slot? Does it matter? + } else { + // lg::warn("Disabling def of {} in final or delay slot", + // as_set->to_string(func.ir2.env)); + func.ir2.env.disable_def(as_set->dst()); + } + } else { - // lg::warn("Disabling def of {} in final or delay slot", - // as_set->to_string(func.ir2.env)); + // lg::warn("Disabling def of {} in or delay slot", as_set->to_string(func.ir2.env)); func.ir2.env.disable_def(as_set->dst()); } - - } else { - // lg::warn("Disabling def of {} in or delay slot", as_set->to_string(func.ir2.env)); - func.ir2.env.disable_def(as_set->dst()); } if (i == 0) {