Skip to content

Commit

Permalink
C++23 if consteval
Browse files Browse the repository at this point in the history
  • Loading branch information
guwirth committed Aug 28, 2024
1 parent 41ab59e commit 3dfda75
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 9 deletions.
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';
}

0 comments on commit 3dfda75

Please sign in to comment.