diff --git a/decompiler/IR2/Form.cpp b/decompiler/IR2/Form.cpp index 7acfc350e6..757b73192f 100644 --- a/decompiler/IR2/Form.cpp +++ b/decompiler/IR2/Form.cpp @@ -1798,6 +1798,7 @@ DerefElement::DerefElement(Form* base, bool is_addr_of, DerefToken token) x.expr()->parent_element = this; } } + inline_nested(); } DerefElement::DerefElement(Form* base, bool is_addr_of, std::vector tokens) @@ -1808,6 +1809,7 @@ DerefElement::DerefElement(Form* base, bool is_addr_of, std::vector x.expr()->parent_element = this; } } + inline_nested(); } goos::Object DerefElement::to_form_internal(const Env& env) const { diff --git a/decompiler/IR2/FormExpressionAnalysis.cpp b/decompiler/IR2/FormExpressionAnalysis.cpp index 865ed1d581..b7a8252176 100644 --- a/decompiler/IR2/FormExpressionAnalysis.cpp +++ b/decompiler/IR2/FormExpressionAnalysis.cpp @@ -3382,10 +3382,12 @@ void ArrayFieldAccess::update_with_val(Form* new_val, if (m_expected_stride == 1) { // reg0 is idx auto reg0_matcher = - Matcher::match_or({Matcher::cast("int", Matcher::any(0)), Matcher::any(0)}); + Matcher::match_or({Matcher::cast("int", Matcher::any(0)), + Matcher::cast("uint", Matcher::any(0)), Matcher::any(0)}); // reg1 is base auto reg1_matcher = - Matcher::match_or({Matcher::cast("int", Matcher::any(1)), Matcher::any(1)}); + Matcher::match_or({Matcher::cast("int", Matcher::any(1)), + Matcher::cast("uint", Matcher::any(1)), Matcher::any(1)}); auto matcher = Matcher::fixed_op(FixedOperatorKind::ADDITION, {reg0_matcher, reg1_matcher}); auto match_result = match(matcher, new_val); if (!match_result.matched) { diff --git a/decompiler/ObjectFile/ObjectFileDB_IR2.cpp b/decompiler/ObjectFile/ObjectFileDB_IR2.cpp index 86db7687b4..90fe38ef8c 100644 --- a/decompiler/ObjectFile/ObjectFileDB_IR2.cpp +++ b/decompiler/ObjectFile/ObjectFileDB_IR2.cpp @@ -854,8 +854,8 @@ std::string ObjectFileDB::ir2_function_to_string(ObjectFileData& data, Function& auto& op = func.get_atomic_op_at_instr(instr_id); op_id = func.ir2.atomic_ops->instruction_to_atomic_op.at(instr_id); append_commented(line, printed_comment, - op.to_form(data.linked_data.labels, func.ir2.env).print() + "[" + - std::to_string(op_id) + "]"); + fmt::format("[{:3d}] {}", op_id, + op.to_form(data.linked_data.labels, func.ir2.env).print())); if (func.ir2.env.has_type_analysis()) { append_commented( diff --git a/decompiler/analysis/cfg_builder.cpp b/decompiler/analysis/cfg_builder.cpp index f8dd50d2e9..998e2553cf 100644 --- a/decompiler/analysis/cfg_builder.cpp +++ b/decompiler/analysis/cfg_builder.cpp @@ -537,6 +537,13 @@ bool try_splitting_nested_sc(FormPool& pool, Function& func, ShortCircuitElement assert(ir->entries.front().branch_delay.has_value()); bool first_is_and = delay_slot_sets_false(first_branch.first, *ir->entries.front().branch_delay); bool first_is_or = delay_slot_sets_truthy(first_branch.first, *ir->entries.front().branch_delay); + + if (first_is_and == first_is_or) { + throw std::runtime_error(fmt::format( + "Failed to split nested sc. This may mean that abs/ash/type-of was misrecognized as " + "and/or:\n{}", + ir->to_string(func.ir2.env))); + } assert(first_is_and != first_is_or); // one or the other but not both! int first_different = -1; // the index of the first one that's different. diff --git a/test/decompiler/reference/engine/geometry/vol-h_REF.gc b/test/decompiler/reference/engine/geometry/vol-h_REF.gc index 1dcb91648d..c17d34e827 100644 --- a/test/decompiler/reference/engine/geometry/vol-h_REF.gc +++ b/test/decompiler/reference/engine/geometry/vol-h_REF.gc @@ -115,11 +115,11 @@ ) (when (>= s4-0 0) (let ((s3-0 s4-0) - (s2-0 (-> (-> (the-as res-lump s5-1) tag) s4-0)) + (s2-0 (-> (the-as res-lump s5-1) tag s4-0)) ) (let ((v1-10 0)) ) - (while (= (-> s2-0 name) (-> (-> (the-as res-lump s5-1) tag) s4-0 name)) + (while (= (-> s2-0 name) (-> (the-as res-lump s5-1) tag s4-0 name)) (let ((v1-12 (make-property-data @@ -145,7 +145,7 @@ (+ (-> (the-as vol-control gp-0) pos-vol-count) 1) ) (+! s3-0 1) - (set! s2-0 (-> (-> (the-as res-lump s5-1) tag) s3-0)) + (set! s2-0 (-> (the-as res-lump s5-1) tag s3-0)) ) ) ) @@ -165,11 +165,11 @@ ) (when (>= s4-1 0) (let ((s3-1 s4-1) - (s2-1 (-> (-> (the-as res-lump s5-2) tag) s4-1)) + (s2-1 (-> (the-as res-lump s5-2) tag s4-1)) ) (let ((v1-29 0)) ) - (while (= (-> s2-1 name) (-> (-> (the-as res-lump s5-2) tag) s4-1 name)) + (while (= (-> s2-1 name) (-> (the-as res-lump s5-2) tag s4-1 name)) (let ((v1-31 (make-property-data @@ -195,7 +195,7 @@ (+ (-> (the-as vol-control gp-0) neg-vol-count) 1) ) (+! s3-1 1) - (set! s2-1 (-> (-> (the-as res-lump s5-2) tag) s3-1)) + (set! s2-1 (-> (the-as res-lump s5-2) tag s3-1)) ) ) ) diff --git a/test/decompiler/reference/engine/target/joint-mod-h_REF.gc b/test/decompiler/reference/engine/target/joint-mod-h_REF.gc index 42b0457fd2..6d62003c90 100644 --- a/test/decompiler/reference/engine/target/joint-mod-h_REF.gc +++ b/test/decompiler/reference/engine/target/joint-mod-h_REF.gc @@ -88,7 +88,7 @@ ) ) (set! (-> obj process) proc) - (set! (-> obj joint) (-> (-> proc node-list) data joint-idx)) + (set! (-> obj joint) (-> proc node-list data joint-idx)) (set-mode! obj mode) (let ((twist-max (-> obj twist-max))) (set! (-> twist-max x) 8192.0) @@ -398,7 +398,7 @@ ) (set! sv-52 - (vector-normalize! (-> (-> csp bone) transform vector (-> gp-0 nose)) 1.0) + (vector-normalize! (-> csp bone transform vector (-> gp-0 nose)) 1.0) ) (let ((t9-3 vector-normalize!) (a0-5 (new 'stack-no-clear 'vector)) @@ -974,7 +974,7 @@ (set! (-> v1-2 z) 0.0) (set! (-> v1-2 w) 1.0) ) - (let ((v1-5 (-> (-> arg0 node-list) data arg1))) + (let ((v1-5 (-> arg0 node-list data arg1))) (set! (-> v1-5 param0) joint-mod-wheel-callback) (set! (-> v1-5 param1) v0-0) ) @@ -1059,7 +1059,7 @@ (set! (-> v0-0 transform trans quad) (-> *null-vector* quad)) (set! (-> v0-0 transform rot quad) (-> *null-vector* quad)) (set! (-> v0-0 transform scale quad) (-> *identity-vector* quad)) - (let ((v1-8 (-> (-> arg0 node-list) data arg1))) + (let ((v1-8 (-> arg0 node-list data arg1))) (set! (-> v1-8 param0) joint-mod-set-local-callback) (set! (-> v1-8 param1) v0-0) ) @@ -1122,7 +1122,7 @@ (set! (-> v0-0 transform trans quad) (-> *null-vector* quad)) (set! (-> v0-0 transform rot quad) (-> *null-vector* quad)) (set! (-> v0-0 transform scale quad) (-> *identity-vector* quad)) - (let ((v1-7 (-> (-> arg0 node-list) data arg1))) + (let ((v1-7 (-> arg0 node-list data arg1))) (set! (-> v1-7 param0) joint-mod-set-world-callback) (set! (-> v1-7 param1) v0-0) ) @@ -1216,7 +1216,7 @@ (set! (-> v0-0 transform trans quad) (-> *null-vector* quad)) (set! (-> v0-0 transform rot quad) (-> *null-vector* quad)) (set! (-> v0-0 transform scale quad) (-> *identity-vector* quad)) - (let ((v1-7 (-> (-> arg0 node-list) data arg1))) + (let ((v1-7 (-> arg0 node-list data arg1))) (set! (-> v1-7 param0) joint-mod-blend-local-callback) (set! (-> v1-7 param1) v0-0) ) @@ -1301,7 +1301,7 @@ (set! (-> v0-0 spin-rate) arg3) (set! (-> v0-0 enable) #t) (set! (-> v0-0 angle) 0.0) - (let ((v1-6 (-> (-> arg0 node-list) data arg1))) + (let ((v1-6 (-> arg0 node-list data arg1))) (set! (-> v1-6 param0) joint-mod-spinner-callback) (set! (-> v1-6 param1) v0-0) ) diff --git a/test/decompiler/test_FormExpressionBuildLong.cpp b/test/decompiler/test_FormExpressionBuildLong.cpp index 29c85b88de..5459e0b926 100644 --- a/test/decompiler/test_FormExpressionBuildLong.cpp +++ b/test/decompiler/test_FormExpressionBuildLong.cpp @@ -2836,7 +2836,7 @@ TEST_F(FormRegressionTest, Method19ResTag) { " (->\n" " (the-as\n" " (pointer uint64)\n" - " (-> (symbol->string (-> (-> arg0 tag) t5-2 name)) data)\n" + " (-> (symbol->string (-> arg0 tag t5-2 name)) data)\n" " )\n" " 0\n" " )\n" @@ -2873,7 +2873,7 @@ TEST_F(FormRegressionTest, Method19ResTag) { " (->\n" " (the-as\n" " (pointer uint64)\n" - " (-> (symbol->string (-> (-> arg0 tag) (+ t4-1 -1) name)) data)\n" + " (-> (symbol->string (-> arg0 tag (+ t4-1 -1) name)) data)\n" " )\n" " 0\n" " )\n"