From e8435b9ecba3ec13228a7ee5dda3245241571c3e Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sat, 31 Aug 2019 00:40:57 -0500 Subject: [PATCH] Fix issue 9306: Adjust shiftTooManyBitsSigned for C++14 (#2127) --- lib/checktype.cpp | 22 ++++++++++++++++++---- test/testtype.cpp | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 081acf6b8..10f988426 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -57,6 +57,11 @@ void CheckType::checkTooBigBitwiseShift() if (mSettings->platformType == Settings::Unspecified) return; + const bool cpp14 = mSettings->standards.cpp >= Standards::CPP14; + + if (cpp14 && !mSettings->isEnabled(Settings::PORTABILITY)) + return; + for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { // C++ and macro: OUT(x<isCPP() && Token::Match(tok, "[;{}] %name% (") && Token::simpleMatch(tok->linkAt(2), ") ;") && tok->next()->isUpperCaseName() && !tok->next()->function()) @@ -91,7 +96,7 @@ void CheckType::checkTooBigBitwiseShift() // Get biggest rhs value. preferably a value which doesn't have 'condition'. const ValueFlow::Value * value = tok->astOperand2()->getValueGE(lhsbits, mSettings); - if (value && mSettings->isEnabled(value, false)) + if (value && mSettings->isEnabled(value, false) && !cpp14) tooBigBitwiseShiftError(tok, lhsbits, *value); else if (lhstype->sign == ValueType::Sign::SIGNED) { value = tok->astOperand2()->getValueGE(lhsbits-1, mSettings); @@ -124,19 +129,28 @@ void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, con { const char id[] = "shiftTooManyBitsSigned"; + const bool cpp14 = mSettings->standards.cpp >= Standards::CPP14; + + std::string behaviour = "undefined"; + if (cpp14) + behaviour = "implementation-defined"; if (!tok) { - reportError(tok, Severity::error, id, "Shifting signed 32-bit value by 31 bits is undefined behaviour", CWE758, false); + reportError(tok, Severity::error, id, "Shifting signed 32-bit value by 31 bits is " + behaviour + " behaviour", CWE758, false); return; } const ErrorPath errorPath = getErrorPath(tok, &rhsbits, "Shift"); std::ostringstream errmsg; - errmsg << "Shifting signed " << lhsbits << "-bit value by " << rhsbits.intvalue << " bits is undefined behaviour"; + errmsg << "Shifting signed " << lhsbits << "-bit value by " << rhsbits.intvalue << " bits is " + behaviour + " behaviour"; if (rhsbits.condition) errmsg << ". See condition at line " << rhsbits.condition->linenr() << "."; - reportError(errorPath, rhsbits.errorSeverity() ? Severity::error : Severity::warning, id, errmsg.str(), CWE758, rhsbits.isInconclusive()); + Severity::SeverityType severity = rhsbits.errorSeverity() ? Severity::error : Severity::warning; + if (cpp14) + severity = Severity::portability; + + reportError(errorPath, severity, id, errmsg.str(), CWE758, rhsbits.isInconclusive()); } //--------------------------------------------------------------------------- diff --git a/test/testtype.cpp b/test/testtype.cpp index e5a9366c8..b85211dbe 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -50,6 +50,7 @@ private: settings = &_settings; } settings->addEnabled("warning"); + settings->standards.setCPP("c++11"); // Tokenize.. Tokenizer tokenizer(settings, this);