From 93932ad27d5fccea4f93fd999fdbadb000e7ae25 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 7 Oct 2024 20:37:33 +0200 Subject: [PATCH] Fix #13197 Crash in isExhaustiveSwitch() (#6875) --- lib/tokenlist.cpp | 7 ++++++- test/testtokenize.cpp | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 7f09c2eaa2c..fddabf1d590 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -913,7 +913,7 @@ static bool isPrefixUnary(const Token* tok, bool cpp) } } if (!tok->previous() - || ((Token::Match(tok->previous(), "(|[|{|%op%|;|?|:|,|.|return|::") || (cpp && tok->strAt(-1) == "throw")) + || ((Token::Match(tok->previous(), "(|[|{|%op%|;|?|:|,|.|case|return|::") || (cpp && tok->strAt(-1) == "throw")) && (tok->previous()->tokType() != Token::eIncDecOp || tok->tokType() == Token::eIncDecOp))) return true; @@ -1893,6 +1893,11 @@ void TokenList::validateAst(bool print) const "' doesn't have two operands.", InternalError::AST); } + if (tok->str() == "case" && !tok->astOperand1()) { + throw InternalError(tok, + "Syntax Error: AST broken, 'case' doesn't have an operand.", + InternalError::AST); + } // Check member access if (Token::Match(tok, "%var% .")) { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 51ef2f51812..b890ef242d5 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -6903,6 +6903,7 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("12+case", testAst("case 1+2:")); ASSERT_EQUALS("xyz:?case", testAst("case (x?y:z):")); ASSERT_EQUALS("switchx( 1case y++ 2case", testAst("switch(x){case 1:{++y;break;case 2:break;}}")); + ASSERT_EQUALS("switchi( 12<<~case 0return", testAst("switch (i) { case ~(1 << 2) : return 0; }")); // #13197 } void astrefqualifier() {