prevent a case of false detection for auto functions
This commit is contained in:
parent
f283650c12
commit
55a6b2a758
|
@ -30,6 +30,7 @@ private:
|
||||||
|
|
||||||
bool[] _returns;
|
bool[] _returns;
|
||||||
size_t _mixinDepth;
|
size_t _mixinDepth;
|
||||||
|
string[] _literalWithReturn;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -93,10 +94,62 @@ public:
|
||||||
override void visit(const(PrimaryExpression) exp)
|
override void visit(const(PrimaryExpression) exp)
|
||||||
{
|
{
|
||||||
exp.accept(this);
|
exp.accept(this);
|
||||||
|
|
||||||
|
import std.algorithm.searching : canFind;
|
||||||
|
|
||||||
|
if (_returns.length && _mixinDepth)
|
||||||
|
{
|
||||||
|
if (findReturnInLiteral(exp.primary.text))
|
||||||
|
_returns[$-1] = true;
|
||||||
|
else if (exp.identifierOrTemplateInstance &&
|
||||||
|
_literalWithReturn.canFind(exp.identifierOrTemplateInstance.identifier.text))
|
||||||
|
_returns[$-1] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool findReturnInLiteral(const(string) value)
|
||||||
|
{
|
||||||
import std.algorithm.searching : find;
|
import std.algorithm.searching : find;
|
||||||
import std.range : empty;
|
import std.range : empty;
|
||||||
if (_returns.length && _mixinDepth && !exp.primary.text.find("return").empty)
|
|
||||||
_returns[$-1] = true;
|
return value == "return" || !value.find("return ").empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stringliteralHasReturn(const(NonVoidInitializer) nvi)
|
||||||
|
{
|
||||||
|
bool result;
|
||||||
|
if (!nvi.assignExpression || (cast(UnaryExpression) nvi.assignExpression) is null)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
const(UnaryExpression) u = cast(UnaryExpression) nvi.assignExpression;
|
||||||
|
if (u.primaryExpression &&
|
||||||
|
u.primaryExpression.primary.type.isStringLiteral &&
|
||||||
|
findReturnInLiteral(u.primaryExpression.primary.text))
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void visit(const(AutoDeclaration) decl)
|
||||||
|
{
|
||||||
|
decl.accept(this);
|
||||||
|
|
||||||
|
foreach(const(AutoDeclarationPart) p; decl.parts)
|
||||||
|
if (p.initializer &&
|
||||||
|
p.initializer.nonVoidInitializer &&
|
||||||
|
stringliteralHasReturn(p.initializer.nonVoidInitializer))
|
||||||
|
_literalWithReturn ~= p.identifier.text.idup;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void visit(const(VariableDeclaration) decl)
|
||||||
|
{
|
||||||
|
decl.accept(this);
|
||||||
|
|
||||||
|
foreach(const(Declarator) d; decl.declarators)
|
||||||
|
if (d.initializer &&
|
||||||
|
d.initializer.nonVoidInitializer &&
|
||||||
|
stringliteralHasReturn(d.initializer.nonVoidInitializer))
|
||||||
|
_literalWithReturn ~= d.name.text.idup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,5 +216,10 @@ unittest
|
||||||
AutoFunctionChecker.MESSAGE,
|
AutoFunctionChecker.MESSAGE,
|
||||||
), sac);
|
), sac);
|
||||||
|
|
||||||
|
assertAnalyzerWarnings(q{
|
||||||
|
enum _genSave = "return true;";
|
||||||
|
auto doStuff(){ mixin(_genSave);}
|
||||||
|
}, sac);
|
||||||
|
|
||||||
stderr.writeln("Unittest for AutoFunctionChecker passed.");
|
stderr.writeln("Unittest for AutoFunctionChecker passed.");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue