Commit: runtime(c): compound literal braces are highlighted as errors

Christian Brabandt <[email protected]> Tue, 4 Aug 2026 23:30:03 +0200
Newsgroups gmane.editors.vim.devel
Message-ID <[email protected]>
runtime(c): compound literal braces are highlighted as errors

Commit: https://github.com/vim/vim/commit/5a1124e4f59fafa0c774db956ae1e86bd=
d259442
Author: Bogdan Barbu <[email protected]>
Date:   Tue Aug 4 21:11:56 2026 +0000

    runtime(c): compound literal braces are highlighted as errors
   =20
    Problem: Braces in C compound literals and initializers inside parenthe=
ses
             and brackets are highlighted as errors.
   =20
    Solution: Recognize those initializer blocks while preserving syntax re=
covery
              for malformed parentheses.
   =20
    fixes:  #18709
    closes: #20842
   =20
    Signed-off-by: Bogdan Barbu <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/syntax/c.vim b/runtime/syntax/c.vim
index 683810952..9b18c2b8a 100644
--- a/runtime/syntax/c.vim
+++ b/runtime/syntax/c.vim
@@ -1,7 +1,7 @@
 " Vim syntax file
 " Language:		C
 " Maintainer:		The Vim Project <https://github.com/vim/vim>
-" Last Change:		2026 Jun 01
+" Last Change:		2026 Jul 25
 " Former Maintainer:	Bram Moolenaar <[email protected]>
=20
 " Quit when a (custom) syntax file was already loaded
@@ -138,7 +138,7 @@ endif
 " This should be before cErrInParen to avoid problems with #define ({ xxx =
})
 if exists("c_curly_error")
   syn match cCurlyError "}"
-  syn region	cBlock		start=3D"{" end=3D"}" contains=3DALLBUT,cBadBlock,cCu=
rlyError,@cParenGroup,cErrInParen,cCppParen,cErrInBracket,cCppBracket,@cStr=
ingGroup,@Spell fold
+  syn region	cBlock		start=3D"{" end=3D"}" contains=3DALLBUT,cBadBlock,cCu=
rlyError,cInitBlock,@cParenGroup,cErrInParen,cCppParen,cErrInBracket,cCppBr=
acket,@cStringGroup,@Spell fold
 else
   syn region	cBlock		start=3D"{" end=3D"}" transparent fold
 endif
@@ -146,7 +146,7 @@ endif
 " Catch errors caused by wrong parenthesis and brackets.
 " Also accept <% for {, %> for }, <: for [ and :> for ] (C99)
 " But avoid matching <::.
-syn cluster	cParenGroup	contains=3DcParenError,cIncluded,cSpecial,cComment=
Skip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUser=
Label,cBitField,cOctalZero,@cCppOutInGroup,cFormat,cNumber,cFloat,cOctal,cO=
ctalError,cNumbersCom
+syn cluster	cParenGroup	contains=3DcParenError,cIncluded,cSpecial,cComment=
Skip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUser=
Label,cBitField,cOctalZero,@cCppOutInGroup,cFormat,cNumber,cFloat,cOctal,cO=
ctalError,cNumbersCom,cBadParenBlock
 if exists("c_no_curly_error")
   if s:in_cpp_family && !exists("cpp_no_cpp11")
     syn region	cParen		transparent start=3D'(' end=3D')' contains=3DALLBUT=
,@cParenGroup,cCppParen,@cStringGroup,@Spell
@@ -198,8 +198,15 @@ endif
=20
 if s:ft =3D=3D# 'c' || exists("cpp_no_cpp11")
   syn region	cBadBlock	keepend start=3D"{" end=3D"}" contained containedin=
