From 4f417b64a1ed774ccbfd357a95d7e62461c77b1a Mon Sep 17 00:00:00 2001 From: MoonlightSentinel Date: Sun, 26 Jan 2020 18:41:58 +0100 Subject: [PATCH] Fix #788: Enum value used inside __traits(...) flagged as unused --- src/dscanner/analysis/unused_variable.d | 42 ++++++++++++++++++++----- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/dscanner/analysis/unused_variable.d b/src/dscanner/analysis/unused_variable.d index 782e9df..5d1bf00 100644 --- a/src/dscanner/analysis/unused_variable.d +++ b/src/dscanner/analysis/unused_variable.d @@ -19,6 +19,12 @@ final class UnusedVariableCheck : UnusedIdentifierCheck mixin AnalyzerInfo!"unused_variable_check"; + /** + Ignore declarations which are allowed to be unused, e.g. inside of a + speculative compilation: __traits(compiles, { S s = 0; }) + **/ + uint ignoreDeclarations = 0; + /** * Params: * fileName = the name of the file being analyzed @@ -42,17 +48,30 @@ final class UnusedVariableCheck : UnusedIdentifierCheck autoDeclaration.accept(this); } + override void visit(const TraitsExpression traitsExp) + { + // issue #788: Enum values might be used inside of `__traits` expressions, e.g.: + // enum name = "abc"; + // __traits(hasMember, S, name); + ignoreDeclarations++; + traitsExp.templateArgumentList.accept(this); + ignoreDeclarations--; + } + override protected void popScope() { - foreach (uu; tree[$ - 1]) + if (!ignoreDeclarations) { - if (!uu.isRef && tree.length > 1) + foreach (uu; tree[$ - 1]) { - if (uu.uncertain) - continue; - immutable string errorMessage = "Variable " ~ uu.name ~ " is never used."; - addErrorMessage(uu.line, uu.column, - "dscanner.suspicious.unused_variable", errorMessage); + if (!uu.isRef && tree.length > 1) + { + if (uu.uncertain) + continue; + immutable string errorMessage = "Variable " ~ uu.name ~ " is never used."; + addErrorMessage(uu.line, uu.column, + "dscanner.suspicious.unused_variable", errorMessage); + } } } tree = tree[0 .. $ - 1]; @@ -124,6 +143,15 @@ final class UnusedVariableCheck : UnusedIdentifierCheck testValue.writeln; } + // Issue 788 + void traits() + { + enum fieldName = "abc"; + __traits(hasMember, S, fieldName); + + __traits(compiles, { int i = 2; }); + } + }c, sac); stderr.writeln("Unittest for UnusedVariableCheck passed."); }