From 1977a18a1ecdf53e17e2fb14ef24fa5513282b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 27 Nov 2015 14:16:49 +0100 Subject: [PATCH] simplifyNumericCalculations: Don't fold negative constants in shift/bitmask calculation. Behaviour is not well defined. --- lib/templatesimplifier.cpp | 6 ++++++ test/testsimplifytokens.cpp | 1 + 2 files changed, 7 insertions(+) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index de0652c3d..8e2018d4b 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -964,6 +964,12 @@ bool TemplateSimplifier::simplifyNumericCalculations(Token *tok) // Integer operations if (Token::Match(op, ">>|<<|&|^|%or%")) { + // Don't simplify if operand is negative, shifting with negative + // operand is UB. Bitmasking with negative operand is implementation + // defined behaviour. + if (MathLib::isNegative(tok->str()) || MathLib::isNegative(tok->strAt(2))) + continue; + const char cop = op->str()[0]; std::string result; if (tok->str().find_first_of("uU") != std::string::npos) diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 50a400aa2..549a17938 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2096,6 +2096,7 @@ private: ASSERT_EQUALS("x ( 1 )", tok("x(2 && 4<<4<<5 && 4)")); // #4933 ASSERT_EQUALS("x ( 1 )", tok("x(9&&8%5%4/3)")); // #4931 ASSERT_EQUALS("x ( 1 )", tok("x(2 && 2|5<<2%4)")); // #4931 + ASSERT_EQUALS("x ( -2 << 6 | 1 )", tok("x(1-3<<6|5/3)")); // #4931 // don't remove these spaces.. ASSERT_EQUALS("new ( auto ) ( 4 ) ;", tok("new (auto)(4);"));