This commit is contained in:
parent
289481182a
commit
54dca3c4da
|
@ -1 +1 @@
|
||||||
Subproject commit 4bf4e5aa09453570121134a819a4f436275fe3f7
|
Subproject commit c5b458b518ec26c6a59b3d16ffb39d10fe121d27
|
|
@ -106,5 +106,8 @@ struct StaticAnalysisConfig
|
||||||
bool auto_ref_assignment_check;
|
bool auto_ref_assignment_check;
|
||||||
|
|
||||||
@INI("Checks for incorrect infinite range definitions")
|
@INI("Checks for incorrect infinite range definitions")
|
||||||
bool incorrect_infinite_range;
|
bool incorrect_infinite_range_check;
|
||||||
|
|
||||||
|
@INI("Checks for asserts that are always true")
|
||||||
|
bool useless_assert_check;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ import analysis.label_var_same_name_check;
|
||||||
import analysis.line_length;
|
import analysis.line_length;
|
||||||
import analysis.auto_ref_assignment;
|
import analysis.auto_ref_assignment;
|
||||||
import analysis.incorrect_infinite_range;
|
import analysis.incorrect_infinite_range;
|
||||||
|
import analysis.useless_assert;
|
||||||
|
|
||||||
import dsymbol.string_interning : internString;
|
import dsymbol.string_interning : internString;
|
||||||
import dsymbol.scope_;
|
import dsymbol.scope_;
|
||||||
|
@ -264,7 +265,10 @@ MessageSet analyze(string fileName, const Module m,
|
||||||
checks ~= new LineLengthCheck(fileName, tokens);
|
checks ~= new LineLengthCheck(fileName, tokens);
|
||||||
if (analysisConfig.auto_ref_assignment_check)
|
if (analysisConfig.auto_ref_assignment_check)
|
||||||
checks ~= new AutoRefAssignmentCheck(fileName);
|
checks ~= new AutoRefAssignmentCheck(fileName);
|
||||||
|
if (analysisConfig.incorrect_infinite_range_check)
|
||||||
checks ~= new IncorrectInfiniteRangeCheck(fileName);
|
checks ~= new IncorrectInfiniteRangeCheck(fileName);
|
||||||
|
if (analysisConfig.useless_assert_check)
|
||||||
|
checks ~= new UselessAssertCheck(fileName);
|
||||||
version (none)
|
version (none)
|
||||||
if (analysisConfig.redundant_if_check)
|
if (analysisConfig.redundant_if_check)
|
||||||
checks ~= new IfStatementCheck(fileName, moduleScope);
|
checks ~= new IfStatementCheck(fileName, moduleScope);
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
// Copyright Brian Schott (Hackerpilot) 2015.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
module analysis.useless_assert;
|
||||||
|
|
||||||
|
import analysis.base;
|
||||||
|
import analysis.helpers;
|
||||||
|
import dparse.ast;
|
||||||
|
import dparse.lexer;
|
||||||
|
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for asserts that always succeed
|
||||||
|
*/
|
||||||
|
class UselessAssertCheck : BaseAnalyzer
|
||||||
|
{
|
||||||
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
|
///
|
||||||
|
this(string fileName)
|
||||||
|
{
|
||||||
|
super(fileName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void visit(const AssertExpression ae)
|
||||||
|
{
|
||||||
|
import std.conv : to;
|
||||||
|
|
||||||
|
UnaryExpression unary = cast(UnaryExpression) ae.assertion;
|
||||||
|
if (unary is null)
|
||||||
|
{
|
||||||
|
stderr.writeln("unary is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unary.primaryExpression is null)
|
||||||
|
return;
|
||||||
|
immutable token = unary.primaryExpression.primary;
|
||||||
|
immutable skipSwitch = unary.primaryExpression.arrayLiteral !is null
|
||||||
|
|| unary.primaryExpression.assocArrayLiteral !is null
|
||||||
|
|| unary.primaryExpression.functionLiteralExpression !is null;
|
||||||
|
if (!skipSwitch) switch (token.type)
|
||||||
|
{
|
||||||
|
case tok!"doubleLiteral":
|
||||||
|
if (!token.text.to!double)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case tok!"floatLiteral":
|
||||||
|
if (!token.text.to!float)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case tok!"idoubleLiteral":
|
||||||
|
case tok!"ifloatLiteral":
|
||||||
|
case tok!"irealLiteral":
|
||||||
|
return; // `to` doesn't support imaginary numbers
|
||||||
|
case tok!"intLiteral":
|
||||||
|
if (!token.text.to!int)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case tok!"longLiteral":
|
||||||
|
if (!token.text.to!long)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case tok!"realLiteral":
|
||||||
|
if (!token.text.to!real)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case tok!"uintLiteral":
|
||||||
|
if (!token.text.to!uint)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case tok!"ulongLiteral":
|
||||||
|
if (!token.text.to!ulong)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case tok!"characterLiteral":
|
||||||
|
if (token.text == `'\0'`)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case tok!"dstringLiteral":
|
||||||
|
case tok!"stringLiteral":
|
||||||
|
case tok!"wstringLiteral":
|
||||||
|
case tok!"true":
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addErrorMessage(ae.line, ae.column, KEY, "Assert condition is always true");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum string KEY = "dscanner.suspicious.useless_assert";
|
||||||
|
}
|
Loading…
Reference in New Issue