LCOV - code coverage report
Current view: top level - lib - programmemory.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 11 17 64.7 %
Date: 2024-04-28 12:00:40 Functions: 9 12 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Cppcheck - A tool for static C/C++ code analysis
       3             :  * Copyright (C) 2007-2024 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             : #ifndef GUARD_PROGRAMMEMORY_H
      20             : #define GUARD_PROGRAMMEMORY_H
      21             : 
      22             : #include "config.h"
      23             : #include "mathlib.h"
      24             : #include "vfvalue.h" // needed for alias
      25             : 
      26             : #include <cstddef>
      27             : #include <functional>
      28             : #include <map>
      29             : #include <string>
      30             : #include <unordered_map>
      31             : #include <utility>
      32             : #include <vector>
      33             : 
      34             : class Scope;
      35             : class Token;
      36             : class Settings;
      37             : 
      38             : // Class used to handle heterogeneous lookup in unordered_map(since we can't use C++20 yet)
      39             : struct ExprIdToken {
      40             :     const Token* tok = nullptr;
      41             :     nonneg int exprid = 0;
      42             : 
      43             :     ExprIdToken() = default;
      44             :     // cppcheck-suppress noExplicitConstructor
      45             :     // NOLINTNEXTLINE(google-explicit-constructor)
      46             :     ExprIdToken(const Token* tok);
      47             :     // TODO: Make this constructor only available from ProgramMemory
      48             :     // cppcheck-suppress noExplicitConstructor
      49             :     // NOLINTNEXTLINE(google-explicit-constructor)
      50     3422050 :     ExprIdToken(nonneg int exprid) : exprid(exprid) {}
      51             : 
      52             :     nonneg int getExpressionId() const;
      53             : 
      54     2490185 :     bool operator==(const ExprIdToken& rhs) const {
      55     2490185 :         return getExpressionId() == rhs.getExpressionId();
      56             :     }
      57             : 
      58             :     bool operator<(const ExprIdToken& rhs) const {
      59             :         return getExpressionId() < rhs.getExpressionId();
      60             :     }
      61             : 
      62             :     template<class T, class U>
      63     5187909 :     friend bool operator!=(const T& lhs, const U& rhs)
      64             :     {
      65     5187909 :         return !(lhs == rhs);
      66             :     }
      67             : 
      68             :     template<class T, class U>
      69             :     friend bool operator<=(const T& lhs, const U& rhs)
      70             :     {
      71             :         return !(lhs > rhs);
      72             :     }
      73             : 
      74             :     template<class T, class U>
      75             :     friend bool operator>(const T& lhs, const U& rhs)
      76             :     {
      77             :         return rhs < lhs;
      78             :     }
      79             : 
      80             :     template<class T, class U>
      81             :     friend bool operator>=(const T& lhs, const U& rhs)
      82             :     {
      83             :         return !(lhs < rhs);
      84             :     }
      85             : 
      86             :     const Token& operator*() const NOEXCEPT {
      87             :         return *tok;
      88             :     }
      89             : 
      90             :     const Token* operator->() const NOEXCEPT {
      91             :         return tok;
      92             :     }
      93             : 
      94             :     struct Hash {
      95             :         std::size_t operator()(ExprIdToken etok) const;
      96             :     };
      97             : };
      98             : 
      99             : struct ProgramMemory {
     100             :     using Map = std::unordered_map<ExprIdToken, ValueFlow::Value, ExprIdToken::Hash>;
     101             : 
     102      159523 :     ProgramMemory() = default;
     103             : 
     104        5957 :     explicit ProgramMemory(Map values) : mValues(std::move(values)) {}
     105             : 
     106             :     void setValue(const Token* expr, const ValueFlow::Value& value);
     107             :     const ValueFlow::Value* getValue(nonneg int exprid, bool impossible = false) const;
     108             : 
     109             :     bool getIntValue(nonneg int exprid, MathLib::bigint& result) const;
     110             :     void setIntValue(const Token* expr, MathLib::bigint value, bool impossible = false);
     111             : 
     112             :     bool getContainerSizeValue(nonneg int exprid, MathLib::bigint& result) const;
     113             :     bool getContainerEmptyValue(nonneg int exprid, MathLib::bigint& result) const;
     114             :     void setContainerSizeValue(const Token* expr, MathLib::bigint value, bool isEqual = true);
     115             : 
     116             :     void setUnknown(const Token* expr);
     117             : 
     118             :     bool getTokValue(nonneg int exprid, const Token*& result) const;
     119             :     bool hasValue(nonneg int exprid);
     120             : 
     121             :     const ValueFlow::Value& at(nonneg int exprid) const;
     122             :     ValueFlow::Value& at(nonneg int exprid);
     123             : 
     124             :     void erase_if(const std::function<bool(const ExprIdToken&)>& pred);
     125             : 
     126             :     void swap(ProgramMemory &pm);
     127             : 
     128             :     void clear();
     129             : 
     130             :     bool empty() const;
     131             : 
     132             :     void replace(ProgramMemory pm);
     133             : 
     134             :     void insert(const ProgramMemory &pm);
     135             : 
     136      212848 :     Map::iterator begin() {
     137      212848 :         return mValues.begin();
     138             :     }
     139             : 
     140      212849 :     Map::iterator end() {
     141      212849 :         return mValues.end();
     142             :     }
     143             : 
     144           0 :     Map::const_iterator begin() const {
     145           0 :         return mValues.begin();
     146             :     }
     147             : 
     148           0 :     Map::const_iterator end() const {
     149           0 :         return mValues.end();
     150             :     }
     151             : 
     152           0 :     friend bool operator==(const ProgramMemory& x, const ProgramMemory& y) {
     153           0 :         return x.mValues == y.mValues;
     154             :     }
     155             : 
     156             :     friend bool operator!=(const ProgramMemory& x, const ProgramMemory& y) {
     157             :         return x.mValues != y.mValues;
     158             :     }
     159             : 
     160             : private:
     161             :     Map mValues;
     162             : };
     163             : 
     164             : struct ProgramMemoryState {
     165             :     ProgramMemory state;
     166             :     std::map<nonneg int, const Token*> origins;
     167             :     const Settings* settings;
     168             : 
     169             :     explicit ProgramMemoryState(const Settings* s);
     170             : 
     171             :     void insert(const ProgramMemory &pm, const Token* origin = nullptr);
     172             :     void replace(ProgramMemory pm, const Token* origin = nullptr);
     173             : 
     174             :     void addState(const Token* tok, const ProgramMemory::Map& vars);
     175             : 
     176             :     void assume(const Token* tok, bool b, bool isEmpty = false);
     177             : 
     178             :     void removeModifiedVars(const Token* tok);
     179             : 
     180             :     ProgramMemory get(const Token* tok, const Token* ctx, const ProgramMemory::Map& vars) const;
     181             : };
     182             : 
     183             : std::vector<ValueFlow::Value> execute(const Scope* scope, ProgramMemory& pm, const Settings& settings);
     184             : 
     185             : void execute(const Token* expr,
     186             :              ProgramMemory& programMemory,
     187             :              MathLib::bigint* result,
     188             :              bool* error,
     189             :              const Settings& settings);
     190             : 
     191             : /**
     192             :  * Is condition always false when variable has given value?
     193             :  * \param condition   top ast token in condition
     194             :  * \param pm   program memory
     195             :  */
     196             : bool conditionIsFalse(const Token* condition, ProgramMemory pm, const Settings& settings);
     197             : 
     198             : /**
     199             :  * Is condition always true when variable has given value?
     200             :  * \param condition   top ast token in condition
     201             :  * \param pm   program memory
     202             :  */
     203             : bool conditionIsTrue(const Token* condition, ProgramMemory pm, const Settings& settings);
     204             : 
     205             : /**
     206             :  * Get program memory by looking backwards from given token.
     207             :  */
     208             : ProgramMemory getProgramMemory(const Token* tok, const Token* expr, const ValueFlow::Value& value, const Settings& settings);
     209             : 
     210             : ValueFlow::Value evaluateLibraryFunction(const std::unordered_map<nonneg int, ValueFlow::Value>& args,
     211             :                                          const std::string& returnValue,
     212             :                                          const Settings& settings,
     213             :                                          bool cpp);
     214             : 
     215             : #endif
     216             : 
     217             : 
     218             : 

Generated by: LCOV version 1.14