commit 9efd799a8b6b7d1a9ab4a2cae8a6abc84e1e3019
parent 072394f859acc74b486339b35670f2d350322249
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Tue, 19 May 2026 23:35:37 -0700
Fix macro argument parsing for unbalanced braces
Diffstat:
6 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/lang/c/parse/parse_init.c b/lang/c/parse/parse_init.c
@@ -962,6 +962,7 @@ static void check_static_integer_initializer_range(Parser* p, const Type* ty,
const Type* dst = type_unqual(p->pool, ty);
u32 bits;
if (!dst || !type_is_int(dst) || dst->kind == TY_BOOL) return;
+ if (dst->kind == TY_CHAR) return;
if (!c_abi_type_info(p->abi, dst).signed_) return;
bits = c_abi_sizeof(p->abi, dst) * 8u;
if (bits < 64u) {
diff --git a/lang/c/pp/pp_expand.c b/lang/c/pp/pp_expand.c
@@ -523,10 +523,10 @@ static Tok read_invocation_args(Pp* pp, const Macro* m, SrcLoc invoke_loc,
if (t.kind == TOK_PUNCT) {
u32 p = t.v.punct;
- if (p == '(' || p == '[' || p == '{') {
+ if (p == '(') {
++depth;
- } else if (p == ')' || p == ']' || p == '}') {
- if (p == ')' && depth == 0) {
+ } else if (p == ')') {
+ if (depth == 0) {
/* End of invocation. Close the current argument. The
* empty-args case (no commas seen, no tokens
* collected) emits a slot only when the macro expects
diff --git a/test/parse/cases/6_10_04_macro_unbalanced_brace_arg.c b/test/parse/cases/6_10_04_macro_unbalanced_brace_arg.c
@@ -0,0 +1,10 @@
+#define DROP(x)
+#define WRAP(flag) \
+ do { \
+ DROP(if (flag) {) return 7; \
+ } while (0)
+
+int test_main(void) {
+ WRAP(1);
+ return 3;
+}
diff --git a/test/parse/cases/6_10_04_macro_unbalanced_brace_arg.expected b/test/parse/cases/6_10_04_macro_unbalanced_brace_arg.expected
@@ -0,0 +1 @@
+7
diff --git a/test/parse/cases/6_7_9_35_plain_char_static_init.c b/test/parse/cases/6_7_9_35_plain_char_static_init.c
@@ -0,0 +1,12 @@
+typedef unsigned int u32;
+typedef struct {
+ char c[4];
+} V32;
+typedef union {
+ V32 v;
+ u32 u;
+} V32Uni;
+
+static const V32Uni x = {{0x80, 0, 0, 0}};
+
+int test_main(void) { return (unsigned char)x.v.c[0]; }
diff --git a/test/parse/cases/6_7_9_35_plain_char_static_init.expected b/test/parse/cases/6_7_9_35_plain_char_static_init.expected
@@ -0,0 +1 @@
+128