aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2015-11-13 15:42:25 +0100
committerXavier Leroy <xavier.leroy@inria.fr>2015-11-13 15:42:25 +0100
commit9f0fcc2c52d136fb8891f1ce2e135bdb1273df19 (patch)
tree0a536a5e755514cad2acfad746282cadf7f8926c
parent3f24b362f5ac2aa252ee14f1b793ebbf2f69ff08 (diff)
downloadcompcert-kvx-9f0fcc2c52d136fb8891f1ce2e135bdb1273df19.tar.gz
compcert-kvx-9f0fcc2c52d136fb8891f1ce2e135bdb1273df19.zip
Issue #71: incorrect initialization of wchar_t arrays from wide string literal
Regression test added in regression/initializers.c
-rw-r--r--cparser/Elab.ml12
-rw-r--r--test/regression/Results/initializers3
-rw-r--r--test/regression/initializers.c26
3 files changed, 35 insertions, 6 deletions
diff --git a/cparser/Elab.ml b/cparser/Elab.ml
index 27b650c0..d58d8be6 100644
--- a/cparser/Elab.ml
+++ b/cparser/Elab.ml
@@ -850,18 +850,18 @@ let init_char_array_string opt_size s =
Init_array (add_chars (Int64.pred size) [])
let init_int_array_wstring opt_size s =
- let len = Int64.of_int (List.length s) in
+ let a = Array.of_list s in
+ let len = Int64.of_int (Array.length a) 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 =
+ let rec add_chars i 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)
+ let c = if i < len then a.(Int64.to_int i) else 0L in
+ add_chars (Int64.pred i) (Init_single (intconst c IInt) :: init)
end in
- Init_array (add_chars (Int64.pred size) (List.rev s) [])
+ Init_array (add_chars (Int64.pred size) [])
let check_init_type loc env a ty =
if wrap2 valid_assignment loc env a ty then ()
diff --git a/test/regression/Results/initializers b/test/regression/Results/initializers
index 18339f74..a3c92e86 100644
--- a/test/regression/Results/initializers
+++ b/test/regression/Results/initializers
@@ -25,3 +25,6 @@ x23 = { hd = 8, tl = ok }
x24[6] = { '/', '*', 'B', '*', '/', 0, }
x25[4] = { "/tmp" }
x26[6] = { 'w', 'o', 'r', 'l', 'd', 0, }
+x27[4] = { 'a', 'b', 'c', 0, }
+x28[2] = { 'a', 'b', }
+x29[10] = { 'a', 'b', 'c', 0, 0, 0, 0, 0, 0, 0, }
diff --git a/test/regression/initializers.c b/test/regression/initializers.c
index 31f73734..6c8fadc9 100644
--- a/test/regression/initializers.c
+++ b/test/regression/initializers.c
@@ -1,3 +1,4 @@
+#include <stddef.h>
#include <stdio.h>
int x0;
@@ -67,6 +68,11 @@ char * x25[] = { "/tmp" };
/* One more */
char x26[] = { "world" };
+/* Wide strings (issue #71) */
+wchar_t x27[] = L"abc";
+wchar_t x28[2] = L"abc";
+wchar_t x29[10] = L"abc";
+
static void print_chars(char * s, int sz)
{
int i;
@@ -78,6 +84,17 @@ static void print_chars(char * s, int sz)
}
}
+static void print_wchars(wchar_t * s, int sz)
+{
+ int i;
+ for (i = 0; i < sz; i++) {
+ if (s[i] >= 32 && s[i] < 127)
+ printf("'%c', ", (char) s[i]);
+ else
+ printf("%d, ", (int) s[i]);
+ }
+}
+
int main()
{
int i;
@@ -137,6 +154,15 @@ int main()
printf("x26[%d] = { ", (int) sizeof(x26));
print_chars(x26, sizeof(x26));
printf("}\n");
+ printf("x27[%d] = { ", (int) (sizeof(x27) / sizeof(wchar_t)));
+ print_wchars(x27, sizeof(x27) / sizeof(wchar_t));
+ printf("}\n");
+ printf("x28[%d] = { ", (int) (sizeof(x28) / sizeof(wchar_t)));
+ print_wchars(x28, sizeof(x28) / sizeof(wchar_t));
+ printf("}\n");
+ printf("x29[%d] = { ", (int) (sizeof(x29) / sizeof(wchar_t)));
+ print_wchars(x29, sizeof(x29) / sizeof(wchar_t));
+ printf("}\n");
return 0;
}