File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1301,6 +1301,10 @@ void CheckConditionImpl::checkIncorrectLogicOperator()
13011301 if (isfloat && (op1 == " ==" || op1 == " !=" || op2 == " ==" || op2 == " !=" ))
13021302 continue ;
13031303
1304+ // no double value to compare (1e400L would become infinity)
1305+ if (isfloat && (MathLib::isLongDoubleOutOfDoubleRange (value1) || MathLib::isLongDoubleOutOfDoubleRange (value2)))
1306+ continue ;
1307+
13041308 // the expr are not the token of the value but they provide better context
13051309 const double d1 = isfloat ? MathLib::toDoubleNumber (value1) : 0 ;
13061310 const double d2 = isfloat ? MathLib::toDoubleNumber (value2) : 0 ;
Original file line number Diff line number Diff line change @@ -591,6 +591,13 @@ bool MathLib::isFloat(const std::string &str)
591591 return isDecimalFloat (str) || isFloatHex (str);
592592}
593593
594+ bool MathLib::isLongDoubleOutOfDoubleRange (const std::string &str)
595+ {
596+ if (str.empty () || (str.back () != ' l' && str.back () != ' L' ) || !isFloat (str))
597+ return false ;
598+ return std::isinf (toDoubleNumber (str));
599+ }
600+
594601bool MathLib::isDecimalFloat (const std::string &str)
595602{
596603 if (str.empty ())
Original file line number Diff line number Diff line change @@ -115,6 +115,8 @@ class CPPCHECKLIB MathLib {
115115
116116 static bool isInt (const std::string & str);
117117 static bool isFloat (const std::string &str);
118+ /* * @brief a long double literal out of the range of double, such as 1e400L, which toDoubleNumber() makes infinity */
119+ static bool isLongDoubleOutOfDoubleRange (const std::string &str);
118120 static bool isDecimalFloat (const std::string &str);
119121 static bool isNegative (const std::string &str);
120122 static bool isPositive (const std::string &str);
Original file line number Diff line number Diff line change @@ -139,12 +139,16 @@ namespace ValueFlow
139139 // Bad character literal
140140 }
141141 } else if (tok->isNumber () && MathLib::isFloat (tok->str ())) {
142- Value value;
143- value.valueType = Value::ValueType::FLOAT ;
144- value.floatValue = MathLib::toDoubleNumber (tok);
145- if (!tok->isTemplateArg ())
146- value.setKnown ();
147- setTokenValue (tok, std::move (value), settings);
142+ // A long double literal out of the range of double (1e400L) has no
143+ // double value: infinity would make different literals compare equal.
144+ if (!MathLib::isLongDoubleOutOfDoubleRange (tok->str ())) {
145+ Value value;
146+ value.valueType = Value::ValueType::FLOAT ;
147+ value.floatValue = MathLib::toDoubleNumber (tok);
148+ if (!tok->isTemplateArg ())
149+ value.setKnown ();
150+ setTokenValue (tok, std::move (value), settings);
151+ }
148152 } else if (tok->enumerator () && tok->enumerator ()->value_known ) {
149153 Value value (tok->enumerator ()->value );
150154 if (!tok->isTemplateArg ())
Original file line number Diff line number Diff line change @@ -69,6 +69,7 @@ class TestCondition : public TestFixture {
6969 TEST_CASE (incorrectLogicOperator15);
7070 TEST_CASE (incorrectLogicOperator16); // #10070
7171 TEST_CASE (incorrectLogicOperator17);
72+ TEST_CASE (incorrectLogicOperator18); // #12282
7273 TEST_CASE (secondAlwaysTrueFalseWhenFirstTrueError);
7374 TEST_CASE (incorrectLogicOp_condSwapping);
7475 TEST_CASE (testBug5895);
@@ -1758,6 +1759,17 @@ class TestCondition : public TestFixture {
17581759 ASSERT_EQUALS (" " , errout_str ());
17591760 }
17601761
1762+ void incorrectLogicOperator18 () { // #12282
1763+ // long double literals out of the range of double are different values
1764+ check (" int f(long double x) {\n "
1765+ " return x > 1e400L && x < 1e500L;\n "
1766+ " }\n "
1767+ " int g() {\n "
1768+ " return 1e400L < 1e500L;\n "
1769+ " }\n " );
1770+ ASSERT_EQUALS (" " , errout_str ());
1771+ }
1772+
17611773 void incorrectLogicOperator17 () { // #12471
17621774 check (" struct R {\n "
17631775 " void set() { i = 1; }\n "
Original file line number Diff line number Diff line change @@ -45,6 +45,7 @@ class TestMathLib : public TestFixture {
4545 TEST_CASE (isnegative);
4646 TEST_CASE (ispositive);
4747 TEST_CASE (isFloat);
48+ TEST_CASE (isLongDoubleOutOfDoubleRange);
4849 TEST_CASE (isDecimalFloat);
4950 TEST_CASE (isGreater);
5051 TEST_CASE (isGreaterEqual);
@@ -599,6 +600,16 @@ class TestMathLib : public TestFixture {
599600 // TODO: test with 128-bit values
600601 }
601602
603+ void isLongDoubleOutOfDoubleRange () const {
604+ ASSERT_EQUALS (true , MathLib::isLongDoubleOutOfDoubleRange (" 1e400L" ));
605+ ASSERT_EQUALS (true , MathLib::isLongDoubleOutOfDoubleRange (" 1.0e4931l" ));
606+ ASSERT_EQUALS (false , MathLib::isLongDoubleOutOfDoubleRange (" 1e300L" ));
607+ ASSERT_EQUALS (false , MathLib::isLongDoubleOutOfDoubleRange (" 1e10000" ));
608+ ASSERT_EQUALS (false , MathLib::isLongDoubleOutOfDoubleRange (" 1e10000f" ));
609+ ASSERT_EQUALS (false , MathLib::isLongDoubleOutOfDoubleRange (" 10L" ));
610+ ASSERT_EQUALS (false , MathLib::isLongDoubleOutOfDoubleRange (" " ));
611+ }
612+
602613 void toDoubleNumber () const {
603614 // float values
604615 ASSERT_EQUALS_DOUBLE (1.0 , MathLib::toDoubleNumber (" 1." ), 0.001 );
Original file line number Diff line number Diff line change @@ -204,6 +204,7 @@ class TestOther : public TestFixture {
204204 TEST_CASE(duplicateExpression20);
205205 TEST_CASE(duplicateExpression21);
206206 TEST_CASE(duplicateExpression22);
207+ TEST_CASE(duplicateExpression23); // #12282
207208 TEST_CASE(duplicateExpressionLoop);
208209 TEST_CASE(duplicateValueTernary);
209210 TEST_CASE(duplicateValueTernarySizeof); // #13773
@@ -8498,6 +8499,17 @@ class TestOther : public TestFixture {
84988499 ASSERT_EQUALS("", errout_str());
84998500 }
85008501
8502+ void duplicateExpression23() { // #12282
8503+ // long double literals out of the range of double are different values
8504+ check("long double f() {\n"
8505+ " return 1e400L / 1e500L;\n"
8506+ "}\n"
8507+ "int g(long double x) {\n"
8508+ " return x == 1e400L || x == 1e500L;\n"
8509+ "}\n");
8510+ ASSERT_EQUALS("", errout_str());
8511+ }
8512+
85018513 void duplicateExpression22() {
85028514 check("int f() {\n" // #14913
85038515 " return 0x1 | (0x2 | 0x4) | 0x1;\n"
You can’t perform that action at this time.
0 commit comments