=3DcParen,cBracket,cBadBlock transparent fold
+  if !exists("c_no_curly_error") && !exists("c_no_bracket_error")
+    " Do not mistake an unmatched ')' followed by a block for a compound l=
iteral.
+    syn region	cBadParenBlock	keepend transparent start=3D')\_s*\ze\%({\|<=
%\)' matchgroup=3DcErrInBracket end=3D'}\|%>' contained containedin=3DcBrac=
ket,cBadBlock contains=3DALLBUT,cBlock,cBadBlock,cInitBlock,@cParenGroup,cE=
rrInParen,cCppParen,cCppBracket,@cStringGroup,@Spell
+  endif
 endif
=20
+" Compound literals and initializers may appear inside parentheses or brac=
kets.
+syn region	cInitBlock	transparent matchgroup=3DcInitBlock start=3D'\%([)=
=3D]\_s*\)\@<=3D\%({\|<%\)' end=3D'}\|%>' contained containedin=3DcParen,cB=
racket,cBadBlock contains=3DALLBUT,cBlock,cCurlyError,@cParenGroup,cErrInPa=
ren,cCppParen,cErrInBracket,cCppBracket,@cStringGroup,@Spell,cInitBlock fol=
d
+
 "integer number, or floating point number without a dot and with "f".
 syn case ignore
 syn match	cNumbers	display transparent "\<\d\|\.\d" contains=3DcNumber,cFl=
