diff --git a/src/analysis/unused_label.d b/src/analysis/unused_label.d index cc19779..be51701 100644 --- a/src/analysis/unused_label.d +++ b/src/analysis/unused_label.d @@ -89,6 +89,30 @@ class UnusedLabelCheck : BaseAnalyzer labelUsed(gotoStatement.label.text); } + override void visit(const AsmInstruction instr) + { + instr.accept(this); + + bool jmp; + if (instr.identifierOrIntegerOrOpcode.text.length) + jmp = instr.identifierOrIntegerOrOpcode.text[0] == 'j'; + + if (!jmp || instr.operands.operands.length != 1) + return; + + const AsmExp e = cast(AsmExp) instr.operands.operands[0]; + if (e.left && cast(const(AsmBrExp)) e.left) + { + const AsmBrExp b = cast(AsmBrExp) e.left; + if (b.asmUnaExp && b.asmUnaExp.asmPrimaryExp) + { + const AsmPrimaryExp p = b.asmUnaExp.asmPrimaryExp; + if (p && p.identifierChain && p.identifierChain.identifiers.length == 1) + labelUsed(p.identifierChain.identifiers[0].text); + } + } + } + private: static struct Label @@ -181,5 +205,21 @@ unittest } }c, sac); + assertAnalyzerWarnings(q{ + void testAsm() + { + asm { jmp lbl;} + lbl: + } + }c, sac); + + assertAnalyzerWarnings(q{ + void testAsm() + { + asm { mov RAX,1;} + lbl: // [warn]: Label "lbl" is not used. + } + }c, sac); + stderr.writeln("Unittest for UnusedLabelCheck passed."); }