| 717 | |
| 718 | using BuiltinLibraryFunction = std::function<ValueFlow::Value (const std::vector<ValueFlow::Value>&)>; |
| 719 | static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibraryFunctions() |
| 720 | { |
| 721 | std::unordered_map<std::string, BuiltinLibraryFunction> functions; |
| 722 | functions["strlen"] = [](const std::vector<ValueFlow::Value>& args) { |
| 723 | if (args.size() != 1) |
| 724 | return ValueFlow::Value::unknown(); |
| 725 | const ValueFlow::Value& v_ref = args[0]; |
| 726 | if (!(v_ref.isTokValue() && v_ref.tokvalue->tokType() == Token::eString)) |
| 727 | return ValueFlow::Value::unknown(); |
| 728 | ValueFlow::Value v = v_ref; |
| 729 | v.valueType = ValueFlow::Value::ValueType::INT; |
| 730 | v.intvalue = Token::getStrLength(v.tokvalue); |
| 731 | v.tokvalue = nullptr; |
| 732 | return v; |
| 733 | }; |
| 734 | functions["strcmp"] = [](const std::vector<ValueFlow::Value>& args) { |
| 735 | if (args.size() != 2) |
| 736 | return ValueFlow::Value::unknown(); |
| 737 | const ValueFlow::Value& lhs = args[0]; |
| 738 | if (!(lhs.isTokValue() && lhs.tokvalue->tokType() == Token::eString)) |
| 739 | return ValueFlow::Value::unknown(); |
| 740 | const ValueFlow::Value& rhs = args[1]; |
| 741 | if (!(rhs.isTokValue() && rhs.tokvalue->tokType() == Token::eString)) |
| 742 | return ValueFlow::Value::unknown(); |
| 743 | ValueFlow::Value v(getStringLiteral(lhs.tokvalue->str()).compare(getStringLiteral(rhs.tokvalue->str()))); |
| 744 | ValueFlow::combineValueProperties(lhs, rhs, v); |
| 745 | return v; |
| 746 | }; |
| 747 | functions["strncmp"] = [](const std::vector<ValueFlow::Value>& args) { |
| 748 | if (args.size() != 3) |
| 749 | return ValueFlow::Value::unknown(); |
| 750 | const ValueFlow::Value& lhs = args[0]; |
| 751 | if (!(lhs.isTokValue() && lhs.tokvalue->tokType() == Token::eString)) |
| 752 | return ValueFlow::Value::unknown(); |
| 753 | const ValueFlow::Value& rhs = args[1]; |
| 754 | if (!(rhs.isTokValue() && rhs.tokvalue->tokType() == Token::eString)) |
| 755 | return ValueFlow::Value::unknown(); |
| 756 | const ValueFlow::Value& len = args[2]; |
| 757 | if (!len.isIntValue()) |
| 758 | return ValueFlow::Value::unknown(); |
| 759 | ValueFlow::Value v(getStringLiteral(lhs.tokvalue->str()) |
| 760 | .compare(0, len.intvalue, getStringLiteral(rhs.tokvalue->str()), 0, len.intvalue)); |
| 761 | ValueFlow::combineValueProperties(lhs, rhs, v); |
| 762 | return v; |
| 763 | }; |
| 764 | functions["sin"] = [](const std::vector<ValueFlow::Value>& args) { |
| 765 | if (args.size() != 1) |
| 766 | return ValueFlow::Value::unknown(); |
| 767 | const ValueFlow::Value& v_ref = args[0]; |
| 768 | if (!v_ref.isFloatValue() && !v_ref.isIntValue()) |
| 769 | return ValueFlow::Value::unknown(); |
| 770 | ValueFlow::Value v = v_ref; |
| 771 | v.floatValue = std::sin(asFloat(args[0])); |
| 772 | v.valueType = ValueFlow::Value::ValueType::FLOAT; |
| 773 | return v; |
| 774 | }; |
| 775 | functions["lgamma"] = [](const std::vector<ValueFlow::Value>& args) { |
| 776 | if (args.size() != 1) |
no test coverage detected