Skip to content

Commit ef06677

Browse files
Fix #15086 syntaxError for ternary with two inequalities (#8913)
1 parent 33c2c43 commit ef06677

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

‎lib/templatesimplifier.cpp‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,13 +394,14 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
394394
return 0;
395395
if (tok->str() != "<")
396396
return 0;
397-
if (Token::Match(tok->previous(), "%var% <"))
397+
if (Token::Match(tok->previous(), "%var%|) <") && !(tok->linkAt(-1) && Token::simpleMatch(tok->linkAt(-1)->tokAt(-1), "operator")))
398398
return 0;
399399
tok = tok->next();
400400
if (!tok || tok->str() == ">")
401401
return 0;
402402

403403
unsigned int level = 0;
404+
unsigned int ternaryLevel = 0;
404405

405406
while (tok) {
406407
// skip template template
@@ -460,8 +461,16 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
460461
}
461462

462463
// Skip '=', '?', ':'
463-
if (Token::Match(tok, "=|?|:"))
464+
if (Token::Match(tok, "=|?|:")) {
465+
if (tok->str()[0] == '?')
466+
++ternaryLevel;
467+
else if (tok->str()[0] == ':') {
468+
if (ternaryLevel == 0)
469+
return 0;
470+
--ternaryLevel;
471+
}
464472
tok = tok->next();
473+
}
465474
if (!tok)
466475
return 0;
467476

‎test/testtokenize.cpp‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ class TestTokenizer : public TestFixture {
240240
TEST_CASE(vardecl33);
241241
TEST_CASE(vardecl34);
242242
TEST_CASE(vardecl35);
243+
TEST_CASE(vardecl36);
243244
TEST_CASE(vardecl_stl_1);
244245
TEST_CASE(vardecl_stl_2);
245246
TEST_CASE(vardecl_stl_3);
@@ -3035,6 +3036,38 @@ class TestTokenizer : public TestFixture {
30353036
}
30363037
}
30373038

3039+
void vardecl36() {
3040+
const char code[] = "struct S {\n" // #15086
3041+
" bool f1() const;\n"
3042+
" bool f2() const;\n"
3043+
" int g() const;\n"
3044+
" int x, y;\n"
3045+
"};\n"
3046+
"bool S::f1() const {\n"
3047+
" const bool b = x ? g() < 0 : 0 > y;\n"
3048+
" return b;\n"
3049+
"}\n"
3050+
"bool S::f2() const {\n"
3051+
" const bool b = g() < x ? x != y : 0 > y;\n"
3052+
" return b;\n"
3053+
"}\n";
3054+
const char expected[] = "struct S {\n"
3055+
"bool f1 ( ) const ;\n"
3056+
"bool f2 ( ) const ;\n"
3057+
"int g ( ) const ;\n"
3058+
"int x ; int y ;\n"
3059+
"} ;\n"
3060+
"bool S :: f1 ( ) const {\n"
3061+
"const bool b = x ? ( g ( ) < 0 ) : 0 > y ;\n"
3062+
"return b ;\n"
3063+
"}\n"
3064+
"bool S :: f2 ( ) const {\n"
3065+
"const bool b = g ( ) < x ? x != y : 0 > y ;\n"
3066+
"return b ;\n"
3067+
"}";
3068+
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
3069+
}
3070+
30383071
void volatile_variables() {
30393072
{
30403073
const char code[] = "volatile int a=0;\n"

0 commit comments

Comments
 (0)