From 8215521843552fe692275dc81ad72b514888a8f1 Mon Sep 17 00:00:00 2001 From: orbitcowboy Date: Sat, 9 Jul 2022 19:59:16 +0200 Subject: [PATCH] Fixed zerodiv/moduloofone FNs for more math functions --- cfg/std.cfg | 24 +++++++++++------------ lib/programmemory.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++ test/cfg/std.cpp | 21 +++++++++++++++++++++ 3 files changed, 77 insertions(+), 12 deletions(-) diff --git a/cfg/std.cfg b/cfg/std.cfg index 951323811..6e01700c5 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -2119,7 +2119,7 @@ - + hypot(arg1, arg2) false @@ -2136,7 +2136,7 @@ - + hypot(arg1, arg2) false @@ -2150,7 +2150,7 @@ - + hypot(arg1, arg2) false @@ -2989,7 +2989,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + ldexp(arg1,arg2) false @@ -3003,7 +3003,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + ldexp(arg1,arg2) false @@ -3017,7 +3017,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + ldexp(arg1,arg2) false @@ -3031,7 +3031,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + lgamma(arg1) false @@ -3042,7 +3042,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + lgamma(arg1) false @@ -3053,7 +3053,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + lgamma(arg1) false @@ -3511,7 +3511,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + ilogb(arg1) false @@ -3522,7 +3522,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + ilogb(arg1) false @@ -3533,7 +3533,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + ilogb(arg1) false diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 53617c6ce..e81c8af53 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -642,6 +642,17 @@ static std::unordered_map createBuiltinLibr v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; }; + functions["lgamma"] = [](const std::vector& args) { + if (args.size() != 1) + return ValueFlow::Value::unknown(); + ValueFlow::Value v = args[0]; + if (!v.isFloatValue() && !v.isIntValue()) + return ValueFlow::Value::unknown(); + double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; + v.floatValue = std::lgamma(value); + v.valueType = ValueFlow::Value::ValueType::FLOAT; + return v; + }; functions["cos"] = [](const std::vector& args) { if (args.size() != 1) return ValueFlow::Value::unknown(); @@ -708,6 +719,17 @@ static std::unordered_map createBuiltinLibr v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; }; + functions["hypot"] = [](const std::vector& args) { + if (args.size() != 2) + return ValueFlow::Value::unknown(); + ValueFlow::Value v = args[0]; + if (!v.isFloatValue() && !v.isIntValue()) + return ValueFlow::Value::unknown(); + double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; + 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& args) { if (args.size() != 2) return ValueFlow::Value::unknown(); @@ -763,6 +785,28 @@ static std::unordered_map createBuiltinLibr v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; }; + functions["ldexp"] = [](const std::vector& args) { + if (args.size() != 2) + return ValueFlow::Value::unknown(); + ValueFlow::Value v = args[0]; + if (!v.isFloatValue() && !v.isIntValue()) + return ValueFlow::Value::unknown(); + double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; + v.floatValue = std::ldexp(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); + v.valueType = ValueFlow::Value::ValueType::FLOAT; + return v; + }; + functions["ilogb"] = [](const std::vector& args) { + if (args.size() != 1) + return ValueFlow::Value::unknown(); + ValueFlow::Value v = args[0]; + if (!v.isFloatValue() && !v.isIntValue()) + return ValueFlow::Value::unknown(); + double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; + v.intvalue = std::ilogb(value); + v.valueType = ValueFlow::Value::ValueType::INT; + return v; + }; functions["erf"] = [](const std::vector& args) { if (args.size() != 1) return ValueFlow::Value::unknown(); diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 0f6a1eef3..bdac23899 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -36,6 +36,27 @@ #include #include +int zerodiv_ldexp() +{ + int i = std::ldexp(0.0, 42.0); + // cppcheck-suppress zerodiv + return 42 / i; +} + +int zerodiv_ilogb() +{ + int i = std::ilogb(1.0); + // cppcheck-suppress zerodiv + return 42 / i; +} + +int zerodiv_hypot() +{ + int i = std::hypot(0.0, 0.0); + // cppcheck-suppress zerodiv + return 42 / i; +} + int zerodiv_fmod() { int i = std::fmod(0.0, 42.0);