Skip to content

Commit abb4200

Browse files
committed
Fixed #10196 ("Unhandled char constant 'x'" with non-standard escape character)
1 parent 0a84ad8 commit abb4200

File tree

5 files changed

+42
-12
lines changed

5 files changed

+42
-12
lines changed

lib/cppcheck.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,8 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
835835
ErrorMessage::FileLocation loc(tokenizer.list.getSourceFilePath(), 0, 0);
836836
ErrorMessage::FileLocation loc2(filename, 0, 0);
837837
locationList.push_back(loc2);
838-
locationList.push_back(loc);
838+
if (filename != tokenizer.list.getSourceFilePath())
839+
locationList.push_back(loc);
839840
}
840841
ErrorMessage errmsg(locationList,
841842
tokenizer.list.getSourceFilePath(),

lib/mathlib.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -505,13 +505,8 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
505505
return static_cast<bigint>(doubleval);
506506
}
507507

508-
if (isCharLiteral(str)) {
509-
try {
510-
return simplecpp::characterLiteralToLL(str);
511-
} catch (const std::exception& e) {
512-
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: characterLiteralToLL(" + str + ") => " + e.what());
513-
}
514-
}
508+
if (isCharLiteral(str))
509+
return simplecpp::characterLiteralToLL(str);
515510

516511
try {
517512
const biguint ret = std::stoull(str, nullptr, 10);

lib/tokenize.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2766,6 +2766,19 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration)
27662766
ValueFlow::setValues(&list, mSymbolDatabase, mErrorLogger, mSettings);
27672767
}
27682768

2769+
// Warn about unhandled character literals
2770+
if (mSettings->severity.isEnabled(Severity::information)) {
2771+
for (const Token *tok = tokens(); tok; tok = tok->next()) {
2772+
if (tok->tokType() == Token::eChar && tok->values().empty()) {
2773+
try {
2774+
simplecpp::characterLiteralToLL(tok->str());
2775+
} catch (const std::exception &e) {
2776+
unhandledCharLiteral(tok, e.what());
2777+
}
2778+
}
2779+
}
2780+
}
2781+
27692782
mSymbolDatabase->setArrayDimensionsUsingValueFlow();
27702783

27712784
printDebugOutput(1);
@@ -9528,6 +9541,21 @@ void Tokenizer::cppcheckError(const Token *tok) const
95289541
printDebugOutput(0);
95299542
throw InternalError(tok, "Analysis failed. If the code is valid then please report this failure.", InternalError::INTERNAL);
95309543
}
9544+
9545+
void Tokenizer::unhandledCharLiteral(const Token *tok, const std::string& msg) const
9546+
{
9547+
std::string s = tok ? (" " + tok->str()) : "";
9548+
for (int i = 0; i < s.size(); ++i) {
9549+
if ((unsigned char)s[i] >= 0x80)
9550+
s.clear();
9551+
}
9552+
9553+
reportError(tok,
9554+
Severity::information,
9555+
"cppcheckUnhandledChar",
9556+
"Character literal" + s + " is not handled. " + msg);
9557+
}
9558+
95319559
/**
95329560
* Helper function to check whether number is equal to integer constant X
95339561
* or floating point pattern X.0

lib/tokenize.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,8 @@ class CPPCHECKLIB Tokenizer {
652652
/** Warn about unknown macro(s), configuration is recommended */
653653
NORETURN void unknownMacroError(const Token *tok1) const;
654654

655+
void unhandledCharLiteral(const Token *tok, const std::string& msg) const;
656+
655657
private:
656658

657659
/** Report that there is an unhandled "class x y {" code */

lib/valueflow.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -913,10 +913,14 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings *settings)
913913
static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, bool cpp)
914914
{
915915
if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) {
916-
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
917-
if (!tok->isTemplateArg())
918-
value.setKnown();
919-
setTokenValue(tok, value, settings);
916+
try {
917+
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
918+
if (!tok->isTemplateArg())
919+
value.setKnown();
920+
setTokenValue(tok, value, settings);
921+
} catch (const std::exception &e) {
922+
// Bad character literal
923+
}
920924
} else if (tok->isNumber() && MathLib::isFloat(tok->str())) {
921925
ValueFlow::Value value;
922926
value.valueType = ValueFlow::Value::ValueType::FLOAT;

0 commit comments

Comments
 (0)