Static Analysis: unassigned binops, bug fix, wording

pull/7/head
soad003 7 years ago
parent 25591ed824
commit fd4027994b
  1. 11
      remix-solidity/src/analysis/modules/assignAndCompare.js
  2. 13
      remix-solidity/src/analysis/modules/staticAnalysisCommon.js
  3. 2
      remix-solidity/test/analysis/staticAnalysisIntegration-test.js
  4. 2
      remix-solidity/test/analysis/test-contracts/blockLevelCompare.sol

@ -1,5 +1,5 @@
var name = 'Assign or Compare: ' var name = 'Result not used: '
var desc = 'Assign and compare operators can be confusing.' var desc = 'The result of an operation was not used.'
var categories = require('./categories') var categories = require('./categories')
var common = require('./staticAnalysisCommon') var common = require('./staticAnalysisCommon')
@ -8,15 +8,14 @@ function assignAndCompare () {
} }
assignAndCompare.prototype.visit = function (node) { assignAndCompare.prototype.visit = function (node) {
if (common.isBlockWithTopLevelUnAssignedBinOp(node)) this.warningNodes.push(node) if (common.isBlockWithTopLevelUnAssignedBinOp(node)) common.getUnAssignedTopLevelBinOps(node).forEach((n) => this.warningNodes.push(n))
} }
assignAndCompare.prototype.report = function (compilationResults) { assignAndCompare.prototype.report = function (compilationResults) {
return this.warningNodes.map(function (item, i) { return this.warningNodes.map(function (item, i) {
return { return {
warning: 'Use of "this" for local functions: Never use this to call functions in the same contract, it only consumes more gas than normal local calls.', warning: 'A binary operation yields a value that is not used in the following. This is often caused by confusing assignment (=) and comparison (==).',
location: item.src, location: item.src
more: 'http://solidity.readthedocs.io/en/develop/control-structures.html#external-function-calls'
} }
}) })
} }

@ -24,7 +24,8 @@ var nodeTypes = {
RETURN: 'Return', RETURN: 'Return',
IFSTATEMENT: 'IfStatement', IFSTATEMENT: 'IfStatement',
FORSTATEMENT: 'ForStatement', FORSTATEMENT: 'ForStatement',
WHILESTATEMENT: 'WhileStatement' WHILESTATEMENT: 'WhileStatement',
DOWHILESTATEMENT: 'DoWhileStatement'
} }
var basicTypes = { var basicTypes = {
@ -385,6 +386,10 @@ function getFullQuallyfiedFuncDefinitionIdent (contract, func, paramTypes) {
return getContractName(contract) + '.' + getFunctionDefinitionName(func) + '(' + util.concatWithSeperator(paramTypes, ',') + ')' return getContractName(contract) + '.' + getFunctionDefinitionName(func) + '(' + util.concatWithSeperator(paramTypes, ',') + ')'
} }
function getUnAssignedTopLevelBinOps (blocklike) {
return blocklike.children.filter(isBinaryOpInExpression)
}
// #################### Trivial Node Identification // #################### Trivial Node Identification
function isFunctionDefinition (node) { function isFunctionDefinition (node) {
@ -621,7 +626,10 @@ function isBlockWithTopLevelUnAssignedBinOp (node) {
} }
function isBlockLikeStatement (node) { function isBlockLikeStatement (node) {
return (nodeType(node, exactMatch(nodeTypes.IFSTATEMENT)) || nodeType(node, exactMatch(nodeTypes.FORSTATEMENT)) || nodeType(node, exactMatch(nodeTypes.WHILESTATEMENT))) && return (nodeType(node, exactMatch(nodeTypes.IFSTATEMENT)) ||
nodeType(node, exactMatch(nodeTypes.FORSTATEMENT)) ||
nodeType(node, exactMatch(nodeTypes.WHILESTATEMENT)) ||
nodeType(node, exactMatch(nodeTypes.DOWHILESTATEMENT))) &&
minNrOfChildren(node, 2) && !nodeType(node.children[1], exactMatch(nodeTypes.BLOCK)) minNrOfChildren(node, 2) && !nodeType(node.children[1], exactMatch(nodeTypes.BLOCK))
} }
@ -937,6 +945,7 @@ module.exports = {
getStateVariableDeclarationsFormContractNode: getStateVariableDeclarationsFormContractNode, getStateVariableDeclarationsFormContractNode: getStateVariableDeclarationsFormContractNode,
getFunctionOrModifierDefinitionParameterPart: getFunctionOrModifierDefinitionParameterPart, getFunctionOrModifierDefinitionParameterPart: getFunctionOrModifierDefinitionParameterPart,
getFunctionOrModifierDefinitionReturnParameterPart: getFunctionOrModifierDefinitionReturnParameterPart, getFunctionOrModifierDefinitionReturnParameterPart: getFunctionOrModifierDefinitionReturnParameterPart,
getUnAssignedTopLevelBinOps: getUnAssignedTopLevelBinOps,
// #################### Complex Node Identification // #################### Complex Node Identification
isDeleteOfDynamicArray: isDeleteOfDynamicArray, isDeleteOfDynamicArray: isDeleteOfDynamicArray,

@ -559,7 +559,7 @@ test('Integration test assignAndCompare.js', function (t) {
'forgottenReturn.sol': 0, 'forgottenReturn.sol': 0,
'selfdestruct.sol': 0, 'selfdestruct.sol': 0,
'deleteDynamicArray.sol': 0, 'deleteDynamicArray.sol': 0,
'blockLevelCompare.sol': 6 'blockLevelCompare.sol': 8
} }
runModuleOnFiles(module, t, (file, report) => { runModuleOnFiles(module, t, (file, report) => {

@ -32,11 +32,13 @@ contract grr {
while(false) { while(false) {
int c = 3; int c = 3;
uint(c) + a;
c == 5; c == 5;
} }
a + b;
breaker = false; breaker = false;
} }

Loading…
Cancel
Save