Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions lib/mathlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,42 @@ bool MathLib::isOctalDigit(char c)
return (c >= '0' && c <= '7');
}

bool MathLib::isDigitSeparator(const std::string& iCode, std::string::size_type iPos) {
if (iPos == 0 || iPos >= iCode.size() || iCode[iPos] != '\'')
return false;
std::string::size_type i = iPos - 1;
while (std::isxdigit(iCode[i])) {
if (i == 0)
return true; // Only xdigits before '
--i;
}
if (i == iPos - 1) { // No xdigit before '
return false;
} else {
switch(iCode[i]) {
case ' ':
case '.':
case ',':
case 'x':
case '(':
case '{':
case '+':
case '-':
case '*':
case '%':
case '/':
case '&':
case '|':
case '^':
case '~':
case '=':
return true;
default:
return false;
}
}
}

MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2)
{
return MathLib::value::calc('+',v1,v2);
Expand Down
7 changes: 7 additions & 0 deletions lib/mathlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ class CPPCHECKLIB MathLib {
* */
static MathLib::bigint characterLiteralToLongNumber(const std::string& str);

/**
* \param iCode Code being considered
* \param iPos A posision within iCode
* \return Whether iCode[iPos] is a C++14 digit separator
*/
static bool isDigitSeparator(const std::string& iCode, std::string::size_type iPos);

private:
/*
* \param iLiteral A character literal
Expand Down
2 changes: 1 addition & 1 deletion lib/preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ std::string Preprocessor::removeComments(const std::string &str, const std::stri
}

// C++14 digit separators
if (ch == '\'' && std::isxdigit(previous))
if (MathLib::isDigitSeparator(str, i))
; // Just skip it.

// String or char constants..
Expand Down
18 changes: 18 additions & 0 deletions test/testmathlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class TestMathLib : public TestFixture {
TEST_CASE(abs);
TEST_CASE(toString);
TEST_CASE(characterLiteralsNormalization);
TEST_CASE(CPP14DigitSeparators);
}

void isGreater() const {
Expand Down Expand Up @@ -1143,6 +1144,23 @@ class TestMathLib : public TestFixture {
// Unsupported single escape sequence
ASSERT_THROW(MathLib::normalizeCharacterLiteral("\\c"), InternalError);
}

void CPP14DigitSeparators() { // Ticket #7137
ASSERT(MathLib::isDigitSeparator("'", 0) == false);
ASSERT(MathLib::isDigitSeparator("123'0;", 3));
ASSERT(MathLib::isDigitSeparator("foo(1'2);", 5));
ASSERT(MathLib::isDigitSeparator("foo(1,1'2);", 7));
ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 7));
ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 13));
ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 16) == false);
ASSERT(MathLib::isDigitSeparator("int b=1+9'8;", 9));
ASSERT(MathLib::isDigitSeparator("if (1'2) { char c = 'c'; }", 5));
ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 9));
ASSERT(MathLib::isDigitSeparator("if (120&1'2) { char c = 'c'; }", 9));
ASSERT(MathLib::isDigitSeparator("if (120|1'2) { char c = 'c'; }", 9));
ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 24) == false);
ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 26) == false);
}
};

REGISTER_TEST(TestMathLib)
5 changes: 5 additions & 0 deletions test/testpreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,11 @@ class TestPreprocessor : public TestFixture {

ASSERT_EQUALS("int i = 0x0F0FFFFF;", preprocessorRead("int i = 0x0F0F'FFFF;"));
ASSERT_EQUALS("", errout.str());

// Ticket #7137
const char code[] = "void t(char c) { switch (c) { case'M': break; } }";
ASSERT_EQUALS(code, preprocessorRead(code));
ASSERT_EQUALS("", errout.str());
}


Expand Down