From 6a0c34f658eddfea38798f3359136f84d9087cd8 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 10 Jul 2024 19:14:42 +0200 Subject: [PATCH] [typing] allow parenthesizing string literals that initialize an array --- src/kernel_internals/typing/cabs2cil.ml | 31 +++++++++++++------ tests/syntax/init_array_string.i | 8 +++++ .../oracle/init_array_string.res.oracle | 7 +++++ 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index 8bd77a0e771..a45a7cc0065 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -7947,16 +7947,21 @@ and doInitializer loc local_env (vi: varinfo) (inite: Cabs.init_expression) let open Current_loc.Operators in let checkArrayInit ty init = - if Cil.isArrayType ty then - match init with - | COMPOUND_INIT _ - | SINGLE_INIT - { expr_node = - CONSTANT (CONST_STRING _ - | CONST_WSTRING _)} -> () - | _ -> - Kernel.error ~current:true ~once:true - "Array initializer must be an initializer list or string literal" + let init_ok = + if Cil.isArrayType ty then + match init with + | COMPOUND_INIT _ -> true + | SINGLE_INIT e -> + (match stripParen e with + { expr_node = + CONSTANT (CONST_STRING _ | CONST_WSTRING _)} -> true + | _ -> false) + | _ -> false + else true + in + if not init_ok then + Kernel.error ~current:true ~once:true + "Array initializer must be an initializer list or string literal"; in Kernel.debug ~dkey:Kernel.dkey_typing_init "@\nStarting a new initializer for %s : %a@\n" @@ -8005,6 +8010,12 @@ and doInitializer loc local_env (vi: varinfo) (inite: Cabs.init_expression) and doInit local_env asconst preinit so acc initl = let ghost = local_env.is_ghost in let whoami fmt = Cil_printer.pp_lval fmt (Var so.host, so.soOff) in + let initl = + match initl with + | (initwhat, SINGLE_INIT e)::tl -> + (initwhat, SINGLE_INIT (stripParen e)) ::tl + | _ -> initl + in let initl1 = match initl with | (Cabs.NEXT_INIT, diff --git a/tests/syntax/init_array_string.i b/tests/syntax/init_array_string.i index b301c8d102c..1891c5ad946 100644 --- a/tests/syntax/init_array_string.i +++ b/tests/syntax/init_array_string.i @@ -9,3 +9,11 @@ char b[] = ("A" "B"); char c[] = "ABC"; char d[] = ("ABC"); + +struct S { + char c[42]; +}; + +struct S s = { .c = ("foo") }; + +char as[3][4] = { ("bar"), [2] = ("bla") }; diff --git a/tests/syntax/oracle/init_array_string.res.oracle b/tests/syntax/oracle/init_array_string.res.oracle index 92a54fcd30d..e678a6a4f01 100644 --- a/tests/syntax/oracle/init_array_string.res.oracle +++ b/tests/syntax/oracle/init_array_string.res.oracle @@ -1,9 +1,16 @@ [kernel] Parsing init_array_string.i (no preprocessing) /* Generated by Frama-C */ +struct S { + char c[42] ; +}; char *ptr = (char *)"AB"; char *ptr2 = (char *)"AB"; char a[3] = {(char)'A', (char)'B', (char)'\000'}; char b[3] = {(char)'A', (char)'B', (char)'\000'}; char c[4] = {(char)'A', (char)'B', (char)'C', (char)'\000'}; char d[4] = {(char)'A', (char)'B', (char)'C', (char)'\000'}; +struct S s = {.c = {(char)'f', (char)'o', (char)'o', (char)'\000'}}; +char as[3][4] = + {{(char)'b', (char)'a', (char)'r', (char)'\000'}, + [2] = {(char)'b', (char)'l', (char)'a', (char)'\000'}}; -- GitLab