From ffd6080f9e1e742c73ac38354b31c6fc4e3963ba Mon Sep 17 00:00:00 2001 From: xleroy Date: Tue, 15 Mar 2011 12:41:45 +0000 Subject: Revised handling of sizeof(string-literal) git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1611 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- cparser/Elab.ml | 17 ++++++++++++----- test/regression/Makefile | 5 +++-- test/regression/Results/sizeof1 | 3 +++ test/regression/Results/sizeof2 | 2 ++ test/regression/sizeof1.c | 12 ++++++++++++ test/regression/sizeof2.c | 9 +++++++++ 6 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 test/regression/Results/sizeof1 create mode 100644 test/regression/Results/sizeof2 create mode 100644 test/regression/sizeof2.c diff --git a/cparser/Elab.ml b/cparser/Elab.ml index b79aa10b..92452b90 100644 --- a/cparser/Elab.ml +++ b/cparser/Elab.ml @@ -837,15 +837,22 @@ let elab_expr loc env a = | CAST ((spec, dcl), _) -> error "cast of initializer expression is not supported" - | EXPR_SIZEOF(CONSTANT(CONST_STRING s)) -> - let cst = CInt(Int64.of_int (String.length s), size_t_ikind, "") in - { edesc = EConst cst; etyp = type_of_constant cst } - | EXPR_SIZEOF a1 -> let b1 = elab a1 in if sizeof env b1.etyp = None then err "incomplete type %a" Cprint.typ b1.etyp; - { edesc = ESizeof b1.etyp; etyp = TInt(size_t_ikind, []) } + let bdesc = + (* Catch special cases sizeof("string literal") *) + match b1.edesc with + | EConst(CStr s) -> + let sz = String.length s + 1 in + EConst(CInt(Int64.of_int sz, size_t_ikind, "")) + | EConst(CWStr s) -> + let sz = (!config).sizeof_wchar * (List.length s + 1) in + EConst(CInt(Int64.of_int sz, size_t_ikind, "")) + | _ -> + ESizeof b1.etyp in + { edesc = bdesc; etyp = TInt(size_t_ikind, []) } | TYPE_SIZEOF (spec, dcl) -> let ty = elab_type loc env spec dcl in diff --git a/test/regression/Makefile b/test/regression/Makefile index eda31dee..377d2050 100644 --- a/test/regression/Makefile +++ b/test/regression/Makefile @@ -11,11 +11,12 @@ LIBS=$(LIBMATH) TESTS=bitfields1 bitfields2 bitfields3 bitfields4 \ bitfields5 bitfields6 bitfields7 \ expr1 initializers volatile2 \ - funct3 expr5 struct7 struct8 casts1 casts2 char1 + funct3 expr5 struct7 struct8 casts1 casts2 char1 \ + sizeof1 sizeof2 # Other tests: should compile to .s without errors (but expect warnings) EXTRAS=annot1 commaprec expr2 expr3 expr4 extern1 funct2 funptr1 init1 \ - init2 init3 init4 pragmas ptrs1 ptrs2 sizeof1 struct1 struct2 struct3 \ + init2 init3 init4 pragmas ptrs1 ptrs2 struct1 struct2 struct3 \ struct4 struct5 struct6 struct9 struct10 types1 volatile1 # Test known to fail diff --git a/test/regression/Results/sizeof1 b/test/regression/Results/sizeof1 new file mode 100644 index 00000000..674f6dad --- /dev/null +++ b/test/regression/Results/sizeof1 @@ -0,0 +1,3 @@ +sizeof(struct s) = 32, sizeof(tbl) = 32 +sizeof(struct bits1) = 1, sizeof(b1) = 1 +sizeof(struct bits2) = 8, sizeof(b2) = 8 diff --git a/test/regression/Results/sizeof2 b/test/regression/Results/sizeof2 new file mode 100644 index 00000000..fd3c81a4 --- /dev/null +++ b/test/regression/Results/sizeof2 @@ -0,0 +1,2 @@ +5 +5 diff --git a/test/regression/sizeof1.c b/test/regression/sizeof1.c index e8441a2c..d7d37d35 100644 --- a/test/regression/sizeof1.c +++ b/test/regression/sizeof1.c @@ -1,3 +1,5 @@ +#include + struct s { char c; union { int i[3]; double d; } n; @@ -29,3 +31,13 @@ struct bits2 { char b2[sizeof(struct bits2)]; /* should be 8 */ +int main() +{ + printf("sizeof(struct s) = %d, sizeof(tbl) = %d\n", + sizeof(struct s), sizeof(tbl)); + printf("sizeof(struct bits1) = %d, sizeof(b1) = %d\n", + sizeof(struct bits1), sizeof(b1)); + printf("sizeof(struct bits2) = %d, sizeof(b2) = %d\n", + sizeof(struct bits2), sizeof(b2)); + return 0; +} diff --git a/test/regression/sizeof2.c b/test/regression/sizeof2.c new file mode 100644 index 00000000..66e38c02 --- /dev/null +++ b/test/regression/sizeof2.c @@ -0,0 +1,9 @@ +#include +#include + +int main() +{ + printf("%d\n", sizeof("abcd")); + printf("%d\n", sizeof(L"abcd") / sizeof(wchar_t)); + return 0; +} -- cgit