diff options
-rw-r--r-- | src/Makefile.files | 2 | ||||
-rw-r--r-- | src/analysis/analysis.cpp | 144 | ||||
-rw-r--r-- | src/analysis/analysis.h | 23 | ||||
-rw-r--r-- | src/analysis/collections.cpp | 172 | ||||
-rw-r--r-- | src/analysis/collections.h | 60 | ||||
-rw-r--r-- | src/analysis/expression.cpp | 1 | ||||
-rw-r--r-- | src/analysis/statement.cpp | 1 |
7 files changed, 237 insertions, 166 deletions
diff --git a/src/Makefile.files b/src/Makefile.files index 0c26ff4..c9e02a5 100644 --- a/src/Makefile.files +++ b/src/Makefile.files @@ -1,5 +1,7 @@ SRC = analysis/analysis.cpp \ analysis/analysis.h \ + analysis/collections.cpp \ + analysis/collections.h \ analysis/declaration.cpp \ analysis/declaration.h \ analysis/expression.cpp \ diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp index 5c73bc3..3433554 100644 --- a/src/analysis/analysis.cpp +++ b/src/analysis/analysis.cpp @@ -22,6 +22,7 @@ #include "command.h" #include "logger.h" +#include "analysis/collections.h" #include "analysis/declaration.h" #include "analysis/expression.h" #include "analysis/function.h" @@ -61,115 +62,6 @@ namespace Analysis { -// add variables null pointer checks -void addNeedCheckNullVars(WalkItem &wi, WalkItem &wo) -{ - FOR_EACH (it, wi.addNullVars) - { - wo.needCheckNullVars.insert(it); - wo.knownVars.insert(it); - } -} - -// remove one variable from null pointer checks -void removeNeedCheckNullVar(WalkItem &wi, std::string str) -{ - if (isIn(str, wi.needCheckNullVars)) - { - wi.needCheckNullVars.erase(str); - } - if (isIn(str, wi.addNullVars)) - { - wi.addNullVars.erase(str); - } - auto it2 = wi.linkedVars.find(str); - if (it2 != wi.linkedVars.end()) - { - const StringSet &linked = (*it2).second; - FOR_EACH (it3, linked) - { - if (isIn(it3, wi.needCheckNullVars)) - { - wi.needCheckNullVars.erase(it3); - } - if (isIn(it3, wi.addNullVars)) - { - wi.addNullVars.erase(it3); - } - } - } -} - -// remove vars from checks for null pointer with linked vars -void removeNeedCheckNullVarsSetAll(WalkItem &wi, std::set<std::string> &vars) -{ - FOR_EACH (it, vars) - { - // remove var if need - removeNeedCheckNullVar(wi, it); - // if need remove some linked var, search it parent, - // and remove all linked vars for this parent - auto it3 = wi.linkedReverseVars.find(it); - if (it3 != wi.linkedReverseVars.end()) - { - const std::string parent = (*it3).second; - //wi.linkedVars.erase(parent); - removeNeedCheckNullVar(wi, parent); - } - } -} - -// remove vars from checks for null pointer without linked vars -void removeNeedCheckNullVarsSet(WalkItem &wi, std::set<std::string> &vars) -{ - FOR_EACH (it, vars) - { - if (isIn(it, wi.needCheckNullVars)) - { - wi.needCheckNullVars.erase(it); - } - if (isIn(it, wi.addNullVars)) - { - wi.addNullVars.erase(it); - } - auto it2 = wi.linkedVars.find(it); - if (it2 != wi.linkedVars.end()) - { - const StringSet linked = (*it2).second; - std::string newParent = *(linked.begin()); - wi.linkedVars[newParent] = linked; - wi.linkedVars.erase(it); - wi.linkedVars[newParent].erase(newParent); - } - auto it3 = wi.linkedReverseVars.find(it); - if (it3 != wi.linkedReverseVars.end()) - { - wi.linkedReverseVars.erase(it); - } - } -} - -void addNullVar(WalkItem &wi, - const std::string &var) -{ - wi.addNullVars.insert(var); - wi.removeNullVars.erase(var); -} - -// link var to parent. (type var = parent) -void addLinkedVar(WalkItem &wi, - std::string parent, - const std::string &var) -{ - // found parent as already linked var. need change parent to real parent - if (isIn(parent, wi.linkedReverseVars)) - parent = wi.linkedReverseVars[parent]; - if (isNotIn(parent, wi.linkedVars)) - wi.linkedVars[parent] = std::set<std::string>(); - wi.linkedVars[parent].insert(var); - wi.linkedReverseVars[var] = parent; -} - void startWalkTree(Node *node) { WalkItem wi; @@ -277,40 +169,6 @@ Node *skipBackNop(Node *node) return node; } -// merger two checked for null var sets -void mergeNullChecked(WalkItem &wi1, WalkItem &wi2) -{ - wi1.checkedNullVars.insert(wi2.checkedNullVars.begin(), - wi2.checkedNullVars.end()); -} - -// merger two checked for non null var sets -void mergeNonNullChecked(WalkItem &wi1, WalkItem &wi2) -{ - wi1.checkedNonNullVars.insert(wi2.checkedNonNullVars.begin(), - wi2.checkedNonNullVars.end()); -} - -// intersect two checked for null sets -void intersectNullChecked(WalkItem &wi, WalkItem &wi1, WalkItem &wi2) -{ - FOR_EACH (it, wi1.checkedNullVars) - { - if (isIn(it, wi2.checkedNullVars)) - wi.checkedNullVars.insert(it); - } -} - -// intersect two checked for non null sets -void intersectNonNullChecked(WalkItem &wi, WalkItem &wi1, WalkItem &wi2) -{ - FOR_EACH (it, wi1.checkedNonNullVars) - { - if (isIn(it, wi2.checkedNonNullVars)) - wi.checkedNonNullVars.insert(it); - } -} - void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo) { if (!node) diff --git a/src/analysis/analysis.h b/src/analysis/analysis.h index 8b38823..032fa3a 100644 --- a/src/analysis/analysis.h +++ b/src/analysis/analysis.h @@ -38,32 +38,9 @@ namespace Analysis int findBackLocation(Node *node); - void addNullVar(WalkItem &wi, - const std::string &var); - - void addLinkedVar(WalkItem &wi, - std::string parent, - const std::string &var); - - void removeNeedCheckNullVar(WalkItem &wi, std::string str); - - void removeNeedCheckNullVarsSetAll(WalkItem &wi, - std::set<std::string> &vars); - - void removeNeedCheckNullVarsSet(WalkItem &wi, - std::set<std::string> &vars); - Node *skipNop(Node *node); Node *skipBackNop(Node *node); - - void mergeNullChecked(WalkItem &wi1, WalkItem &wi2); - - void mergeNonNullChecked(WalkItem &wi1, WalkItem &wi2); - - void intersectNullChecked(WalkItem &wi, WalkItem &wi1, WalkItem &wi2); - - void intersectNonNullChecked(WalkItem &wi, WalkItem &wi1, WalkItem &wi2); } #endif // ANALYSIS_ANALYSIS_H diff --git a/src/analysis/collections.cpp b/src/analysis/collections.cpp new file mode 100644 index 0000000..b53ba9a --- /dev/null +++ b/src/analysis/collections.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2015 Andrei Karas + * + * This file is part of Paranoid null checker. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "analysis/analysis.h" + +#include "analysis/walkitem.h" + +#include "localconsts.h" + +namespace Analysis +{ + +// add variables null pointer checks +void addNeedCheckNullVars(WalkItem &wi, WalkItem &wo) +{ + FOR_EACH (it, wi.addNullVars) + { + wo.needCheckNullVars.insert(it); + wo.knownVars.insert(it); + } +} + +// remove one variable from null pointer checks +void removeNeedCheckNullVar(WalkItem &wi, std::string str) +{ + if (isIn(str, wi.needCheckNullVars)) + { + wi.needCheckNullVars.erase(str); + } + if (isIn(str, wi.addNullVars)) + { + wi.addNullVars.erase(str); + } + auto it2 = wi.linkedVars.find(str); + if (it2 != wi.linkedVars.end()) + { + const StringSet &linked = (*it2).second; + FOR_EACH (it3, linked) + { + if (isIn(it3, wi.needCheckNullVars)) + { + wi.needCheckNullVars.erase(it3); + } + if (isIn(it3, wi.addNullVars)) + { + wi.addNullVars.erase(it3); + } + } + } +} + +// remove vars from checks for null pointer with linked vars +void removeNeedCheckNullVarsSetAll(WalkItem &wi, std::set<std::string> &vars) +{ + FOR_EACH (it, vars) + { + // remove var if need + removeNeedCheckNullVar(wi, it); + // if need remove some linked var, search it parent, + // and remove all linked vars for this parent + auto it3 = wi.linkedReverseVars.find(it); + if (it3 != wi.linkedReverseVars.end()) + { + const std::string parent = (*it3).second; + //wi.linkedVars.erase(parent); + removeNeedCheckNullVar(wi, parent); + } + } +} + +// remove vars from checks for null pointer without linked vars +void removeNeedCheckNullVarsSet(WalkItem &wi, std::set<std::string> &vars) +{ + FOR_EACH (it, vars) + { + if (isIn(it, wi.needCheckNullVars)) + { + wi.needCheckNullVars.erase(it); + } + if (isIn(it, wi.addNullVars)) + { + wi.addNullVars.erase(it); + } + auto it2 = wi.linkedVars.find(it); + if (it2 != wi.linkedVars.end()) + { + const StringSet linked = (*it2).second; + std::string newParent = *(linked.begin()); + wi.linkedVars[newParent] = linked; + wi.linkedVars.erase(it); + wi.linkedVars[newParent].erase(newParent); + } + auto it3 = wi.linkedReverseVars.find(it); + if (it3 != wi.linkedReverseVars.end()) + { + wi.linkedReverseVars.erase(it); + } + } +} + +void addNullVar(WalkItem &wi, + const std::string &var) +{ + wi.addNullVars.insert(var); + wi.removeNullVars.erase(var); +} + +// link var to parent. (type var = parent) +void addLinkedVar(WalkItem &wi, + std::string parent, + const std::string &var) +{ + // found parent as already linked var. need change parent to real parent + if (isIn(parent, wi.linkedReverseVars)) + parent = wi.linkedReverseVars[parent]; + if (isNotIn(parent, wi.linkedVars)) + wi.linkedVars[parent] = std::set<std::string>(); + wi.linkedVars[parent].insert(var); + wi.linkedReverseVars[var] = parent; +} + +// merger two checked for null var sets +void mergeNullChecked(WalkItem &wi1, WalkItem &wi2) +{ + wi1.checkedNullVars.insert(wi2.checkedNullVars.begin(), + wi2.checkedNullVars.end()); +} + +// merger two checked for non null var sets +void mergeNonNullChecked(WalkItem &wi1, WalkItem &wi2) +{ + wi1.checkedNonNullVars.insert(wi2.checkedNonNullVars.begin(), + wi2.checkedNonNullVars.end()); +} + +// intersect two checked for null sets +void intersectNullChecked(WalkItem &wi, WalkItem &wi1, WalkItem &wi2) +{ + FOR_EACH (it, wi1.checkedNullVars) + { + if (isIn(it, wi2.checkedNullVars)) + wi.checkedNullVars.insert(it); + } +} + +// intersect two checked for non null sets +void intersectNonNullChecked(WalkItem &wi, WalkItem &wi1, WalkItem &wi2) +{ + FOR_EACH (it, wi1.checkedNonNullVars) + { + if (isIn(it, wi2.checkedNonNullVars)) + wi.checkedNonNullVars.insert(it); + } +} + +} diff --git a/src/analysis/collections.h b/src/analysis/collections.h new file mode 100644 index 0000000..d8cdb9e --- /dev/null +++ b/src/analysis/collections.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2015 Andrei Karas + * + * This file is part of Paranoid null checker. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ANALYSIS_COLLECTIONS_H +#define ANALYSIS_COLLECTIONS_H + +#include "includes.h" + +#include <set> +#include <string> + +struct Node; +struct WalkItem; + +namespace Analysis +{ + void addNeedCheckNullVars(WalkItem &wi, + WalkItem &wo); + + void addNullVar(WalkItem &wi, + const std::string &var); + + void addLinkedVar(WalkItem &wi, + std::string parent, + const std::string &var); + + void removeNeedCheckNullVar(WalkItem &wi, std::string str); + + void removeNeedCheckNullVarsSetAll(WalkItem &wi, + std::set<std::string> &vars); + + void removeNeedCheckNullVarsSet(WalkItem &wi, + std::set<std::string> &vars); + + void mergeNullChecked(WalkItem &wi1, WalkItem &wi2); + + void mergeNonNullChecked(WalkItem &wi1, WalkItem &wi2); + + void intersectNullChecked(WalkItem &wi, WalkItem &wi1, WalkItem &wi2); + + void intersectNonNullChecked(WalkItem &wi, WalkItem &wi1, WalkItem &wi2); +} + +#endif // ANALYSIS_COLLECTIONS_H diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp index cd1cbe2..6cee09c 100644 --- a/src/analysis/expression.cpp +++ b/src/analysis/expression.cpp @@ -23,6 +23,7 @@ #include "logger.h" #include "analysis/analysis.h" +#include "analysis/collections.h" #include "analysis/function.h" #include "analysis/reports.h" #include "analysis/statement.h" diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp index 5791819..36b786f 100644 --- a/src/analysis/statement.cpp +++ b/src/analysis/statement.cpp @@ -23,6 +23,7 @@ #include "logger.h" #include "analysis/analysis.h" +#include "analysis/collections.h" #include "analysis/reports.h" #include "analysis/walkitem.h" |