summaryrefslogtreecommitdiff
path: root/cparser
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2013-10-25 08:07:02 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2013-10-25 08:07:02 +0000
commit4489091cae922592f67bcc4b874856c76ca71b0c (patch)
tree4d9be82ae76c448b975eff38524680ab32072152 /cparser
parent014c59b41e554f8294f184244402e285a143c794 (diff)
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
Diffstat (limited to 'cparser')
-rw-r--r--cparser/Ceval.mli1
-rw-r--r--cparser/Elab.ml25
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