Skip to content

Commit 211fb58

Browse files
Fix Issue 23226 - ImportC: allow single-argument _Static_assert(expr)
1 parent e58b452 commit 211fb58

4 files changed

Lines changed: 52 additions & 6 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
ImportC supports single-argument `_Static_assert(expr)`
2+
3+
C23 makes the message operand of a static assertion optional.
4+
ImportC now accepts both forms:
5+
6+
-------
7+
_Static_assert(sizeof(int) == 4);
8+
_Static_assert(sizeof(int) == 4, "unexpected int size");
9+
-------
10+
11+
The two-argument form continues to work as before. When the assertion
12+
fails and no message was supplied, the diagnostic reports that the
13+
condition is false.

compiler/src/dmd/cparse.d

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3289,8 +3289,13 @@ final class CParser(AST) : Parser!AST
32893289
}
32903290

32913291
/***********************************
3292-
* C11 6.7.10
3292+
* C11 6.7.10 / C23 6.7.12
32933293
* _Static_assert ( constant-expression , string-literal ) ;
3294+
* _Static_assert ( constant-expression ) ;
3295+
*
3296+
* C23 makes the message operand optional. Accepting the single-argument
3297+
* form cannot change the meaning of any valid C11 program, so it is
3298+
* enabled unconditionally.
32943299
*/
32953300
private AST.StaticAssert cparseStaticAssert()
32963301
{
@@ -3300,13 +3305,22 @@ final class CParser(AST) : Parser!AST
33003305
nextToken();
33013306
check(TOK.leftParenthesis);
33023307
auto exp = cparseConstantExp();
3303-
check(TOK.comma);
3304-
if (token.value != TOK.string_)
3305-
error("string literal expected");
3306-
auto msg = cparsePrimaryExp();
3308+
if (token.value == TOK.comma) // C23 6.7.12
3309+
{
3310+
nextToken();
3311+
if (token.value != TOK.string_)
3312+
error("string literal expected");
3313+
auto msg = cparsePrimaryExp();
3314+
check(TOK.rightParenthesis);
3315+
check(TOK.semicolon);
3316+
return new AST.StaticAssert(loc, exp, msg);
3317+
}
33073318
check(TOK.rightParenthesis);
33083319
check(TOK.semicolon);
3309-
return new AST.StaticAssert(loc, exp, msg);
3320+
// Use the Expressions* overload so a missing message stays null
3321+
// rather than a one-element array of null (matches D's parseStaticAssert).
3322+
AST.Expressions* msgs = null;
3323+
return new AST.StaticAssert(loc, exp, msgs);
33103324
}
33113325

33123326
/*************************
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* https://github.com/dlang/dmd/issues/23226
2+
* C23 6.7.12: message operand of _Static_assert is optional.
3+
*/
4+
5+
// C23 6.7.12 — single-argument form
6+
_Static_assert(1);
7+
8+
// C23 6.7.12 — two-argument form (parity with existing C11 support)
9+
_Static_assert(1, "ok");
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* TEST_OUTPUT:
2+
---
3+
fail_compilation/test23226.c(10): Error: static assert: `0` is false
4+
---
5+
*/
6+
7+
/* https://github.com/dlang/dmd/issues/23226
8+
* C23 6.7.12: failing single-argument _Static_assert still diagnoses.
9+
*/
10+
_Static_assert(0);

0 commit comments

Comments
 (0)