@@ -2100,187 +2100,6 @@ void CheckClass::selfInitializationError(const Token* tok, const std::string& va
21002100}
21012101
21022102
2103- // ---------------------------------------------------------------------------
2104- // Check for member usage before initialization in constructor
2105- // ---------------------------------------------------------------------------
2106-
2107- struct VarDependency {
2108- VarDependency (const Variable *_var, const Token *_tok)
2109- : var(_var), tok(_tok), initOrder(_var->index ()) { }
2110-
2111- VarDependency (const Variable *_var, const Token *_tok, std::size_t _initOrder)
2112- : var(_var), tok(_tok), initOrder(_initOrder) { }
2113-
2114- bool operator ==(const Variable* _rhs) const {
2115- return var == _rhs;
2116- }
2117-
2118- std::vector< VarInfo > dependencies;
2119- const Variable *var;
2120- const Token *tok;
2121- std::size_t initOrder;
2122- };
2123-
2124- void CheckClass::checkUsageBeforeInitialization ()
2125- {
2126- const std::size_t classes = symbolDatabase->classAndStructScopes .size ();
2127- std::vector< VarDependency > vars;
2128-
2129- for (std::size_t i = 0 ; i < classes; ++i) {
2130- const Scope * info = symbolDatabase->classAndStructScopes [i];
2131-
2132- // lets do some preallocation for the vector
2133- vars.reserve (info->varlist .size ());
2134-
2135- // iterate through all member functions looking for constructors
2136- for (std::list<Function>::const_iterator funcIter = info->functionList .cbegin (); funcIter != info->functionList .cend (); ++funcIter) {
2137- if (!(*funcIter).isConstructor () || !(*funcIter).hasBody ())
2138- continue ;
2139-
2140- vars.clear ();
2141- // check for initializer list
2142- const Token *tok = (*funcIter).arg ->link ()->next ();
2143- if (tok->str () == " :" ) {
2144- tok = tok->next ();
2145-
2146- // find all variable initializations in list
2147- while (tok && tok != (*funcIter).functionScope ->classStart ) {
2148- if (Token::Match (tok, " %name% (|{" )) {
2149- const Variable *var = tok->variable ();
2150-
2151- bool lhsIsReference = false ;
2152-
2153- if (var && (var->scope () == info)) {
2154- vars.push_back (VarDependency (var, tok));
2155- lhsIsReference = var->isReference ();
2156- } else { // Sanity check: Seems lhs is not a member of this class
2157- tok = tok->next ();
2158- continue ;
2159- }
2160-
2161- tok = tok->next ();
2162-
2163- const Token* tokEnd = tok->link ();
2164-
2165- if (tokEnd) {
2166- tok = tok->next ();
2167-
2168- while (tok && tok != tokEnd) {
2169- if (tok->str () == " &" ) { // treat adresses as always correct value (correct?)
2170- tok = tok->next ();
2171- } else {
2172- const Variable *dep = tok->variable ();
2173-
2174- if (dep && (dep->scope () == info) && !dep->isStatic () && (!lhsIsReference || dep->isReference ())) {
2175- if (tok->varId () == dep->nameToken ()->varId ()) {
2176- vars.back ().dependencies .push_back (VarInfo (dep, tok));
2177- }
2178- }
2179- }
2180- tok = tok->next ();
2181- }
2182- }
2183- } else {
2184- tok = tok->next ();
2185- }
2186- }
2187- }
2188-
2189- // report initialization list errors
2190- for (std::size_t j = 0 , j_max = vars.size (); j < j_max; ++j) {
2191- const std::vector< VarInfo >& deps = vars[j].dependencies ;
2192- const std::size_t init = vars[j].initOrder ;
2193- for (std::size_t k = 0 , k_max = deps.size (); k < k_max; ++k) {
2194- const VarInfo& varInfo = deps[k];
2195-
2196- if (init <= varInfo.var ->index ()) {
2197- usageBeforeInitializationError (varInfo.tok , info->className , varInfo.var ->name (), false );
2198- }
2199- }
2200- }
2201-
2202- // check constructor compound statement for initializations
2203- if (tok == (*funcIter).functionScope ->classStart ) {
2204- tok = tok->next ();
2205-
2206- while (tok && tok != (*funcIter).functionScope ->classEnd ) {
2207- if (Token::Match (tok, " %name% =" )) {
2208- const Variable *var = tok->variable ();
2209- const std::vector< VarDependency >::const_iterator currentEnd = vars.cend ();
2210-
2211- if (var && (var->scope () == info)) {
2212- const std::vector< VarDependency >::const_iterator depIter = std::find (vars.cbegin (), currentEnd, var);
2213- if (depIter == vars.cend ()) {
2214- vars.push_back (VarDependency (var, tok, vars.size ()));
2215- }
2216- }
2217-
2218- tok = tok->next ()->next ();
2219- while (tok && tok->str () != " ;" ) { // parse variables until end of assignment
2220- if (Token::Match (tok, " %name% =" )) { // cascading assignments
2221- const Variable *varRhs = tok->variable ();
2222-
2223- if (varRhs && (varRhs->scope () == info)) {
2224- if (tok->varId () == varRhs->nameToken ()->varId ()) {
2225- const std::vector< VarDependency >::const_iterator depIter = std::find (vars.cbegin (), vars.cend (), varRhs);
2226- if (depIter == vars.cend ()) {
2227- if (vars.size () > 0 ) {
2228- vars.push_back (VarDependency (varRhs, tok, vars.back ().initOrder ));
2229- } else {
2230- vars.push_back (VarDependency (varRhs, tok));
2231- }
2232- }
2233- }
2234- }
2235-
2236- tok = tok->next ()->next ();
2237- } else {
2238- bool isAddress = false ;
2239- if (tok->str () == " &" ) {
2240- isAddress = true ;
2241- tok = tok->next ();
2242- }
2243-
2244- const Variable *dep = tok->variable ();
2245-
2246-
2247- if (dep && (dep->scope () == info) && !(dep->isClass () || dep->isStatic () || dep->isReference () || isAddress)) {
2248- if (tok->varId () == dep->nameToken ()->varId ()) {
2249- const std::vector< VarDependency >::const_iterator depIter = std::find (vars.cbegin (), currentEnd, dep);
2250- if (depIter == currentEnd)
2251- usageBeforeInitializationError (tok, info->className , dep->name (), false );
2252- }
2253- }
2254-
2255- tok = tok->next ();
2256- }
2257- }
2258- } else if (Token::Match (tok, " %name% ++|--" )) { // check for post increment/decrement of unitialized members
2259- const Variable *var = tok->variable ();
2260-
2261- if (var && (var->scope () == info) && !(var->isClass () || var->isStatic ())) {
2262- if (tok->varId () == var->nameToken ()->varId ()) {
2263- const std::vector< VarDependency >::const_iterator depIter = std::find (vars.cbegin (), vars.cend (), var);
2264- if (depIter == vars.cend ())
2265- usageBeforeInitializationError (tok, info->className , var->name (), false );
2266- }
2267- }
2268-
2269- tok = tok->next ()->next ();
2270- } else
2271- tok = tok->next ();
2272- }
2273- }
2274- }
2275- }
2276- }
2277-
2278- void CheckClass::usageBeforeInitializationError (const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive)
2279- {
2280- reportError (tok, Severity::error, " usageBeforeInitialization" , " Member variable '" + classname + " ::" + varname + " ' is used before it is initialized." , inconclusive);
2281- }
2282-
2283-
22842103// ---------------------------------------------------------------------------
22852104// Check for pure virtual function calls
22862105// ---------------------------------------------------------------------------
0 commit comments