From 4489091cae922592f67bcc4b874856c76ca71b0c Mon Sep 17 00:00:00 2001 From: xleroy Date: Fri, 25 Oct 2013 08:07:02 +0000 Subject: Revise parsing of character constants for conformance with ISO C 99. git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@2352 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- cparser/Ceval.mli | 1 + cparser/Elab.ml | 25 +++++++++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/cparser/Ceval.mli b/cparser/Ceval.mli index c7f7aa8..7425a33 100644 --- a/cparser/Ceval.mli +++ b/cparser/Ceval.mli @@ -15,3 +15,4 @@ val integer_expr : Env.t -> C.exp -> int64 option val constant_expr : Env.t -> C.typ -> C.exp -> C.constant option +val normalize_int : int64 -> C.ikind -> int64 diff --git a/cparser/Elab.ml b/cparser/Elab.ml index 7e14144..d0e1b28 100644 --- a/cparser/Elab.ml +++ b/cparser/Elab.ml @@ -215,20 +215,23 @@ let elab_float_constant loc f = let elab_char_constant loc sz cl = let nbits = 8 * sz in (* Treat multi-char constants as a number in base 2^nbits *) + let max_digit = Int64.shift_left 1L nbits in let max_val = Int64.shift_left 1L (64 - nbits) in let v = List.fold_left (fun acc d -> - if acc >= max_val then begin - error loc "character literal overflows"; - end; + if acc >= max_val then + error loc "character constant overflows"; + if d >= max_digit then + warning loc "escape sequence out of range"; Int64.add (Int64.shift_left acc nbits) d) 0L cl in - let ty = - if v < 256L then IInt - else if v < Int64.shift_left 1L (8 * sizeof_ikind IULong) then IULong - else IULongLong in - (v, ty) + if not (integer_representable v IInt) then + error loc "character constant cannot be represented at type 'int'"; + (* C99 6.4.4.4 item 10: single character -> represent at type char *) + if List.length cl = 1 + then Ceval.normalize_int v IChar + else v let elab_constant loc = function | CONST_INT s -> @@ -238,11 +241,9 @@ let elab_constant loc = function let (v, fk) = elab_float_constant loc f in CFloat(v, fk) | CONST_CHAR cl -> - let (v, ik) = elab_char_constant loc 1 cl in - CInt(v, ik, "") + CInt(elab_char_constant loc 1 cl, IInt, "") | CONST_WCHAR cl -> - let (v, ik) = elab_char_constant loc !config.sizeof_wchar cl in - CInt(v, ik, "") + CInt(elab_char_constant loc !config.sizeof_wchar cl, IInt, "") | CONST_STRING s -> CStr s | CONST_WSTRING s -> CWStr s -- cgit v1.2.3