parent
898ad314ab
commit
c340b6ae6c
|
@ -709,133 +709,145 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
|
|||
return v;
|
||||
};
|
||||
functions["atan2"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::atan2(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["remainder"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::remainder(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["nextafter"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::nextafter(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["nexttoward"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::nexttoward(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["hypot"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::hypot(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["fdim"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::fdim(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["fmax"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::fmax(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["fmin"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::fmin(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["fmod"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::fmod(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["pow"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::pow(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["scalbln"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::scalbln(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
};
|
||||
functions["ldexp"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||
if (args.size() != 2)
|
||||
return ValueFlow::Value::unknown();
|
||||
ValueFlow::Value v = args[0];
|
||||
if (!v.isFloatValue() && !v.isIntValue())
|
||||
if (args.size() != 2 || !std::all_of(args.begin(), args.end(), [](const ValueFlow::Value& v) {
|
||||
return v.isFloatValue() || v.isIntValue();
|
||||
}))
|
||||
return ValueFlow::Value::unknown();
|
||||
double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
|
||||
ValueFlow::Value v;
|
||||
combineValueProperties(args[0], args[1], &v);
|
||||
v.floatValue = std::ldexp(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
|
||||
v.valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||
return v;
|
||||
|
|
|
@ -500,7 +500,7 @@ static bool isNumeric(const ValueFlow::Value& value) {
|
|||
return value.isIntValue() || value.isFloatValue();
|
||||
}
|
||||
|
||||
static void combineValueProperties(const ValueFlow::Value &value1, const ValueFlow::Value &value2, ValueFlow::Value *result)
|
||||
void combineValueProperties(const ValueFlow::Value &value1, const ValueFlow::Value &value2, ValueFlow::Value *result)
|
||||
{
|
||||
if (value1.isKnown() && value2.isKnown())
|
||||
result->setKnown();
|
||||
|
|
|
@ -535,4 +535,6 @@ CPPCHECKLIB std::vector<ValueFlow::Value> getLifetimeObjValues(const Token* tok,
|
|||
|
||||
const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScope = nullptr, bool smallest = true);
|
||||
|
||||
void combineValueProperties(const ValueFlow::Value& value1, const ValueFlow::Value& value2, ValueFlow::Value* result);
|
||||
|
||||
#endif // valueflowH
|
||||
|
|
|
@ -10347,6 +10347,12 @@ private:
|
|||
" }\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f(int i, int j) {\n" // #11191
|
||||
" const int c = pow(2, i);\n"
|
||||
" if (j % c) {}\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void sameExpressionPointers() {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue