Skip to content

Commit 06f5689

Browse files
authored
Fix 12372: C++20: syntaxError with implicit operator and requires clause (#6397)
1 parent 9c21862 commit 06f5689

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

lib/tokenize.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ const Token * Tokenizer::isFunctionHead(const Token *tok, const std::string &end
132132
if (Token::Match(tok, "%name% (") && tok->isUpperCaseName())
133133
tok = tok->linkAt(1)->next();
134134
if (tok && tok->originalName() == "->") { // trailing return type
135-
for (tok = tok->next(); tok && !Token::Match(tok, ";|{|override|final"); tok = tok->next())
135+
for (tok = tok->next(); tok && !Token::Match(tok, ";|{|override|final|}|)|]"); tok = tok->next())
136136
if (tok->link() && Token::Match(tok, "<|[|("))
137137
tok = tok->link();
138138
}
@@ -141,6 +141,14 @@ const Token * Tokenizer::isFunctionHead(const Token *tok, const std::string &end
141141
tok = tok->next();
142142
if (Token::Match(tok, "= 0|default|delete ;"))
143143
tok = tok->tokAt(2);
144+
if (Token::simpleMatch(tok, "requires")) {
145+
for (tok = tok->next(); tok && !Token::Match(tok, ";|{|}|)|]"); tok = tok->next()) {
146+
if (tok->link() && Token::Match(tok, "<|[|("))
147+
tok = tok->link();
148+
if (Token::simpleMatch(tok, "bool {"))
149+
tok = tok->linkAt(1);
150+
}
151+
}
144152
if (tok && tok->str() == ":" && !Token::Match(tok->next(), "%name%|::"))
145153
return nullptr;
146154
return (tok && endsWith.find(tok->str()) != std::string::npos) ? tok : nullptr;

test/testtokenize.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7671,6 +7671,12 @@ class TestTokenizer : public TestFixture {
76717671
{
76727672
ASSERT_NO_THROW(tokenizeAndStringify("template<class T, class U>\n"
76737673
"struct X { X(U) requires true {} };\n"));
7674+
ASSERT_NO_THROW(tokenizeAndStringify("template<class T, class U>\n"
7675+
"struct X { X(U) requires bool{std::is_integral<T>{}} {} };\n"));
7676+
ASSERT_NO_THROW(tokenizeAndStringify("template <typename T>\n"
7677+
"struct test { operator int() requires true { return 0; } };\n"));
7678+
ASSERT_NO_THROW(tokenizeAndStringify("template <typename T>\n"
7679+
"struct test { operator int() requires bool{std::is_integral<T>{}} { return 0; } };\n"));
76747680
}
76757681

76767682
void noCrash1() {

0 commit comments

Comments
 (0)