Skip to content

Commit

Permalink
Fix 12372: C++20: syntaxError with implicit operator and requires cla…
Browse files Browse the repository at this point in the history
…use (#6397)
  • Loading branch information
pfultz2 authored May 23, 2024
1 parent 9c21862 commit 06f5689
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
10 changes: 9 additions & 1 deletion lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ const Token * Tokenizer::isFunctionHead(const Token *tok, const std::string &end
if (Token::Match(tok, "%name% (") && tok->isUpperCaseName())
tok = tok->linkAt(1)->next();
if (tok && tok->originalName() == "->") { // trailing return type
for (tok = tok->next(); tok && !Token::Match(tok, ";|{|override|final"); tok = tok->next())
for (tok = tok->next(); tok && !Token::Match(tok, ";|{|override|final|}|)|]"); tok = tok->next())
if (tok->link() && Token::Match(tok, "<|[|("))
tok = tok->link();
}
Expand All @@ -141,6 +141,14 @@ const Token * Tokenizer::isFunctionHead(const Token *tok, const std::string &end
tok = tok->next();
if (Token::Match(tok, "= 0|default|delete ;"))
tok = tok->tokAt(2);
if (Token::simpleMatch(tok, "requires")) {
for (tok = tok->next(); tok && !Token::Match(tok, ";|{|}|)|]"); tok = tok->next()) {
if (tok->link() && Token::Match(tok, "<|[|("))
tok = tok->link();
if (Token::simpleMatch(tok, "bool {"))
tok = tok->linkAt(1);
}
}
if (tok && tok->str() == ":" && !Token::Match(tok->next(), "%name%|::"))
return nullptr;
return (tok && endsWith.find(tok->str()) != std::string::npos) ? tok : nullptr;
Expand Down
6 changes: 6 additions & 0 deletions test/testtokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7671,6 +7671,12 @@ class TestTokenizer : public TestFixture {
{
ASSERT_NO_THROW(tokenizeAndStringify("template<class T, class U>\n"
"struct X { X(U) requires true {} };\n"));
ASSERT_NO_THROW(tokenizeAndStringify("template<class T, class U>\n"
"struct X { X(U) requires bool{std::is_integral<T>{}} {} };\n"));
ASSERT_NO_THROW(tokenizeAndStringify("template <typename T>\n"
"struct test { operator int() requires true { return 0; } };\n"));
ASSERT_NO_THROW(tokenizeAndStringify("template <typename T>\n"
"struct test { operator int() requires bool{std::is_integral<T>{}} { return 0; } };\n"));
}

void noCrash1() {
Expand Down

0 comments on commit 06f5689

Please sign in to comment.