From f535ac931c2b7dc65fefa83e47bb8c79ca90e92d Mon Sep 17 00:00:00 2001 From: xleroy Date: Mon, 17 Oct 2011 09:38:31 +0000 Subject: Corrected initialization of char arrays by string literals. Added -flongdouble option (to turn long double into double) git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1731 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- cfrontend/C2C.ml | 4 ++- cparser/Elab.ml | 47 +++++++++++++++++------------------ driver/Clflags.ml | 1 + driver/Driver.ml | 4 ++- test/regression/Results/initializers | Bin 404 -> 465 bytes test/regression/initializers.c | 25 +++++++++++++++++-- 6 files changed, 53 insertions(+), 28 deletions(-) diff --git a/cfrontend/C2C.ml b/cfrontend/C2C.ml index a5167809..2f50a0e9 100644 --- a/cfrontend/C2C.ml +++ b/cfrontend/C2C.ml @@ -256,7 +256,9 @@ let convertIkind = function let convertFkind = function | C.FFloat -> F32 | C.FDouble -> F64 - | C.FLongDouble -> unsupported "'long double' type"; F64 + | C.FLongDouble -> + if not !Clflags.option_flongdouble then unsupported "'long double' type"; + F64 let int64_struct = let ty = Tint(I32,Unsigned) in diff --git a/cparser/Elab.ml b/cparser/Elab.ml index a4e934bf..870385de 100644 --- a/cparser/Elab.ml +++ b/cparser/Elab.ml @@ -763,7 +763,7 @@ let elab_expr loc env a = let b1 = elab a1 in let (fld, attrs) = match unroll env b1.etyp with - | TPtr(t, _) -> + | TPtr(t, _) | TArray(t,_,_) -> begin match unroll env t with | TStruct(id, attrs) -> (wrap Env.find_struct_member loc env (id, fieldname), attrs) @@ -1262,34 +1262,33 @@ let project_init loc il = i) il -let below_optsize n opt_sz = - match opt_sz with None -> true | Some sz -> n < sz - let init_char_array_string opt_size s = - let init = ref [] - and len = ref 0L in - let enter x = - if below_optsize !len opt_size then begin - init := Init_single (intconst x IChar) :: !init; - len := Int64.succ !len + let len = Int64.of_int (String.length s) in + let size = + match opt_size with + | Some sz -> sz + | None -> Int64.succ len (* include final 0 character *) in + let rec add_chars i init = + if i < 0L then init else begin + let c = + if i < len then Int64.of_int (Char.code s.[Int64.to_int i]) else 0L in + add_chars (Int64.pred i) (Init_single (intconst c IChar) :: init) end in - for i = 0 to String.length s - 1 do - enter (Int64.of_int (Char.code s.[i])) - done; - enter 0L; - Init_array (List.rev !init) + Init_array (add_chars (Int64.pred size) []) let init_int_array_wstring opt_size s = - let init = ref [] - and len = ref 0L in - let enter x = - if below_optsize !len opt_size then begin - init := Init_single (intconst x IInt) :: !init; - len := Int64.succ !len + let len = Int64.of_int (List.length s) in + let size = + match opt_size with + | Some sz -> sz + | None -> Int64.succ len (* include final 0 character *) in + let rec add_chars i s init = + if i < 0L then init else begin + let (c, s') = + match s with [] -> (0L, []) | c::s' -> (c, s') in + add_chars (Int64.pred i) s' (Init_single (intconst c IInt) :: init) end in - List.iter enter s; - enter 0L; - Init_array (List.rev !init) + Init_array (add_chars (Int64.pred size) (List.rev s) []) let check_init_type loc env a ty = if valid_assignment env a ty then () diff --git a/driver/Clflags.ml b/driver/Clflags.ml index fe14ba7c..cb26b725 100644 --- a/driver/Clflags.ml +++ b/driver/Clflags.ml @@ -16,6 +16,7 @@ let prepro_options = ref ([]: string list) let linker_options = ref ([]: string list) let exe_name = ref "a.out" let option_flonglong = ref true +let option_flongdouble = ref false let option_fstruct_passing = ref false let option_fstruct_assign = ref false let option_fbitfields = ref false diff --git a/driver/Driver.ml b/driver/Driver.ml index 1139e7a4..3aff4e0f 100644 --- a/driver/Driver.ml +++ b/driver/Driver.ml @@ -338,6 +338,7 @@ Preprocessing options: Language support options (use -fno- to turn off -f) : -fbitfields Emulate bit fields in structs [off] -flonglong Partial emulation of 'long long' types [on] + -flongdouble Treat 'long double' as 'double' [off] -fstruct-passing Emulate passing structs and unions by value [off] -fstruct-assign Emulate assignment between structs or unions [off] -fvararg-calls Emulate calls to variable-argument functions [on] @@ -379,7 +380,7 @@ Interpreter mode: " let language_support_options = [ - option_fbitfields; option_flonglong; option_fstruct_passing; + option_fbitfields; option_flonglong; option_flongdouble; option_fstruct_passing; option_fstruct_assign; option_fvararg_calls; option_fpacked_structs; option_fvolatile_rmw ] @@ -438,6 +439,7 @@ let cmdline_actions = List.iter (fun r -> r := false) language_support_options); ] @ f_opt "longlong" option_flonglong + @ f_opt "longdouble" option_flongdouble @ f_opt "struct-passing" option_fstruct_passing @ f_opt "struct-assign" option_fstruct_assign @ f_opt "bitfields" option_fbitfields diff --git a/test/regression/Results/initializers b/test/regression/Results/initializers index b626a2af..67460cc4 100644 Binary files a/test/regression/Results/initializers and b/test/regression/Results/initializers differ diff --git a/test/regression/initializers.c b/test/regression/initializers.c index c16a3567..a0913fda 100644 --- a/test/regression/initializers.c +++ b/test/regression/initializers.c @@ -46,6 +46,21 @@ char * x18 = "Hello!"; char * x19[2] = { "Hello", "world!" }; +char x20[3] = "Hello!"; + +char x21[10] = "Hello!"; + +static void print_chars(char * s, int sz) +{ + int i; + for (i = 0; i < sz; i++) { + if (s[i] >= 32 && s[i] < 127) + printf("'%c', ", s[i]); + else + printf("%d, ", s[i]); + } +} + int main() { int i; @@ -62,7 +77,7 @@ int main() printf("x7 = { %d, '%c' }\n", x7.y, x7.z); printf("x8 = { '%c', %d }\n", x8.y, x8.z); printf("x9 = { { "); - for (i = 0; i < 9; i++) printf("'%c', ", x9.y[i]); + print_chars(x9.y, 9); printf("}, %.3f }\n", x9.z); printf("x10 = { { '%c', %d }, %.3f }\n", x10.u.y, x10.u.z, x10.v); @@ -81,10 +96,16 @@ int main() else printf("x16 error\n"); printf("x17[%d] = { ", (int) sizeof(x17)); - for (i = 0; i < sizeof(x17); i++) printf("'%c', ", x17[i]); + print_chars(x17, sizeof(x17)); printf("}\n"); printf("x18 = \"%s\"\n", x18); printf("x19 = { \"%s\", \"%s\" }\n", x19[0], x19[1]); + printf("x20 = { "); + print_chars(x20, sizeof(x20)); + printf("}\n"); + printf("x21 = { "); + print_chars(x21, sizeof(x21)); + printf("}\n"); return 0; } -- cgit