Analysis: fix bugs found with Coverity
[scilab.git] / scilab / modules / ast / src / cpp / analysis / ConstraintManager.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "gvn/ConstraintManager.hxx"
14 #include "data/FunctionBlock.hxx"
15
16 namespace analysis
17 {
18 std::vector<std::shared_ptr<InferenceConstraint>> ConstraintManager::generalConstraints = init();
19
20 std::vector<std::shared_ptr<InferenceConstraint>> ConstraintManager::init()
21 {
22     std::vector<std::shared_ptr<InferenceConstraint>> v;
23     v.reserve(Kind::COUNT);
24     // Same dims => equality of 2 pairs of values
25     v.emplace_back(new SameDimsConstraint());
26     // Equality of values
27     v.emplace_back(new EqualConstraint());
28     // Positivity of a value
29     v.emplace_back(new PositiveConstraint());
30     // Strict positivity of a value
31     v.emplace_back(new StrictPositiveConstraint());
32     // Is a value greater than an other ?
33     v.emplace_back(new GreaterConstraint());
34     // Is a value strict greater than an other ?
35     v.emplace_back(new StrictGreaterConstraint());
36     // Valid index
37     v.emplace_back(new ValidIndexConstraint());
38     // Valid range
39     v.emplace_back(new ValidRangeConstraint());
40
41     return v;
42 }
43
44 ConstraintManager::ConstraintManager(FunctionBlock * _function, FunctionBlock * _parent) : parent(_parent ? & _parent->getConstraintManager() : nullptr), function(_function) { }
45
46 bool ConstraintManager::check(const MPolyConstraintSet & set, const std::vector<GVN::Value *> & values)
47 {
48     /*std::wcerr << set.constraints.begin()->poly << "::" << set.constraints.begin()->kind << std::endl;
49     for (const auto & v : values)
50     {
51     std::wcerr << "DEBUG1=" << *v << std::endl;
52     }*/
53     InferenceConstraint::Result res = set.check((parent && parent->function) ? parent->function->getGVN() : function->getGVN(), values);
54     switch (res)
55     {
56         case InferenceConstraint::Result::RESULT_TRUE:
57         {
58             mpConstraints.add(set);
59             set.applyConstraints(values);
60             return true;
61         }
62         case InferenceConstraint::Result::RESULT_FALSE:
63             return false;
64         case InferenceConstraint::Result::RESULT_DUNNO:
65         {
66             if (parent && parent->function)
67             {
68                 const bool ret = parent->check(set.getMPConstraints(values), parent->function->getInValues());
69                 if (ret)
70                 {
71                     mpConstraints.add(set);
72                     set.applyConstraints(values);
73                 }
74                 return ret;
75             }
76             else
77             {
78                 return false;
79             }
80         }
81     }
82 }
83
84 bool ConstraintManager::check(Kind kind, const std::vector<GVN::Value *> & values)
85 {
86     if (function)
87     {
88         const InferenceConstraint & ic = *generalConstraints[kind];
89         InferenceConstraint::Result res = ic.check(function->getGVN(), values);
90         //std::wcerr << "DEBUG2=" << res << std::endl;
91
92         switch (res)
93         {
94             case InferenceConstraint::Result::RESULT_TRUE:
95             {
96                 mpConstraints.add(ic.getMPConstraints(values));
97                 ic.applyConstraints(values);
98                 return true;
99             }
100             case InferenceConstraint::Result::RESULT_FALSE:
101                 return false;
102             case InferenceConstraint::Result::RESULT_DUNNO:
103             {
104                 MPolyConstraintSet set = ic.getMPConstraints(values);
105                 const bool ret = check(set, function->getInValues());
106                 if (ret)
107                 {
108                     mpConstraints.add(set);
109                     ic.applyConstraints(values);
110                 }
111                 return ret;
112             }
113         }
114     }
115
116     return false;
117 }
118
119 bool ConstraintManager::checkGlobalConstant(const symbol::Symbol & sym)
120 {
121     if (constantConstraints.find(sym) == constantConstraints.end())
122     {
123         // TODO: fix that !!!
124         const bool ret = true; //symbol::Context::getInstance()->isOriginalSymbol(sym);
125         if (ret)
126         {
127             ConstraintManager * cm = this;
128             while (cm)
129             {
130                 cm->constantConstraints.emplace(sym);
131                 cm = cm->parent;
132             }
133         }
134         return ret;
135     }
136     else
137     {
138         return true;
139     }
140 }
141
142 bool ConstraintManager::checkGlobalConstants(const std::set<symbol::Symbol> & gc)
143 {
144     for (const auto sym : gc)
145     {
146         if (!symbol::Context::getInstance()->isOriginalSymbol(sym))
147         {
148             return false;
149         }
150     }
151     return true;
152 }
153 }