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.