Cppcheck
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
executionpath.h
Go to the documentation of this file.
1 /*
2  * Cppcheck - A tool for static C/C++ code analysis
3  * Copyright (C) 2007-2015 Daniel Marjamäki and Cppcheck team.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 //---------------------------------------------------------------------------
20 #ifndef executionpathH
21 #define executionpathH
22 //---------------------------------------------------------------------------
23 
24 #include <list>
25 #include "config.h"
26 
27 class Token;
28 class Check;
29 class SymbolDatabase;
30 
31 /**
32  * Base class for Execution Paths checking
33  * An execution path is a linear list of statements. There are no "if"/.. to worry about.
34  **/
36 private:
37  /** No implementation */
38  ExecutionPath();
39  ExecutionPath& operator=(const ExecutionPath &);
40 
41 protected:
42  Check * const owner;
43 
44  /** Are two execution paths equal? */
45  virtual bool is_equal(const ExecutionPath *) const = 0;
46 
47 public:
48  ExecutionPath(Check *c, unsigned int id) : owner(c), numberOfIf(0), varId(id) {
49  }
50 
51  virtual ~ExecutionPath() {
52  }
53 
54  /** Implement this in each derived class. This function must create a copy of the current instance */
55  virtual ExecutionPath *copy() = 0;
56 
57  /** print checkdata */
58  void print() const;
59 
60  /** number of if blocks */
61  unsigned int numberOfIf;
62 
63  const unsigned int varId;
64 
65  /**
66  * bail out all execution paths
67  * @param checks the execution paths to bail out on
68  **/
69  static void bailOut(std::list<ExecutionPath *> &checks) {
70  while (!checks.empty()) {
71  delete checks.back();
72  checks.pop_back();
73  }
74  }
75 
76  /**
77  * bail out execution paths with given variable id
78  * @param checks the execution paths to bail out on
79  * @param varid the specific variable id
80  **/
81  static void bailOutVar(std::list<ExecutionPath *> &checks, const unsigned int varid) {
82  if (varid == 0)
83  return;
84 
85  std::list<ExecutionPath *>::iterator it = checks.begin();
86  while (it != checks.end()) {
87  if ((*it)->varId == varid) {
88  delete *it;
89  checks.erase(it++);
90  } else {
91  ++it;
92  }
93  }
94  }
95 
96  /**
97  * Parse tokens at given location
98  * @param tok token to parse
99  * @param checks The execution paths. All execution paths in the list are executed in the current scope.
100  * @return the token before the "next" token.
101  **/
102  virtual const Token *parse(const Token &tok, std::list<ExecutionPath *> &checks) const = 0;
103 
104  /**
105  * Parse condition
106  * @param tok first token in condition.
107  * @param checks The execution paths. All execution paths in the list are executed in the current scope
108  * @return true => bail out all checking
109  **/
110  virtual bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks);
111 
112  /**
113  * Parse loop body
114  * @param tok the first token in the loop body (the token after the {)
115  * @param checks The execution paths
116  */
117  virtual void parseLoopBody(const Token *tok, std::list<ExecutionPath *> &checks) const {
118  (void)tok;
119  (void)checks;
120  }
121 
122  /** going out of scope - all execution paths end */
123  virtual void end(const std::list<ExecutionPath *> & /*checks*/, const Token * /*tok*/) const {
124  }
125 
126  bool operator==(const ExecutionPath &e) const {
127  return bool(varId == e.varId && is_equal(&e));
128  }
129 
130  static void checkScope(const Token *tok, std::list<ExecutionPath *> &checks);
131 };
132 
133 
134 void checkExecutionPaths(const SymbolDatabase *symbolDatabase, ExecutionPath *c);
135 
136 //---------------------------------------------------------------------------
137 #endif // executionpathH