Skip to content

Commit

Permalink
Merge branch 'replace_libdparse' into if-else-same
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladiwostok committed Dec 20, 2023
2 parents 1dc1619 + c3c7ee1 commit ddd30f7
Showing 1 changed file with 43 additions and 20 deletions.
63 changes: 43 additions & 20 deletions src/dscanner/analysis/unused_label.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import dmd.tokens;
/**
* Checks for labels that are never used.
*/
extern(C++) class UnusedLabelCheck(AST) : BaseAnalyzerDmd
extern (C++) class UnusedLabelCheck(AST) : BaseAnalyzerDmd
{
alias visit = BaseAnalyzerDmd.visit;
mixin AnalyzerInfo!"unused_label_check";

extern(D) this(string fileName, bool skipTests = false)
extern (D) this(string fileName, bool skipTests = false)
{
super(fileName, skipTests);
}
Expand All @@ -30,17 +30,18 @@ extern(C++) class UnusedLabelCheck(AST) : BaseAnalyzerDmd
override void visit(AST.LabelStatement ls)
{
Label* label = ls.ident.toString() in current;

if (label is null)
{
current[ls.ident.toString()] = Label(ls.ident.toString(), ls.loc.linnum, ls.loc.charnum, false);
current[ls.ident.toString()] = Label(ls.ident.toString(),
ls.loc.linnum, ls.loc.charnum, false);
}
else
{
label.line = ls.loc.linnum;
label.column = ls.loc.charnum;
}

super.visit(ls);
}

Expand All @@ -52,8 +53,6 @@ extern(C++) class UnusedLabelCheck(AST) : BaseAnalyzerDmd

override void visit(AST.BreakStatement bs)
{
import std.stdio : writeln;

if (bs.ident)
labelUsed(bs.ident.toString());
}
Expand Down Expand Up @@ -86,25 +85,38 @@ extern(C++) class UnusedLabelCheck(AST) : BaseAnalyzerDmd
super.visit(fd);
popScope();
}

override void visit(AST.AsmStatement as)
{
if (!as.tokens)
return;

// Look for jump instructions
bool jmp;
if (as.tokens[0].ident && as.tokens[0].ident.toString()[0] == 'j')
if (getFirstLetterOf(cast(char*) as.tokens[0].ptr) == 'j')
jmp = true;

// Last argument of the jmp instruction will be the label
Token *label;
Token* label;
for (label = as.tokens; label.next; label = label.next) {}

if (jmp && label.ident)
labelUsed(label.ident.toString());
}

private char getFirstLetterOf(char* str)
{
import std.ascii : isAlpha;

if (str is null)
return '\0';

while (str && !isAlpha(*str))
str++;

return *str;
}

private:

static struct Label
Expand All @@ -115,9 +127,9 @@ private:
bool used;
}

extern(D) Label[const(char)[]][] stack;
extern (D) Label[const(char)[]][] stack;

extern(D) auto ref current()
extern (D) auto ref current()
{
return stack[$ - 1];
}
Expand Down Expand Up @@ -146,7 +158,7 @@ private:
stack.length--;
}

extern(D) void labelUsed(const(char)[] name)
extern (D) void labelUsed(const(char)[] name)
{
Label* entry = name in current;
if (entry is null)
Expand All @@ -158,13 +170,13 @@ private:

unittest
{
import dscanner.analysis.helpers : assertAnalyzerWarnings = assertAnalyzerWarningsDMD;
import dscanner.analysis.helpers : assertAnalyzerWarningsDMD;
import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig;
import std.stdio : stderr;

StaticAnalysisConfig sac = disabledConfig();
sac.unused_label_check = Check.enabled;
assertAnalyzerWarnings(q{
assertAnalyzerWarningsDMD(q{
int testUnusedLabel()
{
int x = 0;
Expand Down Expand Up @@ -203,15 +215,15 @@ unittest
}
}c, sac);

assertAnalyzerWarnings(q{
assertAnalyzerWarningsDMD(q{
void testAsm()
{
asm { jmp lbl;}
lbl:
}
}c, sac);

assertAnalyzerWarnings(q{
assertAnalyzerWarningsDMD(q{
void testAsm()
{
asm { mov RAX,1;}
Expand All @@ -220,7 +232,7 @@ unittest
}c, sac);

// from std.math
assertAnalyzerWarnings(q{
assertAnalyzerWarningsDMD(q{
real polyImpl() {
asm {
jecxz return_ST;
Expand All @@ -229,7 +241,7 @@ unittest
}c, sac);

// a label might be hard to find, e.g. in a mixin
assertAnalyzerWarnings(q{
assertAnalyzerWarningsDMD(q{
real polyImpl() {
mixin("return_ST: return 1;");
asm {
Expand All @@ -238,5 +250,16 @@ unittest
}
}c, sac);

assertAnalyzerWarningsDMD(q{
void testAsm()
{
asm nothrow @nogc
{
"movgr2fcsr $r0,%0" :
: "r" (newState & (roundingMask | allExceptions));
}
}
}c, sac);

stderr.writeln("Unittest for UnusedLabelCheck passed.");
}
}

0 comments on commit ddd30f7

Please sign in to comment.