Skip to content

Commit

Permalink
fixed #13606/#13607 - consistently print (precise) float as such in V…
Browse files Browse the repository at this point in the history
…alueFlow debug output (#7274)
  • Loading branch information
firewave authored Feb 13, 2025
1 parent 0593984 commit 5ff116d
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 5 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,8 @@ TESTOBJ = test/fixture.o \
test/testutils.o \
test/testvaarg.o \
test/testvalueflow.o \
test/testvarid.o
test/testvarid.o \
test/testvfvalue.o

.PHONY: run-dmake tags

Expand Down Expand Up @@ -900,6 +901,9 @@ test/testvalueflow.o: test/testvalueflow.cpp externals/simplecpp/simplecpp.h lib
test/testvarid.o: test/testvarid.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvarid.cpp

test/testvfvalue.o: test/testvfvalue.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvfvalue.cpp

externals/simplecpp/simplecpp.o: externals/simplecpp/simplecpp.cpp externals/simplecpp/simplecpp.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ externals/simplecpp/simplecpp.cpp

Expand Down
4 changes: 2 additions & 2 deletions lib/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "astutils.h"
#include "errortypes.h"
#include "library.h"
#include "mathlib.h"
#include "settings.h"
#include "simplecpp.h"
#include "symboldatabase.h"
Expand Down Expand Up @@ -1801,7 +1802,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
break;
case ValueFlow::Value::ValueType::FLOAT:
outs += "floatvalue=\"";
outs += std::to_string(value.floatValue); // TODO: should this be MathLib::toString()?
outs += MathLib::toString(value.floatValue);
outs += '\"';
break;
case ValueFlow::Value::ValueType::MOVED:
Expand Down Expand Up @@ -1875,7 +1876,6 @@ void Token::printValueFlow(bool xml, std::ostream &out) const

outs += "/>\n";
}

else {
if (&value != &values->front())
outs += ",";
Expand Down
3 changes: 2 additions & 1 deletion lib/vfvalue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "vfvalue.h"

#include "errortypes.h"
#include "mathlib.h"
#include "token.h"

#include <sstream>
Expand Down Expand Up @@ -58,7 +59,7 @@ namespace ValueFlow {
ss << this->tokvalue->str();
break;
case ValueType::FLOAT:
ss << this->floatValue;
ss << MathLib::toString(this->floatValue);
break;
case ValueType::MOVED:
ss << toString(this->moveKind);
Expand Down
100 changes: 99 additions & 1 deletion test/cli/other_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3064,4 +3064,102 @@ def test_file_ignore_2(tmp_path): # #13570
'cppcheck: error: could not find or open any of the paths given.',
'cppcheck: Maybe all paths were ignored?'
]
assert stderr.splitlines() == []
assert stderr.splitlines() == []


def test_debug_valueflow(tmp_path):
test_file = tmp_path / 'test.c'
with open(test_file, "w") as f:
f.write(
"""int f()
{
double d = 1.0 / 0.5;
return d;
}
""")

args = [
'-q',
'--debug', # TODO: limit to valueflow output
str(test_file)
]

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0, stdout

# check sections in output
assert stdout.find('##file ') != -1
assert stdout.find('##Value flow') != -1
assert stdout.find('### Symbol database ###') == -1
assert stdout.find('##AST') == -1
assert stdout.find('### Template Simplifier pass ') == -1
assert stderr.splitlines() == []

# check precision in output - #13607
valueflow = stdout[stdout.find('##Value flow'):]
assert valueflow.splitlines() == [
'##Value flow',
'File {}'.format(str(test_file).replace('\\', '/')),
'Line 3',
' = always 2.0',
' 1.0 always 1.0',
' / always 2.0',
' 0.5 always 0.5',
'Line 4',
' d always {symbolic=(1.0/0.5),2.0}'
]


def test_debug_valueflow_xml(tmp_path): # #13606
test_file = tmp_path / 'test.c'
with open(test_file, "w") as f:
f.write(
"""double f()
{
double d = 0.0000001;
return d;
}
""")

args = [
'-q',
'--debug', # TODO: limit to valueflow output
'--xml',
str(test_file)
]

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0, stdout

assert stderr
assert ElementTree.fromstring(stderr) is not None

# check sections in output
assert stdout.find('##file ') != -1 # also exists in CDATA
assert stdout.find('##Value flow') == -1
assert stdout.find('### Symbol database ###') == -1
assert stdout.find('##AST') == -1
assert stdout.find('### Template Simplifier pass ') == -1

# check XML nodes in output
debug_xml = ElementTree.fromstring(stdout)
assert debug_xml is not None
assert debug_xml.tag == 'debug'
file_elem = debug_xml.findall('file')
assert len(file_elem) == 1
valueflow_elem = debug_xml.findall('valueflow')
assert len(valueflow_elem) == 1
scopes_elem = debug_xml.findall('scopes')
assert len(scopes_elem) == 1
ast_elem = debug_xml.findall('ast')
assert len(ast_elem) == 0

# check precision in output - #13606
value_elem = valueflow_elem[0].findall('values/value')
assert len(value_elem) == 3
assert 'floatvalue' in value_elem[0].attrib
assert value_elem[0].attrib['floatvalue'] == '1e-07'
assert 'floatvalue' in value_elem[1].attrib
assert value_elem[1].attrib['floatvalue'] == '1e-07'
assert 'floatvalue' in value_elem[2].attrib
assert value_elem[2].attrib['floatvalue'] == '1e-07'
1 change: 1 addition & 0 deletions test/testrunner.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
<ClCompile Include="testvaarg.cpp" />
<ClCompile Include="testvalueflow.cpp" />
<ClCompile Include="testvarid.cpp" />
<ClCompile Include="testvfvalue.cpp" />
</ItemGroup>
<ItemGroup Label="HeaderFiles">
<ClInclude Include="..\cli\cmdlineparser.h" />
Expand Down
48 changes: 48 additions & 0 deletions test/testvfvalue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2024 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "fixture.h"
#include "vfvalue.h"

class TestValueFlowValue : public TestFixture {
public:
TestValueFlowValue() : TestFixture("TestValueFlowValue") {}

private:
void run() override {
TEST_CASE(toString);
}

void toString() const {
{
ValueFlow::Value v;
ASSERT_EQUALS("0", v.toString());
v.intvalue = -1;
ASSERT_EQUALS("-1", v.toString());
}
{
ValueFlow::Value v;
v.valueType = ValueFlow::Value::ValueType::FLOAT;
ASSERT_EQUALS("0.0", v.toString());
v.floatValue = 0.0000000000001;
ASSERT_EQUALS("1e-13", v.toString());
}
}
};

REGISTER_TEST(TestValueFlowValue)

0 comments on commit 5ff116d

Please sign in to comment.