Skip to content

Commit a071130

Browse files
Fix Issue 23226 - ImportC: allow single-argument _Static_assert(expr) (#23406)
1 parent e58b452 commit a071130

4 files changed

Lines changed: 45 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
/*************************

compiler/test/compilable/testcstuff1.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
// check the expression parser
22

3+
// https://github.com/dlang/dmd/issues/23226
4+
// C23 6.7.12 — message operand is optional
5+
_Static_assert(1);
6+
_Static_assert(1, "ok");
7+
38
_Static_assert(0 == 0, "ok");
49
_Static_assert(0 != 1, "ok");
510
_Static_assert(1 + 2 == 3, "ok");

compiler/test/fail_compilation/failcstuff3.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/* TEST_OUTPUT:
33
---
44
fail_compilation/failcstuff3.c(54): Error: redeclaration of `S22061`
5+
fail_compilation/failcstuff3.c(100): Error: static assert: `0` is false
56
---
67
*/
78

@@ -13,3 +14,9 @@ struct S22061
1314
int field;
1415
};
1516
typedef union S22061 S22061;
17+
18+
/***************************************************/
19+
// https://github.com/dlang/dmd/issues/23226
20+
// C23 6.7.12 — failing single-argument _Static_assert still diagnoses
21+
#line 100
22+
_Static_assert(0);

0 commit comments

Comments
 (0)