oat,cOctalError,cOctal
diff --git a/runtime/syntax/testdir/dumps/c_initializer_00.dump b/runtime/s=
yntax/testdir/dumps/c_initializer_00.dump
new file mode 100644
index 000000000..426a1e958
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/c_initializer_00.dump
@@ -0,0 +1,20 @@
+>/+0#0000e05#ffffff0@1| |C|o|m|p|o|u|n|d| |l|i|t|e|r|a|l|s| |a|n|d| |i|n|i=
|t|i|a|l|i|z|e|r|s| |i|n|s|i|d|e| |e|x|p|r|e|s@1|i|o|n|s| +0#0000000&@18
+|v+0#00e0003&|o|i|d| +0#0000000&|t|e|s|t|(|v+0#00e0003&|o|i|d|)+0#0000000&=
| @59
+|{| @73
+@4|i+0#00e0003&|n|t| +0#0000000&|a|[|(|s+0#00e0003&|t|r|u|c|t| +0#0000000&=
|f|o@1|)|{| |4+0#e000002&|2| +0#0000000&|}|.|b|a|r|]|;| @40
+@4|s+0#00e0003&|t|r|u|c|t| +0#0000000&|f|o@1| |b| |=3D| |(@1|s+0#00e0003&|=
t|r|u|c|t| +0#0000000&|f|o@1|)|{| |}|)|;| @37
+@4|_+0#af5f00255&|S|t|a|t|i|c|_|a|s@1|e|r|t|(+0#0000000&|s+0#af5f00255&|i|=
z|e|o|f| +0#0000000&|(|i+0#00e0003&|n|t| +0#0000000&|[|]|)|{| |1+0#e000002&=
|,+0#0000000&| |2+0#e000002&|,+0#0000000&| |3+0#e000002&| +0#0000000&|}| |=
=3D@1| |3+0#e000002&| +0#0000000&|*| |s+0#af5f00255&|i|z|e|o|f| +0#0000000&=
|(|i+0#00e0003&|n|t|)+0#0000000&|,| |"+0#e000002&@1|)+0#0000000&|;| @3
+@4|f+0#af5f00255&|o|r| +0#0000000&|(|s+0#00e0003&|t|r|u|c|t| +0#0000000&|f=
|o@1| |i| |=3D| |{| |}|;@1|)| |b+0#af5f00255&|r|e|a|k|;+0#0000000&| @37
+@4|i+0#00e0003&|n|t| +0#0000000&|c|[|(|s+0#00e0003&|t|r|u|c|t| +0#0000000&=
|f|o@1|)| |<|%| |4+0#e000002&|2| +0#0000000&|%|>|.|b|a|r|]|;| @37
+@4|s+0#00e0003&|t|r|u|c|t| +0#0000000&|f|o@1| |d| |=3D| |(@1|s+0#00e0003&|=
t|r|u|c|t| +0#0000000&|f|o@1|)| |<|%| |%|>|)|;| @34
+@4|f|(@1|i+0#00e0003&|n|t| +0#0000000&|[|2+0#e000002&|]+0#0000000&|[|2+0#e=
000002&|]+0#0000000&|)|{@1| |1+0#e000002&|,+0#0000000&| |2+0#e000002&| +0#0=
000000&|}|,| |{| |3+0#e000002&|,+0#0000000&| |4+0#e000002&| +0#0000000&|}@1=
|)|;| @34
+@4|s|y|s|c|a|l@1|(|S|Y|S|_|c|l|o|c|k|_|s|e|t@1|i|m|e|,| |C|L|O|C|K|_|R|E|A=
|L|T|I|M|E|,| @28
+@8|t|v| |?| |&|(@1|s+0#00e0003&|t|r|u|c|t| +0#0000000&|t|i|m|e|s|p|e|c|)|{=
| |.|t|v|_|s|e|c| |=3D| |t|v|-|>|t|v|_|s|e|c|,| @19
+@12|.|t|v|_|n|s|e|c| |=3D| |t|v|-|>|t|v|_|u|s|e|c| |*| |1+0#e000002&|0@2| =
+0#0000000&|}|)| |:| |0+0#e000002&|)+0#0000000&|;| @24
+@4|f|(@1|s+0#00e0003&|t|r|u|c|t| +0#0000000&|t|i|m|e|s|p|e|c|)| @51
+@6|<|%| |.|t|v|_|s|e|c| |=3D| |0+0#e000002&| +0#0000000&|%|>|)|;| @49
+@4|i+0#00e0003&|n|t| +0#0000000&|e|[|)+0#ffffff16#ff404010|{| +0#0000000#f=
fffff0|4+0#e000002&|2| +0#0000000&|}+0#ffffff16#ff404010|.+0#0000000#ffffff=
0|b|a|r|]|;| @51
+@4|f|(|a| |{+0#ffffff16#ff404010| +0#0000000#ffffff0|1+0#e000002&| +0#0000=
000&|}+0#ffffff16#ff404010|)+0#0000000#ffffff0|;| |f|(|a|,| |{+0#ffffff16#f=
f404010| +0#0000000#ffffff0|1+0#e000002&| +0#0000000&|}+0#ffffff16#ff404010=
|)+0#0000000#ffffff0|;| @46
+|}| @73
+|~+0#4040ff13&| @73
+| +0#0000000&@56|1|,|1| @10|A|l@1|=20
diff --git a/runtime/syntax/testdir/input/c_initializer.c b/runtime/syntax/=
testdir/input/c_initializer.c
new file mode 100644
index 000000000..a64747d46
--- /dev/null
+++ b/runtime/syntax/testdir/input/c_initializer.c
@@ -0,0 +1,18 @@
+// Compound literals and initializers inside expressions
+void test(void)
+{
+    int a[(struct foo){ 42 }.bar];
+    struct foo b =3D ((struct foo){ });
+    _Static_assert(sizeof (int []){ 1, 2, 3 } =3D=3D 3 * sizeof (int), "")=
;
+    for (struct foo i =3D { };;) break;
+    int c[(struct foo) <% 42 %>.bar];
+    struct foo d =3D ((struct foo) <% %>);
+    f((int [2][2]){{ 1, 2 }, { 3, 4 }});
+    syscall(SYS_clock_settime, CLOCK_REALTIME,
+        tv ? &((struct timespec){ .tv_sec =3D tv->tv_sec,
+            .tv_nsec =3D tv->tv_usec * 1000 }) : 0);
+    f((struct timespec)
+      <% .tv_sec =3D 0 %>);
+    int e[){ 42 }.bar];
+    f(a { 1 }); f(a, { 1 });
+}

--=20
--=20
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---=20
You received this message because you are subscribed to the Google Groups "=
vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1w=
rMi3-00DCXG-O4%40256bit.org.