From a83c47d9cf35f6048ccf8a276e397bd399555a5d Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Sun, 6 Nov 2011 22:12:28 +0100 Subject: [PATCH] Fix false positive of %or% match in alternative pattern match code %or% triggered on code using "|=" or "||". --- lib/token.cpp | 4 ++-- test/testtoken.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/token.cpp b/lib/token.cpp index 6f0ec9fbe..b9dec9427 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -241,7 +241,7 @@ static int multiComparePercent(const char * * haystack_p, } else if (haystack[1] == 'o' && // "%or%" haystack[2] == 'r' && haystack[3] == '%') { - if (*needle == '|') + if (*needle == '|' && needle[1] != '|' && needle[1] != '=') return 1; *haystack_p = haystack = haystack + 4; } else if (haystack[1] == 'o' && // "%oror%" @@ -278,7 +278,7 @@ int Token::multiCompare(const char *haystack, const char *needle) haystack[3] == '%' && haystack[4] == '|') { haystack = haystack + 5; - if (*needle == '|') + if (*needle == '|' && needle[1] != '|' && needle[1] != '=') return 1; } else if (haystack[2] == 'r' && // "%oror%|" haystack[3] == 'o' && diff --git a/test/testtoken.cpp b/test/testtoken.cpp index b72f9e918..2adc1b919 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -43,6 +43,7 @@ private: TEST_CASE(nextprevious); TEST_CASE(multiCompare); TEST_CASE(multiCompare2); // #3294 - false negative multi compare between "=" and "==" + TEST_CASE(multiCompare3); // false positive for %or% on code using "|=" TEST_CASE(getStrLength); TEST_CASE(strValue); @@ -128,6 +129,27 @@ private: ASSERT_EQUALS(true, Token::Match(toks.tokens(), "a =|%op%")); } + void multiCompare3() { + // Original pattern that failed: "return|(|&&|%oror% %var% &&|%oror%|==|!=|<=|>=|<|>|-|%or% %var% )|&&|%oror%|;" + // Code snippet that failed: "return lv@86 |= rv@87 ;" + + // Note: Also test "reverse" alternative pattern, two different code paths to handle it + givenACodeSampleToTokenize toks("return a |= b ;"); + ASSERT_EQUALS(false, Token::Match(toks.tokens(), "return %var% xyz|%or% %var% ;")); + ASSERT_EQUALS(false, Token::Match(toks.tokens(), "return %var% %or%|xyz %var% ;")); + + givenACodeSampleToTokenize toks2("return a | b ;"); + ASSERT_EQUALS(true, Token::Match(toks2.tokens(), "return %var% xyz|%or% %var% ;")); + ASSERT_EQUALS(true, Token::Match(toks2.tokens(), "return %var% %or%|xyz %var% ;")); + + givenACodeSampleToTokenize toks3("return a || b ;"); + ASSERT_EQUALS(false, Token::Match(toks3.tokens(), "return %var% xyz|%or% %var% ;")); + ASSERT_EQUALS(false, Token::Match(toks3.tokens(), "return %var% %or%|xyz %var% ;")); + + ASSERT_EQUALS(true, Token::Match(toks3.tokens(), "return %var% xyz|%oror% %var% ;")); + ASSERT_EQUALS(true, Token::Match(toks3.tokens(), "return %var% %oror%|xyz %var% ;")); + } + void getStrLength() { Token tok(0); @@ -307,6 +329,11 @@ private: ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "%op%")); ASSERT_EQUALS(false, Token::Match(bitwiseOr.tokens(), "%oror%")); + givenACodeSampleToTokenize bitwiseOrAssignment("|="); + ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "%or%")); + ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "%op%")); + ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "%oror%")); + givenACodeSampleToTokenize logicalOr("||"); ASSERT_EQUALS(false, Token::Match(logicalOr.tokens(), "%or%")); ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "%op%"));