Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++23 if consteval #2728

Merged
merged 1 commit into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions cxx-squid/dox/diff-cpp20-cpp23_grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,6 @@ label-seq:
label
label-seq label

selection-statement:
if constexpropt ( init-statementopt condition ) statement
if constexpropt ( init-statementopt condition ) statement else statement
if !opt consteval compound-statement
if !opt consteval compound-statement else statement
switch ( init-statementopt condition ) statement

**A.7 Declarations [gram.dcl]**

declaration:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,9 @@ private static void statements(LexerfulGrammarBuilder b) {
b.firstOf(
b.sequence(CxxKeyword.IF, b.optional(CxxKeyword.CONSTEXPR), "(", b.optional(initStatement), condition, ")",
statement, b.optional(CxxKeyword.ELSE, statement)), // C++
b.sequence(CxxKeyword.SWITCH, "(", b.optional(initStatement), condition, ")", statement)
b.sequence(CxxKeyword.IF, b.optional("!"), CxxKeyword.CONSTEVAL,
compoundStatement, b.optional(CxxKeyword.ELSE, statement)), // C++23
b.sequence(CxxKeyword.SWITCH, "(", b.optional(initStatement), condition, ")", statement) // C++
)
);

Expand Down
10 changes: 9 additions & 1 deletion cxx-squid/src/test/java/org/sonar/cxx/parser/StatementTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ void selectionStatement_reallife() {
// fix #2286
.matches("if(a() < 0 || c >= 1) {}")
.matches("if(a() < 0 || c > 1) {}")
.matches("if(a() < 0 || c >> 1) {}");
.matches("if(a() < 0 || c >> 1) {}")
// C++23
.matches("if !consteval {}")
.matches("if !consteval {} else ;");
}

@Test
Expand Down Expand Up @@ -131,6 +134,7 @@ void selectionStatement() {
mockRule(CxxGrammarImpl.statement);
mockRule(CxxGrammarImpl.condition);
mockRule(CxxGrammarImpl.initStatement);
mockRule(CxxGrammarImpl.compoundStatement);

assertThatParser()
.matches("if ( condition ) statement")
Expand All @@ -141,6 +145,10 @@ void selectionStatement() {
.matches("if constexpr ( condition ) statement else statement")
.matches("if ( initStatement condition ) statement else statement")
.matches("if constexpr ( initStatement condition ) statement else statement")
.matches("if consteval compoundStatement")
.matches("if ! consteval compoundStatement")
.matches("if consteval compoundStatement else statement")
.matches("if ! consteval compoundStatement else statement")
.matches("switch ( condition ) statement")
.matches("switch ( initStatement condition ) statement");
}
Expand Down
40 changes: 40 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++23/if-consteval.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
constexpr bool is_constant_evaluated() noexcept
{
if consteval { return true; } else { return false; }
}

constexpr bool is_runtime_evaluated() noexcept
{
if !consteval { return true; } else { return false; }
}

consteval std::uint64_t ipow_ct(std::uint64_t base, std::uint8_t exp)
{
if (!base) return base;
std::uint64_t res{1};
while (exp)
{
if (exp & 1) res *= base;
exp /= 2;
base *= base;
}
return res;
}

constexpr std::uint64_t ipow(std::uint64_t base, std::uint8_t exp)
{
if consteval // use a compile-time friendly algorithm
{
return ipow_ct(base, exp);
}
else // use runtime evaluation
{
return std::pow(base, exp);
}
}

int main(int, const char* argv[])
{
static_assert(ipow(0, 10) == 0 && ipow(2, 10) == 1024);
std::cout << ipow(std::strlen(argv[0]), 3) << '\n';
}
Loading