From 9ac152597e3a8c892fd1c46e8af20aff5fd1ee61 Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Thu, 11 Jul 2024 18:05:28 +0300 Subject: [PATCH 1/5] Fix #12929: ValueType: char literal '\'' gets valuetype 'int' --- lib/symboldatabase.cpp | 2 +- test/testsymboldatabase.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 40c18bdbff6..2a17badd34d 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -7422,7 +7422,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to } else if (tok->isLong()) { valuetype.originalTypeName = "wchar_t"; valuetype.type = ValueType::Type::WCHAR_T; - } else if ((tok->tokType() == Token::eChar) && ((!tok->isCpp() && tok->isCChar()) || (tok->isCMultiChar()))) { + } else if ((tok->tokType() == Token::eChar) && ((!tok->isCpp() && tok->isCChar()) || (tok->isCMultiChar() && !isPrefixStringCharLiteral(tok->str(), '\'', "\'\\")))) { valuetype.type = ValueType::Type::INT; valuetype.sign = ValueType::Sign::SIGNED; } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 10276b3dc72..50346041a10 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -8887,6 +8887,7 @@ class TestSymbolDatabase : public TestFixture { // char ASSERT_EQUALS("char", typeOf("'a';", "'a'", true)); + ASSERT_EQUALS("char", typeOf("'\\\'';", "'\\\''", true)); ASSERT_EQUALS("signed int", typeOf("'a';", "'a'", false)); ASSERT_EQUALS("wchar_t", typeOf("L'a';", "L'a'", true)); ASSERT_EQUALS("wchar_t", typeOf("L'a';", "L'a'", false)); From 482309aeb2b5bfa7e67321d7f1aa48b7d01d3a16 Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Thu, 11 Jul 2024 19:38:59 +0300 Subject: [PATCH 2/5] Move around --- lib/symboldatabase.cpp | 2 +- lib/token.h | 2 +- test/testtoken.cpp | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 2a17badd34d..40c18bdbff6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -7422,7 +7422,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to } else if (tok->isLong()) { valuetype.originalTypeName = "wchar_t"; valuetype.type = ValueType::Type::WCHAR_T; - } else if ((tok->tokType() == Token::eChar) && ((!tok->isCpp() && tok->isCChar()) || (tok->isCMultiChar() && !isPrefixStringCharLiteral(tok->str(), '\'', "\'\\")))) { + } else if ((tok->tokType() == Token::eChar) && ((!tok->isCpp() && tok->isCChar()) || (tok->isCMultiChar()))) { valuetype.type = ValueType::Type::INT; valuetype.sign = ValueType::Sign::SIGNED; } diff --git a/lib/token.h b/lib/token.h index b87430af3f5..6a2feacd573 100644 --- a/lib/token.h +++ b/lib/token.h @@ -755,7 +755,7 @@ class CPPCHECKLIB Token { } bool isCMultiChar() const { - return (((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString)) && + return (((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString)) && !isPrefixStringCharLiteral(mStr, '\'', "\'\\") && (mStr.length() > 3)); } /** diff --git a/test/testtoken.cpp b/test/testtoken.cpp index e2ff0ab0e1b..85473006876 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -355,6 +355,14 @@ class TestToken : public TestFixture { ASSERT_EQUALS(false, tok.isUtf32()); ASSERT_EQUALS(false, tok.isLong()); ASSERT_EQUALS(true, tok.isCMultiChar()); + + tok.str("'\''"); + ASSERT_EQUALS(true, tok.isCChar()); + ASSERT_EQUALS(false, tok.isUtf8()); + ASSERT_EQUALS(false, tok.isUtf16()); + ASSERT_EQUALS(false, tok.isUtf32()); + ASSERT_EQUALS(false, tok.isLong()); + ASSERT_EQUALS(false, tok.isCMultiChar()); } void stringTypes() const { From 6845a3ff9382bd6a5a25b6532dd335f1531148f9 Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Fri, 12 Jul 2024 10:30:50 +0300 Subject: [PATCH 3/5] Test case --- test/testtoken.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/testtoken.cpp b/test/testtoken.cpp index 85473006876..4a23764f3c9 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -363,6 +363,14 @@ class TestToken : public TestFixture { ASSERT_EQUALS(false, tok.isUtf32()); ASSERT_EQUALS(false, tok.isLong()); ASSERT_EQUALS(false, tok.isCMultiChar()); + + tok.str("'\r\n'"); + ASSERT_EQUALS(false, tok.isCChar()); + ASSERT_EQUALS(false, tok.isUtf8()); + ASSERT_EQUALS(false, tok.isUtf16()); + ASSERT_EQUALS(false, tok.isUtf32()); + ASSERT_EQUALS(false, tok.isLong()); + ASSERT_EQUALS(true, tok.isCMultiChar()); } void stringTypes() const { From da6cd6cc488741c6f8e9502c831f4550462f690f Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Fri, 12 Jul 2024 14:20:25 +0300 Subject: [PATCH 4/5] Check fix --- lib/token.h | 4 ++-- test/testtoken.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/token.h b/lib/token.h index 6a2feacd573..af07b8606ce 100644 --- a/lib/token.h +++ b/lib/token.h @@ -751,11 +751,11 @@ class CPPCHECKLIB Token { bool isCChar() const { return (((mTokType == eString) && isPrefixStringCharLiteral(mStr, '"', emptyString)) || - ((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString) && mStr.length() == 3)); + ((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString) && mStr.length() <= 4)); } bool isCMultiChar() const { - return (((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString)) && !isPrefixStringCharLiteral(mStr, '\'', "\'\\") && + return (((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString)) && (mStr.compare(0, 2, "\'\\") != 0 || mStr.length() > 4) && (mStr.length() > 3)); } /** diff --git a/test/testtoken.cpp b/test/testtoken.cpp index 4a23764f3c9..238bff97bae 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -356,7 +356,7 @@ class TestToken : public TestFixture { ASSERT_EQUALS(false, tok.isLong()); ASSERT_EQUALS(true, tok.isCMultiChar()); - tok.str("'\''"); + tok.str("'\\''"); ASSERT_EQUALS(true, tok.isCChar()); ASSERT_EQUALS(false, tok.isUtf8()); ASSERT_EQUALS(false, tok.isUtf16()); @@ -364,7 +364,7 @@ class TestToken : public TestFixture { ASSERT_EQUALS(false, tok.isLong()); ASSERT_EQUALS(false, tok.isCMultiChar()); - tok.str("'\r\n'"); + tok.str("'\\r\\n'"); ASSERT_EQUALS(false, tok.isCChar()); ASSERT_EQUALS(false, tok.isUtf8()); ASSERT_EQUALS(false, tok.isUtf16()); From 1a2d3ab4830ad4a2ee8de292e893130416662600 Mon Sep 17 00:00:00 2001 From: Oleksandr Labetskyi Date: Fri, 12 Jul 2024 15:42:42 +0300 Subject: [PATCH 5/5] Nits --- lib/token.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/token.h b/lib/token.h index af07b8606ce..c9e8c68ee4a 100644 --- a/lib/token.h +++ b/lib/token.h @@ -751,7 +751,8 @@ class CPPCHECKLIB Token { bool isCChar() const { return (((mTokType == eString) && isPrefixStringCharLiteral(mStr, '"', emptyString)) || - ((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString) && mStr.length() <= 4)); + ((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString) && mStr.length() == 3) || + ((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString) && mStr.compare(0, 2, "\'\\") == 0 && mStr.length() == 4)); } bool isCMultiChar() const {