aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyril SIX <cyril.six@kalray.eu>2018-11-21 11:16:42 +0100
committerCyril SIX <cyril.six@kalray.eu>2018-11-21 11:16:42 +0100
commitb873e06abcee1c7f6a51aaabb973b550a52a5b61 (patch)
tree70ccd9c7cbba08e20b782217b1a2268b1afce3e9
parent65db9a4a02c30d8dd5ca89b6fe3e4524cd4c29a5 (diff)
parenteb7bd26e2b9eeed21d204bad26fa56c8a7937ffb (diff)
downloadcompcert-kvx-b873e06abcee1c7f6a51aaabb973b550a52a5b61.tar.gz
compcert-kvx-b873e06abcee1c7f6a51aaabb973b550a52a5b61.zip
Merge tag 'v3.4' into mppa_k1c
Conflicts: .gitignore
-rw-r--r--.gitignore3
-rw-r--r--Changelog137
-rw-r--r--Makefile33
-rw-r--r--VERSION2
-rw-r--r--arm/Asm.v13
-rw-r--r--arm/AsmToJSON.ml3
-rw-r--r--arm/Asmexpand.ml7
-rw-r--r--arm/Asmgen.v1
-rw-r--r--arm/Asmgenproof.v4
-rw-r--r--arm/TargetPrinter.ml4
-rw-r--r--backend/Allocproof.v17
-rw-r--r--backend/Asmexpandaux.ml32
-rw-r--r--backend/Asmexpandaux.mli6
-rw-r--r--backend/Asmgenproof0.v17
-rw-r--r--backend/Conventions.v53
-rw-r--r--backend/LTL.v19
-rw-r--r--backend/Linear.v2
-rw-r--r--backend/Lineartyping.v70
-rw-r--r--backend/Mach.v5
-rw-r--r--backend/Regalloc.ml8
-rw-r--r--backend/Stackingproof.v92
-rw-r--r--backend/Tunnelingproof.v14
-rw-r--r--cfrontend/C2C.ml42
-rw-r--r--cfrontend/SimplExpr.v1
-rw-r--r--cfrontend/SimplLocals.v1
-rw-r--r--cfrontend/SimplLocalsproof.v2
-rwxr-xr-xconfigure59
-rw-r--r--cparser/Bitfields.ml60
-rw-r--r--cparser/C.mli5
-rw-r--r--cparser/Cabs.v3
-rw-r--r--cparser/Ceval.ml104
-rw-r--r--cparser/Ceval.mli2
-rw-r--r--cparser/Cflow.ml2
-rw-r--r--cparser/Checks.ml1
-rw-r--r--cparser/Cleanup.ml11
-rw-r--r--cparser/Cprint.ml3
-rw-r--r--cparser/Cutil.ml197
-rw-r--r--cparser/Cutil.mli20
-rw-r--r--cparser/Diagnostics.ml34
-rw-r--r--cparser/Diagnostics.mli6
-rw-r--r--cparser/Elab.ml985
-rw-r--r--cparser/ExtendedAsm.ml4
-rw-r--r--cparser/GNUmakefile4
-rw-r--r--cparser/Lexer.mll8
-rw-r--r--cparser/Machine.ml14
-rw-r--r--cparser/Machine.mli4
-rw-r--r--cparser/MenhirLib/Alphabet.v (renamed from cparser/validator/Alphabet.v)0
-rw-r--r--cparser/MenhirLib/Automaton.v (renamed from cparser/validator/Automaton.v)0
-rw-r--r--cparser/MenhirLib/Grammar.v (renamed from cparser/validator/Grammar.v)0
-rw-r--r--cparser/MenhirLib/Interpreter.v (renamed from cparser/validator/Interpreter.v)0
-rw-r--r--cparser/MenhirLib/Interpreter_complete.v (renamed from cparser/validator/Interpreter_complete.v)16
-rw-r--r--cparser/MenhirLib/Interpreter_correct.v (renamed from cparser/validator/Interpreter_correct.v)0
-rw-r--r--cparser/MenhirLib/Interpreter_safe.v (renamed from cparser/validator/Interpreter_safe.v)0
-rw-r--r--cparser/MenhirLib/Main.v (renamed from cparser/validator/Main.v)0
-rw-r--r--cparser/MenhirLib/Tuples.v (renamed from cparser/validator/Tuples.v)0
-rw-r--r--cparser/MenhirLib/Validator_complete.v (renamed from cparser/validator/Validator_complete.v)0
-rw-r--r--cparser/MenhirLib/Validator_safe.v (renamed from cparser/validator/Validator_safe.v)0
-rw-r--r--cparser/PackedStructs.ml44
-rw-r--r--cparser/Parse.ml2
-rw-r--r--cparser/Parser.vy8
-rw-r--r--cparser/Rename.ml2
-rw-r--r--cparser/Unblock.ml2
-rw-r--r--cparser/deLexer.ml1
-rw-r--r--cparser/handcrafted.messages1123
-rw-r--r--cparser/pre_parser.mly1
-rw-r--r--debug/DwarfPrinter.ml2
-rw-r--r--doc/ccomp.150
-rw-r--r--doc/coq2html.css97
-rw-r--r--doc/coq2html.js24
-rw-r--r--doc/coq2html.mll454
-rw-r--r--doc/coqdoc.css62
-rw-r--r--doc/index.html232
-rw-r--r--driver/Assembler.mli2
-rw-r--r--driver/Commandline.ml12
-rw-r--r--driver/Complements.v246
-rw-r--r--driver/Driver.ml2
-rw-r--r--driver/Driveraux.ml2
-rw-r--r--driver/Frontend.ml23
-rw-r--r--driver/Frontend.mli2
-rw-r--r--driver/Linker.ml2
-rw-r--r--driver/Linker.mli4
-rw-r--r--exportclight/Clightgen.ml3
-rw-r--r--exportclight/ExportClight.ml22
-rw-r--r--flocq/Appli/Fappli_IEEE.v5
-rw-r--r--flocq/Appli/Fappli_double_round.v62
-rw-r--r--flocq/Core/Fcore_FLT.v29
-rw-r--r--flocq/Core/Fcore_Raux.v9
-rw-r--r--flocq/Core/Fcore_ulp.v218
-rw-r--r--flocq/Flocq_version.v2
-rw-r--r--flocq/Prop/Fprop_mult_error.v2
-rw-r--r--flocq/Prop/Fprop_plus_error.v269
-rw-r--r--lib/Camlcoq.ml2
-rw-r--r--lib/Coqlib.v1
-rw-r--r--lib/Readconfig.mll6
-rw-r--r--powerpc/Asm.v15
-rw-r--r--powerpc/AsmToJSON.ml6
-rw-r--r--powerpc/Asmexpand.ml29
-rw-r--r--powerpc/Asmgenproof.v4
-rw-r--r--powerpc/CBuiltins.ml14
-rw-r--r--powerpc/TargetPrinter.ml9
-rw-r--r--riscV/Asm.v15
-rw-r--r--riscV/Asmexpand.ml10
-rw-r--r--riscV/Asmgenproof.v4
-rw-r--r--riscV/TargetPrinter.ml4
-rw-r--r--runtime/include/stddef.h9
-rw-r--r--test/Makefile8
-rw-r--r--test/clightgen/Makefile44
-rw-r--r--test/clightgen/empty.c1
-rw-r--r--test/clightgen/issue196.c927
-rw-r--r--test/clightgen/issue216.c5
-rw-r--r--test/regression/Makefile21
-rw-r--r--test/regression/Results/alignas19
-rw-r--r--test/regression/Results/bitfields98
-rw-r--r--test/regression/Results/packedstruct1-3212
-rw-r--r--test/regression/Results/packedstruct1-6412
-rwxr-xr-xtest/regression/Runtest28
-rw-r--r--test/regression/alignas.c57
-rw-r--r--test/regression/bitfields9.c26
-rw-r--r--test/regression/extasm.c5
-rw-r--r--test/regression/funptr2.cond6
-rw-r--r--test/regression/interop1.cond10
-rw-r--r--test/regression/packedstruct1.c42
-rw-r--r--x86/Asm.v13
-rw-r--r--x86/Asmexpand.ml24
-rw-r--r--x86/Asmgenproof.v4
-rw-r--r--x86/TargetPrinter.ml4
126 files changed, 4255 insertions, 2299 deletions
diff --git a/.gitignore b/.gitignore
index c0cd712f..42bf23b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,6 +54,7 @@
/cparser/pre_parser_messages.ml
/cparser/pre_parser.automaton
/cparser/pre_parser.messages
+/cparser/pre_parser.conflicts
/cparser/handcrafted.messages.bak
/cparser/handcrafted.messages.raw
/cparser/deLexer
@@ -75,3 +76,5 @@ runtime/mppa_k1c/i64_smod.s
runtime/mppa_k1c/i64_udiv.s
runtime/mppa_k1c/i64_udivmod.s
runtime/mppa_k1c/i64_umod.s
+# Test generated data
+/test/clightgen/*.v
diff --git a/Changelog b/Changelog
index 552122e0..fda9417e 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,140 @@
+Release 3.4, 2018-09-17
+=======================
+
+Bug fixing:
+- Redefinition of a typedef in a different scope was wrongly rejected.
+- Attach `_Alignas(N)` and `__attribute((aligned(N)))` to names
+ instead of types, so that `_Alignas(16) int * p` means
+ "16-aligned pointer to int", not "pointer to 16-aligned int".
+- For packed structs, fix a discrepancy between the size and alignment
+ computed during elaboration and those computed by the verified front-end
+ after expansion.
+- Honor qualified array types in function parameters: if a parameter is
+ declared as e.g. `int t[const 4]`, it is now treated as `int * const t`
+ in the function body, not `int * t` like before.
+- Reject `__builtin_offsetof(struct s, f)` if `f` is a bit-field.
+- Wrong parsing of attributes having multiple arguments such as
+ `__attribute((packed(A,B,C)))`.
+- If `__builtin_ais_annot` is followed immediately by a label (e.g. a
+ loop head), add a nop instruction to separate the annotation from
+ the label.
+- Wrong parsing of the command-line options `-u <symbol>` and `-iquote`.
+- PowerPC in hybrid 32/64 bit mode: reject %Q and %R register specifications
+ in inline assembly code, since 64-bit integer arguments are not split
+ in two registers.
+- x86 64-bit mode: wrong expansion of __builtin_clzl and builtin_ctzl
+ (issue #127).
+
+New checks for ISO C conformance:
+- Removed support for `_Alignof(expr)`, which is not C11;
+ only `_Alignof(ty)` is part of C11.
+- Reject occurrences of `_Alignas` in places that are not allowed by C11,
+ e.g. in `typedef`. `__attribute((aligned(N)))` can be used instead.
+- Reject occurrences of `restrict` in places that are not allowed by
+ C99 and C11.
+- Reject structs composed of a single flexible array `struct { ty []; }`.
+- Check that qualified array types such as `int t[const 4]` occur only
+ as function parameters, but nowhere else.
+- In function definitions, reject function parameters that have no names.
+
+New warnings:
+- Warn for flexible array types `ty[]` in places where they do not make sense.
+- Warn for inline (not static inline) functions that declare
+ non-constant static variables.
+- Optionally warn if the alignment of an object is reduced below its
+ natural alignment because of a _Alignas qualifier or an aligned attribute,
+ or a packed attribute.
+- Warn for tentative static definitions with an incomplete type, e.g.
+ `static int x[];`.
+- The warning about uses of C11 features is now off by default.
+
+Semantic preservation proof:
+- Model the fact that external functions can destroy caller-save registers
+ and Outgoing stack slots; adapt the proofs accordingly.
+
+Coq and OCaml development:
+- Support Coq versions 8.8.1 and 8.8.2.
+- Support OCaml versions 4.7.0 and up.
+- Support Menhir versions 20180530 and up.
+
+Others:
+- Improved error handling in "configure" script (issue #244)
+- clightgen adds configuration information to the generated .v file (issue #226)
+
+
+
+Release 3.3, 2018-05-30
+=======================
+
+New features:
+- Introduced the __builtin_ais_annot built-in function to communicate
+ source-level annotations to AbsInt's a3 tool suite via a special
+ section in object and executable files.
+- Improved C11 support: define the C11 conditional feature macros;
+ define the max_align_t type in stddef.h.
+- PowerPC 64-bit port: new built-in functions for 64-bit load-store with
+ byte reversal and for 64-bit integer multiply high.
+- x86 64 bits: add support for BSD.
+
+Bug fixing:
+- Wrong code generated for unions containing several bit fields.
+- Internal compiler errors for some initializers for structs and
+ unions containing bit-fields, and for anonymous members of unions.
+- Missing error reporting for <integer> - <ptr> subtraction,
+ causing an internal retyping error later during compilation.
+- String literals are l-values.
+- String literals have array types, not pointer types.
+- Array sizes >= 2^32 were handled incorrectly on 64-bit platforms.
+- Wrong code generated for global variables of size 2^31 bytes or more.
+- struct and union arguments to annotation builtins must be passed by
+ reference, regardless of the ABI calling conventions.
+- "e1, e2" has pointer type if "e2" has array type.
+- x86 64 bits: in "symbol + ofs" addressing modes, the offset "ofs"
+ must be limited to [-2^24, 2^24) otherwise linking can fail.
+
+New or improved diagnostics (errors and warnings):
+- Warn for comparison of a pointer to a complete type and a pointer to
+ an incomplete type.
+- More checks on variables declared in "for" loops: not static, not
+ extern, not function types.
+- Reject empty declarations in K&R functions.
+- Reject arrays of incomplete types.
+- Reject duplicate 'case' or 'default' statements within a 'switch'.
+- Reject 'case' and 'default' statements outside a 'switch'.
+- Check that 'typedef' declares a name and doesn't contain '_Noreturn'.
+- Function parameters are in the same scope as function local variables.
+- More comprehensive constant-ness checks for initializers of global
+ or static local variables.
+- Make sure an enum cannot have the same tag as a struct or an union.
+- More checks on where the 'auto' storage class can be used.
+- Accept empty enum declaration after nonempty enum definition.
+- Reject pointers to incomplete types in ptr - ptr subtraction.
+- When defining a function, take attributes (_Noreturn, etc) from
+ earlier declarations of the function into account.
+- Better check for multiple definitions of functions or global variables.
+- Reject illegal initializations of aggregates such as "char c[4] = 42;".
+- Reject designated initializers where a member of a composite type is
+ re-initialized after the composite has been initialized as a whole.
+- Reject casts to struct/union types.
+- Reject sizeof(e) where e designates a bit-field member of a struct or union.
+- "e1, e2" is not a compile-time constant expression even if e1 and e2 are.
+- "main" function must not be "inline"
+- Warn for functions declared extern after having been defined.
+- Warn for function declarations after function definitions when the
+ declaration has more attributes than the definition.
+- Warn for assignment of a volatile struct to a non-volatile struct.
+- Warn for "main" function if declared _Noreturn.
+
+Coq development:
+- Added support for Coq versions 8.7.2 and 8.8.0.
+- Rewrote "Implicit Arguments" and "Require" inside sections,
+ these are obsolete in 8.8.0.
+- Upgraded Flocq to version 2.6.1.
+- Optionally install the .vo files for reuse by other projects
+ (options -install-coqdev and -coqdevdir to configure script;
+ automatically selected if option -clightgen is given).
+
+
Release 3.2, 2018-01-15
=======================
diff --git a/Makefile b/Makefile
index 03f54744..30cf257c 100644
--- a/Makefile
+++ b/Makefile
@@ -21,9 +21,9 @@ else
ARCHDIRS=$(ARCH)_$(BITSIZE) $(ARCH)
endif
-DIRS=lib common $(ARCHDIRS) backend cfrontend driver debug\
+DIRS=lib common $(ARCHDIRS) backend cfrontend driver \
flocq/Core flocq/Prop flocq/Calc flocq/Appli exportclight \
- cparser cparser/validator
+ cparser cparser/MenhirLib
RECDIRS=lib common $(ARCHDIRS) backend cfrontend driver flocq exportclight cparser
@@ -149,6 +149,9 @@ endif
proof: $(FILES:.v=.vo)
+# Turn off some warnings for compiling Flocq
+flocq/%.vo: COQCOPTS+=-w -compatibility-notation
+
extraction: extraction/STAMP
extraction/STAMP: $(FILES:.v=.vo) extraction/extraction.v $(ARCH)/extractionMachdep.v
@@ -176,18 +179,11 @@ FORCE:
.PHONY: proof extraction runtime FORCE
-documentation: doc/coq2html $(FILES)
+documentation: $(FILES)
mkdir -p doc/html
rm -f doc/html/*.html
- doc/coq2html -o 'doc/html/%.html' doc/*.glob \
+ coq2html -d doc/html/ -base compcert -short-names doc/*.glob \
$(filter-out doc/coq2html cparser/Parser.v, $^)
- cp doc/coq2html.css doc/coq2html.js doc/html/
-
-doc/coq2html: doc/coq2html.ml
- ocamlopt -w +a-29 -o doc/coq2html str.cmxa doc/coq2html.ml
-
-doc/coq2html.ml: doc/coq2html.mll
- ocamllex -q doc/coq2html.mll
tools/ndfun: tools/ndfun.ml
ocamlopt -o tools/ndfun str.cmxa tools/ndfun.ml
@@ -233,7 +229,9 @@ driver/Version.ml: VERSION
>driver/Version.ml
cparser/Parser.v: cparser/Parser.vy
- $(MENHIR) --coq cparser/Parser.vy
+ @rm -f $@
+ $(MENHIR) $(MENHIR_FLAGS) --coq cparser/Parser.vy
+ @chmod a-w $@
depend: $(GENERATED) depend1
@@ -252,12 +250,21 @@ install:
ifeq ($(CLIGHTGEN),true)
install -m 0755 ./clightgen $(BINDIR)
endif
+ifeq ($(INSTALL_COQDEV),true)
+ install -d $(COQDEVDIR)
+ for d in $(DIRS); do \
+ install -d $(COQDEVDIR)/$$d && \
+ install -m 0644 $$d/*.vo $(COQDEVDIR)/$$d/; \
+ done
+ install -m 0644 ./VERSION $(COQDEVDIR)
+ @(echo "To use, pass the following to coq_makefile or add the following to _CoqProject:"; echo "-R $(COQDEVDIR) compcert") > $(COQDEVDIR)/README
+endif
+
clean:
rm -f $(patsubst %, %/*.vo, $(DIRS))
rm -f $(patsubst %, %/.*.aux, $(DIRS))
rm -rf doc/html doc/*.glob
- rm -f doc/coq2html.ml doc/coq2html doc/*.cm? doc/*.o
rm -f driver/Version.ml
rm -f compcert.ini
rm -f extraction/STAMP extraction/*.ml extraction/*.mli .depend.extr
diff --git a/VERSION b/VERSION
index 28a828d8..895933ab 100644
--- a/VERSION
+++ b/VERSION
@@ -1,3 +1,3 @@
-version=3.2
+version=3.4
buildnr=
tag=
diff --git a/arm/Asm.v b/arm/Asm.v
index 184dbc9b..e6d1b4fc 100644
--- a/arm/Asm.v
+++ b/arm/Asm.v
@@ -231,6 +231,7 @@ Inductive instruction : Type :=
| Prev16: ireg -> ireg -> instruction (**r reverse bytes and reverse bits. *)
| Prsc: ireg -> ireg -> shift_op -> instruction (**r reverse subtract without carry. *)
| Psbc: ireg -> ireg -> shift_op -> instruction (**r add with carry *)
+ | Pnop : instruction (**r nop instruction *)
(* Add, sub, rsb versions with s suffix *)
| Padds: ireg -> ireg -> shift_op -> instruction (**r integer addition with update of condition flags *)
| Psubs: ireg -> ireg -> shift_op -> instruction (**r integer subtraction with update of condition flags *)
@@ -805,6 +806,7 @@ Definition exec_instr (f: function) (i: instruction) (rs: regset) (m: mem) : out
| Pfsqrt _ _
| Prsc _ _ _
| Psbc _ _ _
+ | Pnop
| Padds _ _ _
| Psubs _ _ _
| Prsbs _ _ _
@@ -852,6 +854,15 @@ Definition preg_of (r: mreg) : preg :=
| F12 => FR12 | F13 => FR13 | F14 => FR14 | F15 => FR15
end.
+(** Undefine all registers except SP and callee-save registers *)
+
+Definition undef_caller_save_regs (rs: regset) : regset :=
+ fun r =>
+ if preg_eq r SP
+ || In_dec preg_eq r (List.map preg_of (List.filter is_callee_save all_mregs))
+ then rs r
+ else Vundef.
+
(** Extract the values of the arguments of an external call.
We exploit the calling conventions from module [Conventions], except that
we use ARM registers instead of locations. *)
@@ -911,7 +922,7 @@ Inductive step: state -> trace -> state -> Prop :=
Genv.find_funct_ptr ge b = Some (External ef) ->
external_call ef ge args m t res m' ->
extcall_arguments rs m (ef_sig ef) args ->
- rs' = (set_pair (loc_external_result (ef_sig ef) ) res rs)#PC <- (rs IR14) ->
+ rs' = (set_pair (loc_external_result (ef_sig ef) ) res (undef_caller_save_regs rs))#PC <- (rs IR14) ->
step (State rs m) t (State rs' m').
End RELSEM.
diff --git a/arm/AsmToJSON.ml b/arm/AsmToJSON.ml
index 276ceecc..3874e141 100644
--- a/arm/AsmToJSON.ml
+++ b/arm/AsmToJSON.ml
@@ -30,7 +30,7 @@ let mnemonic_names = [ "Padc"; "Padd"; "Padds"; "Pand";"Pannot"; "Pasr"; "Pb"; "
"Pftouizs"; "Pfuitod"; "Pfuitos"; "Pinlineasm"; "Pisb"; "Plabel"; "Pldr";
"Ploadsymbol_lbl"; "Pldr_p"; "Pldrb"; "Pldrb_p"; "Pldrh"; "Pldrh_p"; "Pldrsb";
"Pldrsh"; "Plsl"; "Plsr"; "Pmla"; "Pmov"; "Pmovite";
- "Pmovt"; "Pmovw"; "Pmul"; "Pmvn"; "Ploadsymbol_imm"; "Porr";
+ "Pmovt"; "Pmovw"; "Pmul"; "Pmvn"; "Ploadsymbol_imm"; "Pnop"; "Porr";
"Ppush"; "Prev"; "Prev16"; "Prsb"; "Prsbs"; "Prsc"; "Psbc"; "Psbfx"; "Psdiv"; "Psmull";
"Pstr"; "Pstr_p"; "Pstrb"; "Pstrb_p"; "Pstrh"; "Pstrh_p"; "Psub"; "Psubs"; "Pudiv";
"Pumull" ]
@@ -263,6 +263,7 @@ let pp_instructions pp ic =
| Pmovw(r1, n) -> instruction pp "Pmovw" [Ireg r1; Long n]
| Pmul(r1, r2, r3) -> instruction pp "Pmul" [Ireg r1; Ireg r2; Ireg r3]
| Pmvn(r1, so) -> instruction pp "Pmvn" [Ireg r1; Shift so]
+ | Pnop -> instruction pp "Pnop" []
| Porr(r1, r2, so) -> instruction pp "Porr" [Ireg r1; Ireg r2; Shift so]
| Ppush(rl) -> instruction pp "Ppush" (List.map (fun r -> Ireg r) rl)
| Prev(r1, r2) -> instruction pp "Prev" [Ireg r1; Ireg r2]
diff --git a/arm/Asmexpand.ml b/arm/Asmexpand.ml
index 7c18be6b..d9424d11 100644
--- a/arm/Asmexpand.ml
+++ b/arm/Asmexpand.ml
@@ -404,6 +404,8 @@ let expand_builtin_inline name args res =
(* Vararg stuff *)
| "__builtin_va_start", [BA(IR a)], _ ->
expand_builtin_va_start a
+ | "__builtin_nop", [], _ ->
+ emit Pnop
(* Catch-all *)
| _ ->
raise (Error ("unrecognized builtin " ^ name))
@@ -665,10 +667,7 @@ let expand_function id fn =
try
set_current_function fn;
fixup_arguments Incoming fn.fn_sig;
- if !Clflags.option_g then
- expand_debug id 13 preg_to_dwarf expand_instruction fn.fn_code
- else
- List.iter expand_instruction fn.fn_code;
+ expand id 13 preg_to_dwarf expand_instruction fn.fn_code;
let fn = get_current_function () in
let fn = Constantexpand.expand_constants fn in
Errors.OK fn
diff --git a/arm/Asmgen.v b/arm/Asmgen.v
index 1d2f360f..f12ea870 100644
--- a/arm/Asmgen.v
+++ b/arm/Asmgen.v
@@ -24,6 +24,7 @@ Require Import Asm.
Require Import Compopts.
Local Open Scope string_scope.
+Local Open Scope list_scope.
Local Open Scope error_monad_scope.
(** Extracting integer or float registers. *)
diff --git a/arm/Asmgenproof.v b/arm/Asmgenproof.v
index abec6815..2c001f45 100644
--- a/arm/Asmgenproof.v
+++ b/arm/Asmgenproof.v
@@ -926,8 +926,8 @@ Opaque loadind.
apply plus_one. eapply exec_step_external; eauto.
eapply external_call_symbols_preserved; eauto. apply senv_preserved.
econstructor; eauto.
- apply agree_set_other; auto with asmgen.
- eapply agree_set_pair; eauto.
+ unfold loc_external_result. apply agree_set_other; auto. apply agree_set_pair; auto.
+ apply agree_undef_caller_save_regs; auto.
- (* return *)
inv STACKS. simpl in *.
diff --git a/arm/TargetPrinter.ml b/arm/TargetPrinter.ml
index 52d2ada6..bf37b0e4 100644
--- a/arm/TargetPrinter.ml
+++ b/arm/TargetPrinter.ml
@@ -306,6 +306,8 @@ struct
fprintf oc " vsqrt.f64 %a, %a\n" freg f1 freg f2
| Psbc (r1,r2,sa) ->
fprintf oc " sbc %a, %a, %a\n" ireg r1 ireg r2 shift_op sa
+ | Pnop ->
+ fprintf oc " nop\n"
| Pstr(r1, r2, sa) | Pstr_a(r1, r2, sa) ->
fprintf oc " str %a, [%a, %a]\n" ireg r1 ireg r2 shift_op sa
| Pstrb(r1, r2, sa) ->
@@ -463,7 +465,7 @@ struct
| 1 -> let annot = annot_text preg_annot "sp" (camlstring_of_coqstring txt) args in
fprintf oc "%s annotation: %S\n" comment annot
| 2 -> let lbl = new_label () in
- fprintf oc "%a: " label lbl;
+ fprintf oc "%a:\n" label lbl;
AisAnnot.add_ais_annot lbl preg_annot "r13" (camlstring_of_coqstring txt) args
| _ -> assert false
end
diff --git a/backend/Allocproof.v b/backend/Allocproof.v
index 585fb0da..1804f46b 100644
--- a/backend/Allocproof.v
+++ b/backend/Allocproof.v
@@ -1317,15 +1317,6 @@ Proof.
eauto.
Qed.
-Definition callee_save_loc (l: loc) :=
- match l with
- | R r => is_callee_save r = true
- | S sl ofs ty => sl <> Outgoing
- end.
-
-Definition agree_callee_save (ls1 ls2: locset) : Prop :=
- forall l, callee_save_loc l -> ls1 l = ls2 l.
-
Lemma return_regs_agree_callee_save:
forall caller callee,
agree_callee_save caller (return_regs caller callee).
@@ -2476,10 +2467,10 @@ Proof.
rewrite Locmap.gss. rewrite Locmap.gso by (red; auto). rewrite Locmap.gss.
rewrite val_longofwords_eq_1 by auto. auto.
red; intros. rewrite (AG l H0).
- symmetry; apply Locmap.gpo.
- assert (X: forall r, is_callee_save r = false -> Loc.diff l (R r)).
- { intros. destruct l; simpl in *. congruence. auto. }
- generalize (loc_result_caller_save (ef_sig ef)). destruct (loc_result (ef_sig ef)); simpl; intuition auto.
+ rewrite locmap_get_set_loc_result_callee_save by auto.
+ unfold undef_caller_save_regs. destruct l; simpl in H0.
+ rewrite H0; auto.
+ destruct sl; auto; congruence.
eapply external_call_well_typed; eauto.
(* return *)
diff --git a/backend/Asmexpandaux.ml b/backend/Asmexpandaux.ml
index 62c4a702..0f666a65 100644
--- a/backend/Asmexpandaux.ml
+++ b/backend/Asmexpandaux.ml
@@ -97,6 +97,16 @@ let translate_annot sp preg_to_dwarf annot =
| [] -> None
| a::_ -> aux a)
+let builtin_nop =
+ let signature ={sig_args = []; sig_res = None; sig_cc = cc_default} in
+ let name = coqstring_of_camlstring "__builtin_nop" in
+ Pbuiltin(EF_builtin(name,signature),[],BR_none)
+
+let rec lbl_follows = function
+ | Pbuiltin (EF_debug _, _, _):: rest ->
+ lbl_follows rest
+ | Plabel _ :: _ -> true
+ | _ -> false
let expand_debug id sp preg simple l =
let get_lbl = function
@@ -144,6 +154,11 @@ let expand_debug id sp preg simple l =
| _ ->
aux None scopes rest
end
+ | (Pbuiltin(EF_annot (kind, _, _),_,_) as annot)::rest ->
+ simple annot;
+ if P.to_int kind = 2 && lbl_follows rest then
+ simple builtin_nop;
+ aux None scopes rest
| (Plabel lbl)::rest -> simple (Plabel lbl); aux (Some lbl) scopes rest
| i::rest -> simple i; aux None scopes rest in
(* We need to move all closing debug annotations before the last real statement *)
@@ -157,3 +172,20 @@ let expand_debug id sp preg simple l =
| b::rest -> List.rev ((List.rev (b::bcc)@List.rev acc)@rest) (* We found the first non debug location *)
| [] -> List.rev acc (* This actually can never happen *) in
aux None [] (move_debug [] [] (List.rev l))
+
+let expand_simple simple l =
+ let rec aux = function
+ | (Pbuiltin(EF_annot (kind, _, _),_,_) as annot)::rest ->
+ simple annot;
+ if P.to_int kind = 2 && lbl_follows rest then
+ simple builtin_nop;
+ aux rest
+ | i::rest -> simple i; aux rest
+ | [] -> () in
+ aux l
+
+let expand id sp preg simple l =
+ if !Clflags.option_g then
+ expand_debug id sp preg simple l
+ else
+ expand_simple simple l
diff --git a/backend/Asmexpandaux.mli b/backend/Asmexpandaux.mli
index 797eb10c..d80b4aec 100644
--- a/backend/Asmexpandaux.mli
+++ b/backend/Asmexpandaux.mli
@@ -31,6 +31,6 @@ val set_current_function: coq_function -> unit
(* Set the current function *)
val get_current_function: unit -> coq_function
(* Get the current function *)
-val expand_debug: positive -> int -> (preg -> int) -> (instruction -> unit) -> instruction list -> unit
- (* Expand builtin debug function. Takes the function id, the register number of the stackpointer, a
- function to get the dwarf mapping of varibale names and for the expansion of simple instructions *)
+val expand: positive -> int -> (preg -> int) -> (instruction -> unit) -> instruction list -> unit
+ (* Expand the instruction sequence of a function. Takes the function id, the register number of the stackpointer, a
+ function to get the dwarf mapping of varibale names and for the expansion of simple instructions *)
diff --git a/backend/Asmgenproof0.v b/backend/Asmgenproof0.v
index 8dfa8828..3e25c79b 100644
--- a/backend/Asmgenproof0.v
+++ b/backend/Asmgenproof0.v
@@ -318,6 +318,23 @@ Proof.
intros. rewrite Pregmap.gso; auto.
Qed.
+Lemma agree_undef_caller_save_regs:
+ forall ms sp rs,
+ agree ms sp rs ->
+ agree (Mach.undef_caller_save_regs ms) sp (Asm.undef_caller_save_regs rs).
+Proof.
+ intros. destruct H. unfold Mach.undef_caller_save_regs, Asm.undef_caller_save_regs; split.
+- unfold proj_sumbool; rewrite dec_eq_true. auto.
+- auto.
+- intros. unfold proj_sumbool. rewrite dec_eq_false by (apply preg_of_not_SP).
+ destruct (in_dec preg_eq (preg_of r) (List.map preg_of (List.filter is_callee_save all_mregs))); simpl.
++ apply list_in_map_inv in i. destruct i as (mr & A & B).
+ assert (r = mr) by (apply preg_of_injective; auto). subst mr; clear A.
+ apply List.filter_In in B. destruct B as [C D]. rewrite D. auto.
++ destruct (is_callee_save r) eqn:CS; auto.
+ elim n. apply List.in_map. apply List.filter_In. auto using all_mregs_complete.
+Qed.
+
Lemma agree_change_sp:
forall ms sp rs sp',
agree ms sp rs -> sp' <> Vundef ->
diff --git a/backend/Conventions.v b/backend/Conventions.v
index bdc4c8b6..989bfa05 100644
--- a/backend/Conventions.v
+++ b/backend/Conventions.v
@@ -103,3 +103,56 @@ Proof.
generalize (loc_arguments_bounded _ _ _ H0).
generalize (typesize_pos ty). omega.
Qed.
+
+
+(** * Callee-save locations *)
+
+(** We classify locations as either
+- callee-save, i.e. preserved across function calls:
+ callee-save registers, [Local] and [Incoming] stack slots;
+- caller-save, i.e. possibly modified by a function call:
+ non-callee-save registers, [Outgoing] stack slots.
+
+Concerning [Outgoing] stack slots: several ABIs allow a function to modify
+the stack slots used for passing parameters to this function.
+The code currently generated by CompCert never does so, but the code
+generated by other compilers often does so (e.g. GCC for x86-32).
+Hence, CompCert-generated code must not assume that [Outgoing] stack slots
+are preserved across function calls, because they might not be preserved
+if the called function was compiled by another compiler.
+*)
+
+Definition callee_save_loc (l: loc) :=
+ match l with
+ | R r => is_callee_save r = true
+ | S sl ofs ty => sl <> Outgoing
+ end.
+
+Hint Unfold callee_save_loc.
+
+Definition agree_callee_save (ls1 ls2: Locmap.t) : Prop :=
+ forall l, callee_save_loc l -> ls1 l = ls2 l.
+
+(** * Assigning result locations *)
+
+(** Useful lemmas to reason about the result of an external call. *)
+
+Lemma locmap_get_set_loc_result:
+ forall sg v rs l,
+ match l with R r => is_callee_save r = true | S _ _ _ => True end ->
+ Locmap.setpair (loc_result sg) v rs l = rs l.
+Proof.
+ intros. apply Locmap.gpo.
+ assert (X: forall r, is_callee_save r = false -> Loc.diff l (R r)).
+ { intros. destruct l; simpl. congruence. auto. }
+ generalize (loc_result_caller_save sg). destruct (loc_result sg); simpl; intuition auto.
+Qed.
+
+Lemma locmap_get_set_loc_result_callee_save:
+ forall sg v rs l,
+ callee_save_loc l ->
+ Locmap.setpair (loc_result sg) v rs l = rs l.
+Proof.
+ intros. apply locmap_get_set_loc_result.
+ red in H; destruct l; auto.
+Qed.
diff --git a/backend/LTL.v b/backend/LTL.v
index 8567a891..5e7eec8c 100644
--- a/backend/LTL.v
+++ b/backend/LTL.v
@@ -96,16 +96,31 @@ Definition call_regs (caller: locset) : locset :=
- Callee-save machine registers have the same values as in the caller
before the call.
- Caller-save machine registers have the same values as in the callee.
-- Stack slots have the same values as in the caller.
+- Local and Incoming stack slots have the same values as in the caller.
+- Outgoing stack slots are set to Vundef to reflect the fact that they
+ may have been changed by the callee.
*)
Definition return_regs (caller callee: locset) : locset :=
fun (l: loc) =>
match l with
| R r => if is_callee_save r then caller (R r) else callee (R r)
+ | S Outgoing ofs ty => Vundef
| S sl ofs ty => caller (S sl ofs ty)
end.
+(** [undef_caller_save_regs ls] models the effect of calling
+ an external function: caller-save registers and outgoing locations
+ can change unpredictably, hence we set them to [Vundef]. *)
+
+Definition undef_caller_save_regs (ls: locset) : locset :=
+ fun (l: loc) =>
+ match l with
+ | R r => if is_callee_save r then ls (R r) else Vundef
+ | S Outgoing ofs ty => Vundef
+ | S sl ofs ty => ls (S sl ofs ty)
+ end.
+
(** LTL execution states. *)
Inductive stackframe : Type :=
@@ -259,7 +274,7 @@ Inductive step: state -> trace -> state -> Prop :=
| exec_function_external: forall s ef t args res rs m rs' m',
args = map (fun p => Locmap.getpair p rs) (loc_arguments (ef_sig ef)) ->
external_call ef ge args m t res m' ->
- rs' = Locmap.setpair (loc_result (ef_sig ef)) res rs ->
+ rs' = Locmap.setpair (loc_result (ef_sig ef)) res (undef_caller_save_regs rs) ->
step (Callstate s (External ef) rs m)
t (Returnstate s rs' m')
| exec_return: forall f sp rs1 bb s rs m,
diff --git a/backend/Linear.v b/backend/Linear.v
index 55f92d16..447c6ba6 100644
--- a/backend/Linear.v
+++ b/backend/Linear.v
@@ -239,7 +239,7 @@ Inductive step: state -> trace -> state -> Prop :=
forall s ef args res rs1 rs2 m t m',
args = map (fun p => Locmap.getpair p rs1) (loc_arguments (ef_sig ef)) ->
external_call ef ge args m t res m' ->
- rs2 = Locmap.setpair (loc_result (ef_sig ef)) res rs1 ->
+ rs2 = Locmap.setpair (loc_result (ef_sig ef)) res (undef_caller_save_regs rs1) ->
step (Callstate s (External ef) rs1 m)
t (Returnstate s rs2 m')
| exec_return:
diff --git a/backend/Lineartyping.v b/backend/Lineartyping.v
index d5fadd4c..55d86448 100644
--- a/backend/Lineartyping.v
+++ b/backend/Lineartyping.v
@@ -146,7 +146,18 @@ Lemma wt_return_regs:
wt_locset caller -> wt_locset callee -> wt_locset (return_regs caller callee).
Proof.
intros; red; intros.
- unfold return_regs. destruct l; auto. destruct (is_callee_save r); auto.
+ unfold return_regs. destruct l.
+- destruct (is_callee_save r); auto.
+- destruct sl; auto; red; auto.
+Qed.
+
+Lemma wt_undef_caller_save_regs:
+ forall ls, wt_locset ls -> wt_locset (undef_caller_save_regs ls).
+Proof.
+ intros; red; intros. unfold undef_caller_save_regs.
+ destruct l.
+ destruct (is_callee_save r); auto; simpl; auto.
+ destruct sl; auto; red; auto.
Qed.
Lemma wt_init:
@@ -197,6 +208,24 @@ Proof.
auto.
Qed.
+(** In addition to type preservation during evaluation, we also show
+ properties of the environment [ls] at call points and at return points.
+ These properties are used in the proof of the [Stacking] pass.
+ For call points, we have that the current environment [ls] and the
+ one from the top call stack agree on the [Outgoing] locations
+ used for parameter passing. *)
+
+Definition agree_outgoing_arguments (sg: signature) (ls pls: locset) : Prop :=
+ forall ty ofs,
+ In (S Outgoing ofs ty) (regs_of_rpairs (loc_arguments sg)) ->
+ ls (S Outgoing ofs ty) = pls (S Outgoing ofs ty).
+
+(** For return points, we have that all [Outgoing] stack locations have
+ been set to [Vundef]. *)
+
+Definition outgoing_undef (ls: locset) : Prop :=
+ forall ty ofs, ls (S Outgoing ofs ty) = Vundef.
+
(** Soundness of the type system *)
Definition wt_fundef (fd: fundef) :=
@@ -233,11 +262,15 @@ Inductive wt_state: state -> Prop :=
| wt_call_state: forall s fd rs m
(WTSTK: wt_callstack s)
(WTFD: wt_fundef fd)
- (WTRS: wt_locset rs),
+ (WTRS: wt_locset rs)
+ (AGCS: agree_callee_save rs (parent_locset s))
+ (AGARGS: agree_outgoing_arguments (funsig fd) rs (parent_locset s)),
wt_state (Callstate s fd rs m)
| wt_return_state: forall s rs m
(WTSTK: wt_callstack s)
- (WTRS: wt_locset rs),
+ (WTRS: wt_locset rs)
+ (AGCS: agree_callee_save rs (parent_locset s))
+ (UOUT: outgoing_undef rs),
wt_state (Returnstate s rs m).
(** Preservation of state typing by transitions *)
@@ -307,11 +340,15 @@ Local Opaque mreg_type.
simpl in *; InvBooleans.
econstructor; eauto. econstructor; eauto.
eapply wt_find_function; eauto.
+ red; simpl; auto.
+ red; simpl; auto.
- (* tailcall *)
simpl in *; InvBooleans.
econstructor; eauto.
eapply wt_find_function; eauto.
apply wt_return_regs; auto. apply wt_parent_locset; auto.
+ red; simpl; intros. destruct l; simpl in *. rewrite H3; auto. destruct sl; auto; congruence.
+ red; simpl; intros. apply zero_size_arguments_tailcall_possible in H. apply H in H3. contradiction.
- (* builtin *)
simpl in *; InvBooleans.
econstructor; eauto.
@@ -334,13 +371,20 @@ Local Opaque mreg_type.
simpl in *. InvBooleans.
econstructor; eauto.
apply wt_return_regs; auto. apply wt_parent_locset; auto.
+ red; simpl; intros. destruct l; simpl in *. rewrite H0; auto. destruct sl; auto; congruence.
+ red; simpl; intros. auto.
- (* internal function *)
simpl in WTFD.
econstructor. eauto. eauto. eauto.
apply wt_undef_regs. apply wt_call_regs. auto.
- (* external function *)
- econstructor. auto. apply wt_setpair; auto.
+ econstructor. auto. apply wt_setpair.
eapply external_call_well_typed; eauto.
+ apply wt_undef_caller_save_regs; auto.
+ red; simpl; intros. destruct l; simpl in *.
+ rewrite locmap_get_set_loc_result by auto. simpl. rewrite H; auto.
+ rewrite locmap_get_set_loc_result by auto. simpl. destruct sl; auto; congruence.
+ red; simpl; intros. rewrite locmap_get_set_loc_result by auto. auto.
- (* return *)
inv WTSTK. econstructor; eauto.
Qed.
@@ -352,6 +396,8 @@ Proof.
unfold ge0 in H1. exploit Genv.find_funct_ptr_inversion; eauto.
intros [id IN]. eapply wt_prog; eauto.
apply wt_init.
+ red; auto.
+ red; auto.
Qed.
End SOUNDNESS.
@@ -397,3 +443,19 @@ Lemma wt_callstate_wt_regs:
Proof.
intros. inv H. apply WTRS.
Qed.
+
+Lemma wt_callstate_agree:
+ forall s f rs m,
+ wt_state (Callstate s f rs m) ->
+ agree_callee_save rs (parent_locset s) /\ agree_outgoing_arguments (funsig f) rs (parent_locset s).
+Proof.
+ intros. inv H; auto.
+Qed.
+
+Lemma wt_returnstate_agree:
+ forall s rs m,
+ wt_state (Returnstate s rs m) ->
+ agree_callee_save rs (parent_locset s) /\ outgoing_undef rs.
+Proof.
+ intros. inv H; auto.
+Qed.
diff --git a/backend/Mach.v b/backend/Mach.v
index 839a25bd..9fdee9eb 100644
--- a/backend/Mach.v
+++ b/backend/Mach.v
@@ -156,6 +156,9 @@ Proof.
unfold Regmap.set. destruct (RegEq.eq r a); auto.
Qed.
+Definition undef_caller_save_regs (rs: regset) : regset :=
+ fun r => if is_callee_save r then rs r else Vundef.
+
Definition set_pair (p: rpair mreg) (v: val) (rs: regset) : regset :=
match p with
| One r => rs#r <- v
@@ -407,7 +410,7 @@ Inductive step: state -> trace -> state -> Prop :=
Genv.find_funct_ptr ge fb = Some (External ef) ->
extcall_arguments rs m (parent_sp s) (ef_sig ef) args ->
external_call ef ge args m t res m' ->
- rs' = set_pair (loc_result (ef_sig ef)) res rs ->
+ rs' = set_pair (loc_result (ef_sig ef)) res (undef_caller_save_regs rs) ->
step (Callstate s fb rs m)
t (Returnstate s rs' m')
| exec_return:
diff --git a/backend/Regalloc.ml b/backend/Regalloc.ml
index d4d7362d..19aba4f6 100644
--- a/backend/Regalloc.ml
+++ b/backend/Regalloc.ml
@@ -644,7 +644,7 @@ let add_interfs_instr g instr live =
(* Reloads from incoming slots can occur when some 64-bit
parameters are split and passed as two 32-bit stack locations. *)
begin match src with
- | L(Locations.S(Incoming, _, _)) ->
+ | L(Locations.S(Incoming, _, _)) ->
add_interfs_def g (vmreg temp_for_parent_frame) live
| _ -> ()
end
@@ -1210,9 +1210,9 @@ let regalloc f =
Errors.OK(first_round f3 liveness)
with
| Timeout ->
- Errors.Error(Errors.msg (coqstring_of_camlstring "Spilling fails to converge"))
+ Errors.Error(Errors.msg (coqstring_of_camlstring "spilling fails to converge"))
| Type_error_at pc ->
- Errors.Error [Errors.MSG(coqstring_of_camlstring "Ill-typed XTL code at PC ");
+ Errors.Error [Errors.MSG(coqstring_of_camlstring "ill-typed XTL code at PC ");
Errors.POS pc]
| Bad_LTL ->
- Errors.Error(Errors.msg (coqstring_of_camlstring "Bad LTL after spilling"))
+ Errors.Error(Errors.msg (coqstring_of_camlstring "bad LTL after spilling"))
diff --git a/backend/Stackingproof.v b/backend/Stackingproof.v
index 6d46d04d..c9b07427 100644
--- a/backend/Stackingproof.v
+++ b/backend/Stackingproof.v
@@ -294,12 +294,13 @@ Qed.
Lemma contains_locations_exten:
forall ls ls' j sp pos bound sl,
- (forall ofs ty, ls' (S sl ofs ty) = ls (S sl ofs ty)) ->
+ (forall ofs ty, Val.lessdef (ls' (S sl ofs ty)) (ls (S sl ofs ty))) ->
massert_imp (contains_locations j sp pos bound sl ls)
(contains_locations j sp pos bound sl ls').
Proof.
intros; split; simpl; intros; auto.
- intuition auto. rewrite H. eauto.
+ intuition auto. exploit H5; eauto. intros (v & A & B). exists v; split; auto.
+ specialize (H ofs ty). inv H. congruence. auto.
Qed.
Lemma contains_locations_incr:
@@ -481,7 +482,8 @@ Qed.
Lemma frame_contents_exten:
forall ls ls0 ls' ls0' j sp parent retaddr P m,
- (forall sl ofs ty, ls' (S sl ofs ty) = ls (S sl ofs ty)) ->
+ (forall ofs ty, Val.lessdef (ls' (S Local ofs ty)) (ls (S Local ofs ty))) ->
+ (forall ofs ty, Val.lessdef (ls' (S Outgoing ofs ty)) (ls (S Outgoing ofs ty))) ->
(forall r, In r b.(used_callee_save) -> ls0' (R r) = ls0 (R r)) ->
m |= frame_contents j sp ls ls0 parent retaddr ** P ->
m |= frame_contents j sp ls' ls0' parent retaddr ** P.
@@ -573,16 +575,6 @@ Record agree_locs (ls ls0: locset) : Prop :=
ls (S Incoming ofs ty) = ls0 (S Outgoing ofs ty)
}.
-(** Auxiliary predicate used at call points *)
-
-Definition agree_callee_save (ls ls0: locset) : Prop :=
- forall l,
- match l with
- | R r => is_callee_save r = true
- | S _ _ _ => True
- end ->
- ls l = ls0 l.
-
(** ** Properties of [agree_regs]. *)
(** Values of registers *)
@@ -666,6 +658,16 @@ Proof.
apply agree_regs_set_reg; auto.
Qed.
+Lemma agree_regs_undef_caller_save_regs:
+ forall j ls rs,
+ agree_regs j ls rs ->
+ agree_regs j (LTL.undef_caller_save_regs ls) (Mach.undef_caller_save_regs rs).
+Proof.
+ intros; red; intros.
+ unfold LTL.undef_caller_save_regs, Mach.undef_caller_save_regs.
+ destruct (is_callee_save r); auto.
+Qed.
+
(** Preservation under assignment of stack slot *)
Lemma agree_regs_set_slot:
@@ -800,41 +802,7 @@ Lemma agree_locs_return:
Proof.
intros. red in H0. inv H; constructor; auto; intros.
- rewrite H0; auto. unfold mreg_within_bounds in H. tauto.
-- rewrite H0; auto.
-Qed.
-
-(** Preservation at tailcalls (when [ls0] is changed but not [ls]). *)
-
-Lemma agree_locs_tailcall:
- forall ls ls0 ls0',
- agree_locs ls ls0 ->
- agree_callee_save ls0 ls0' ->
- agree_locs ls ls0'.
-Proof.
- intros. red in H0. inv H; constructor; auto; intros.
-- rewrite <- H0; auto. unfold mreg_within_bounds in H. tauto.
-- rewrite <- H0; auto.
-Qed.
-
-(** ** Properties of [agree_callee_save]. *)
-
-Lemma agree_callee_save_return_regs:
- forall ls1 ls2,
- agree_callee_save (return_regs ls1 ls2) ls1.
-Proof.
- intros; red; intros.
- unfold return_regs. destruct l; auto. rewrite H; auto.
-Qed.
-
-Lemma agree_callee_save_set_result:
- forall sg v ls1 ls2,
- agree_callee_save ls1 ls2 ->
- agree_callee_save (Locmap.setpair (loc_result sg) v ls1) ls2.
-Proof.
- intros; red; intros. rewrite Locmap.gpo. apply H; auto.
- assert (X: forall r, is_callee_save r = false -> Loc.diff l (R r)).
- { intros. destruct l; auto. simpl; congruence. }
- generalize (loc_result_caller_save sg). destruct (loc_result sg); simpl; intuition auto.
+- rewrite <- agree_incoming0 by auto. apply H0. congruence.
Qed.
(** ** Properties of destroyed registers. *)
@@ -1071,6 +1039,7 @@ Lemma function_prologue_correct:
forall j ls ls0 ls1 rs rs1 m1 m1' m2 sp parent ra cs fb k P,
agree_regs j ls rs ->
agree_callee_save ls ls0 ->
+ agree_outgoing_arguments (Linear.fn_sig f) ls ls0 ->
(forall r, Val.has_type (ls (R r)) (mreg_type r)) ->
ls1 = LTL.undef_regs destroyed_at_function_entry (LTL.call_regs ls) ->
rs1 = undef_regs destroyed_at_function_entry rs ->
@@ -1090,7 +1059,7 @@ Lemma function_prologue_correct:
/\ j' sp = Some(sp', fe.(fe_stack_data))
/\ inject_incr j j'.
Proof.
- intros until P; intros AGREGS AGCS WTREGS LS1 RS1 ALLOC TYPAR TYRA SEP.
+ intros until P; intros AGREGS AGCS AGARGS WTREGS LS1 RS1 ALLOC TYPAR TYRA SEP.
rewrite unfold_transf_function.
unfold fn_stacksize, fn_link_ofs, fn_retaddr_ofs.
(* Stack layout info *)
@@ -1174,7 +1143,7 @@ Local Opaque b fe.
split. rewrite LS1. apply agree_locs_undef_locs; [|reflexivity].
constructor; intros. unfold call_regs. apply AGCS.
unfold mreg_within_bounds in H; tauto.
- unfold call_regs. apply AGCS. auto.
+ unfold call_regs. apply AGARGS. apply incoming_slot_in_parameters; auto.
split. exact SEPFINAL.
split. exact SAME. exact INCR.
Qed.
@@ -1325,7 +1294,7 @@ Proof.
apply CS; auto.
rewrite NCS by auto. apply AGR.
split. red; unfold return_regs; intros.
- destruct l; auto. rewrite H; auto.
+ destruct l. rewrite H; auto. destruct sl; auto; contradiction.
assumption.
Qed.
@@ -1619,6 +1588,7 @@ Variable ls: locset.
Variable rs: regset.
Hypothesis AGR: agree_regs j ls rs.
Hypothesis AGCS: agree_callee_save ls (parent_locset cs).
+Hypothesis AGARGS: agree_outgoing_arguments sg ls (parent_locset cs).
Variable m': mem.
Hypothesis SEP: m' |= stack_contents j cs cs'.
@@ -1641,7 +1611,7 @@ Proof.
assert (slot_within_bounds (function_bounds f) Outgoing pos ty) by eauto.
exploit frame_get_outgoing; eauto. intros (v & A & B).
exists v; split.
- constructor. exact A. red in AGCS. rewrite AGCS; auto.
+ constructor. exact A. rewrite AGARGS by auto. exact B.
Qed.
Lemma transl_external_argument_2:
@@ -1816,7 +1786,6 @@ Inductive match_states: Linear.state -> Mach.state -> Prop :=
(TRANSL: transf_fundef f = OK tf)
(FIND: Genv.find_funct_ptr tge fb = Some tf)
(AGREGS: agree_regs j ls rs)
- (AGLOCS: agree_callee_save ls (parent_locset cs))
(SEP: m' |= stack_contents j cs cs'
** minjection j m
** globalenv_inject ge j),
@@ -1826,7 +1795,6 @@ Inductive match_states: Linear.state -> Mach.state -> Prop :=
forall cs ls m cs' rs m' j sg
(STACKS: match_stacks j cs cs' sg)
(AGREGS: agree_regs j ls rs)
- (AGLOCS: agree_callee_save ls (parent_locset cs))
(SEP: m' |= stack_contents j cs cs'
** minjection j m
** globalenv_inject ge j),
@@ -1989,9 +1957,8 @@ Proof.
econstructor; eauto with coqlib.
apply Val.Vptr_has_type.
intros; red.
- apply Z.le_trans with (size_arguments (Linear.funsig f')); auto.
+ apply Z.le_trans with (size_arguments (Linear.funsig f')); auto.
apply loc_arguments_bounded; auto.
- simpl; red; auto.
simpl. rewrite sep_assoc. exact SEP.
- (* Ltailcall *)
@@ -2091,6 +2058,7 @@ Proof.
destruct (transf_function f) as [tfn|] eqn:TRANSL; simpl; try congruence.
intros EQ; inversion EQ; clear EQ; subst tf.
rewrite sep_comm, sep_assoc in SEP.
+ exploit wt_callstate_agree; eauto. intros [AGCS AGARGS].
exploit function_prologue_correct; eauto.
red; intros; eapply wt_callstate_wt_regs; eauto.
eapply match_stacks_type_sp; eauto.
@@ -2109,6 +2077,7 @@ Proof.
- (* external function *)
simpl in TRANSL. inversion TRANSL; subst tf.
+ exploit wt_callstate_agree; eauto. intros [AGCS AGARGS].
exploit transl_external_arguments; eauto. apply sep_proj1 in SEP; eauto. intros [vl [ARGS VINJ]].
rewrite sep_comm, sep_assoc in SEP.
exploit external_call_parallel_rule; eauto.
@@ -2118,18 +2087,22 @@ Proof.
eapply external_call_symbols_preserved; eauto. apply senv_preserved.
eapply match_states_return with (j := j').
eapply match_stacks_change_meminj; eauto.
- apply agree_regs_set_pair. apply agree_regs_inject_incr with j; auto. auto.
- apply agree_callee_save_set_result; auto.
+ apply agree_regs_set_pair. apply agree_regs_undef_caller_save_regs.
+ apply agree_regs_inject_incr with j; auto.
+ auto.
apply stack_contents_change_meminj with j; auto.
rewrite sep_comm, sep_assoc; auto.
- (* return *)
- inv STACKS. simpl in AGLOCS. simpl in SEP. rewrite sep_assoc in SEP.
+ inv STACKS. exploit wt_returnstate_agree; eauto. intros [AGCS OUTU].
+ simpl in AGCS. simpl in SEP. rewrite sep_assoc in SEP.
econstructor; split.
apply plus_one. apply exec_return.
econstructor; eauto.
apply agree_locs_return with rs0; auto.
apply frame_contents_exten with rs0 (parent_locset s); auto.
+ intros; apply Val.lessdef_same; apply AGCS; red; congruence.
+ intros; rewrite (OUTU ty ofs); auto.
Qed.
Lemma transf_initial_states:
@@ -2147,7 +2120,6 @@ Proof.
eapply match_states_call with (j := j); eauto.
constructor. red; intros. rewrite H3, loc_arguments_main in H. contradiction.
red; simpl; auto.
- red; simpl; auto.
simpl. rewrite sep_pure. split; auto. split;[|split].
eapply Genv.initmem_inject; eauto.
simpl. exists (Mem.nextblock m0); split. apply Ple_refl.
diff --git a/backend/Tunnelingproof.v b/backend/Tunnelingproof.v
index c6644ceb..4f95ac9b 100644
--- a/backend/Tunnelingproof.v
+++ b/backend/Tunnelingproof.v
@@ -334,6 +334,16 @@ Proof.
induction res; intros; simpl; auto using locmap_set_lessdef, Val.loword_lessdef, Val.hiword_lessdef.
Qed.
+Lemma locmap_undef_caller_save_regs_lessdef:
+ forall ls1 ls2,
+ locmap_lessdef ls1 ls2 -> locmap_lessdef (undef_caller_save_regs ls1) (undef_caller_save_regs ls2).
+Proof.
+ intros; red; intros. unfold undef_caller_save_regs.
+ destruct l.
+- destruct (Conventions1.is_callee_save r); auto.
+- destruct sl; auto.
+Qed.
+
Lemma find_function_translated:
forall ros ls tls fd,
locmap_lessdef ls tls ->
@@ -363,7 +373,7 @@ Lemma return_regs_lessdef:
Proof.
intros; red; intros. destruct l; simpl.
- destruct (Conventions1.is_callee_save r); auto.
-- auto.
+- destruct sl; auto.
Qed.
(** To preserve non-terminating behaviours, we show that the transformed
@@ -516,7 +526,7 @@ Proof.
left; simpl; econstructor; split.
eapply exec_function_external; eauto.
eapply external_call_symbols_preserved; eauto. apply senv_preserved.
- simpl. econstructor; eauto using locmap_setpair_lessdef.
+ simpl. econstructor; eauto using locmap_setpair_lessdef, locmap_undef_caller_save_regs_lessdef.
- (* return *)
inv STK. inv H1.
left; econstructor; split.
diff --git a/cfrontend/C2C.ml b/cfrontend/C2C.ml
index c4772688..d6bf76f3 100644
--- a/cfrontend/C2C.ml
+++ b/cfrontend/C2C.ml
@@ -16,7 +16,7 @@
open C
open Camlcoq
-open Floats
+open! Floats
open Values
open Ctypes
open Csyntax
@@ -307,18 +307,18 @@ let builtins =
(** ** The known attributes *)
let attributes = [
- (* type-related *)
- ("aligned", Cutil.Attr_type);
+ (* type-related -- currently none *)
(* struct-related *)
("packed", Cutil.Attr_struct);
(* function-related *)
("noreturn", Cutil.Attr_function);
("noinline",Cutil.Attr_function);
(* name-related *)
+ ("aligned", Cutil.Attr_name);
("section", Cutil.Attr_name);
("unused", Cutil.Attr_name)
]
-
+
(** ** Functions used to handle string literals *)
@@ -546,14 +546,14 @@ let convertFkind k a : coq_type =
let checkFunctionType env tres targs =
if not !Clflags.option_fstruct_passing then begin
if Cutil.is_composite_type env tres then
- unsupported "function returning a struct or union (consider adding option -fstruct-passing)";
+ unsupported "function returning a struct or union (consider adding option [-fstruct-passing])";
begin match targs with
| None -> ()
| Some l ->
List.iter
(fun (id, ty) ->
if Cutil.is_composite_type env ty then
- unsupported "function parameter of struct or union type (consider adding option -fstruct-passing)")
+ unsupported "function parameter of struct or union type (consider adding option [-fstruct-passing])")
l
end
end
@@ -606,13 +606,15 @@ let rec convertTypArgs env tl el =
let convertField env f =
if f.fld_bitfield <> None then
- unsupported "bit field in struct or union (consider adding option -fbitfields)";
+ unsupported "bit field in struct or union (consider adding option [-fbitfields])";
(intern_string f.fld_name, convertTyp env f.fld_typ)
let convertCompositedef env su id attr members =
+ if Cutil.find_custom_attributes ["packed";"__packed__"] attr <> [] then
+ unsupported "packed struct (consider adding option [-fpacked-structs])";
let t = match su with
| C.Struct ->
- let layout = Cutil.struct_layout env members in
+ let layout = Cutil.struct_layout env attr members in
List.iter (fun (a,b) -> Debug.set_member_offset id a b) layout;
TStruct (id,attr)
| C.Union -> TUnion (id,attr) in
@@ -717,6 +719,7 @@ let ewrap = function
let rec convertExpr env e =
match e.edesc with
+ | C.EConst (C.CStr _ | C.CWStr _)
| C.EVar _
| C.EUnop((C.Oderef|C.Odot _|C.Oarrow _), _)
| C.EBinop(C.Oindex, _, _, _) ->
@@ -732,12 +735,6 @@ let rec convertExpr env e =
if k = C.FLongDouble && not !Clflags.option_flongdouble then
unsupported "'long double' floating-point constant";
convertFloat f k
- | C.EConst(C.CStr s) ->
- let ty = typeStringLiteral s in
- Evalof(Evar(name_for_string_literal s, ty), ty)
- | C.EConst(C.CWStr s) ->
- let ty = typeWideStringLiteral s in
- Evalof(Evar(name_for_wide_string_literal s, ty), ty)
| C.EConst(C.CEnum(id, i)) ->
Ctyping.econst_int (convertInt32 i) Signed
| C.ESizeof ty1 ->
@@ -793,6 +790,9 @@ let rec convertExpr env e =
if Cutil.is_composite_type env e1.etyp
&& List.mem AVolatile (Cutil.attributes_of_type env e1.etyp) then
warning Diagnostics.Unnamed "assignment to an lvalue of volatile composite type, the 'volatile' qualifier is ignored";
+ if Cutil.is_composite_type env e2.etyp
+ && List.mem AVolatile (Cutil.attributes_of_type env e2.etyp) then
+ warning Diagnostics.Unnamed "assignment of a value of volatile composite type, the 'volatile' qualifier is ignored";
ewrap (Ctyping.eassign e1' e2')
| C.EBinop((C.Oadd_assign|C.Osub_assign|C.Omul_assign|C.Odiv_assign|
C.Omod_assign|C.Oand_assign|C.Oor_assign|C.Oxor_assign|
@@ -829,10 +829,10 @@ let rec convertExpr env e =
| C.ECompound(ty1, ie) ->
unsupported "compound literals"; ezero
+ | C.ECall({edesc = C.EVar {name = "__builtin_debug"}}, args) when List.length args < 2 ->
+ error "too few arguments to function call, expected at least 2, have 0";
+ ezero
| C.ECall({edesc = C.EVar {name = "__builtin_debug"}}, args) ->
- let len = List.length args in
- if len < 2 then
- error "too few arguments to function call, expected at least 2, have 0";
let (kind, args1) =
match args with
| {edesc = C.EConst(CInt(n,_,_))} :: args1 when n <> 0L-> (n, args1)
@@ -957,6 +957,12 @@ and convertLvalue env e =
let e1' = convertExpr env e1 and e2' = convertExpr env e2 in
let e3' = ewrap (Ctyping.ebinop Cop.Oadd e1' e2') in
ewrap (Ctyping.ederef e3')
+ | C.EConst(C.CStr s) ->
+ let ty = typeStringLiteral s in
+ Evar(name_for_string_literal s, ty)
+ | C.EConst(C.CWStr s) ->
+ let ty = typeWideStringLiteral s in
+ Evar(name_for_wide_string_literal s, ty)
| _ ->
error "illegal lvalue"; ezero
@@ -1002,7 +1008,7 @@ type switchbody =
let rec flattenSwitch = function
| {sdesc = C.Sseq(s1, s2)} ->
flattenSwitch s1 @ flattenSwitch s2
- | {sdesc = C.Slabeled(C.Scase e, s1)} ->
+ | {sdesc = C.Slabeled(C.Scase(e, _), s1)} ->
Label(Case e) :: flattenSwitch s1
| {sdesc = C.Slabeled(C.Sdefault, s1)} ->
Label Default :: flattenSwitch s1
diff --git a/cfrontend/SimplExpr.v b/cfrontend/SimplExpr.v
index 45b686f3..7cdff468 100644
--- a/cfrontend/SimplExpr.v
+++ b/cfrontend/SimplExpr.v
@@ -26,6 +26,7 @@ Require Import Csyntax.
Require Import Clight.
Local Open Scope string_scope.
+Local Open Scope list_scope.
(** State and error monad for generating fresh identifiers. *)
diff --git a/cfrontend/SimplLocals.v b/cfrontend/SimplLocals.v
index b142d3cc..f54aa60d 100644
--- a/cfrontend/SimplLocals.v
+++ b/cfrontend/SimplLocals.v
@@ -22,6 +22,7 @@ Require Compopts.
Open Scope error_monad_scope.
Open Scope string_scope.
+Open Scope list_scope.
Module VSet := FSetAVL.Make(OrderedPositive).
diff --git a/cfrontend/SimplLocalsproof.v b/cfrontend/SimplLocalsproof.v
index 7af499f4..26d3d347 100644
--- a/cfrontend/SimplLocalsproof.v
+++ b/cfrontend/SimplLocalsproof.v
@@ -1053,7 +1053,7 @@ Proof.
assert (RPSRC: Mem.range_perm m bsrc (Ptrofs.unsigned osrc) (Ptrofs.unsigned osrc + sizeof tge ty) Cur Nonempty).
eapply Mem.range_perm_implies. eapply Mem.loadbytes_range_perm; eauto. auto with mem.
assert (RPDST: Mem.range_perm m bdst (Ptrofs.unsigned odst) (Ptrofs.unsigned odst + sizeof tge ty) Cur Nonempty).
- replace (sizeof tge ty) with (Z.of_nat (length bytes)).
+ replace (sizeof tge ty) with (Z.of_nat (List.length bytes)).
eapply Mem.range_perm_implies. eapply Mem.storebytes_range_perm; eauto. auto with mem.
rewrite LEN. apply nat_of_Z_eq. omega.
assert (PSRC: Mem.perm m bsrc (Ptrofs.unsigned osrc) Cur Nonempty).
diff --git a/configure b/configure
index 503a899b..e511704f 100755
--- a/configure
+++ b/configure
@@ -18,15 +18,21 @@
prefix='/usr/local'
bindir='$(PREFIX)/bin'
libdir='$(PREFIX)/lib/compcert'
+coqdevdir='$(PREFIX)/lib/compcert/coq'
toolprefix=''
target=''
has_runtime_lib=true
has_standard_headers=true
clightgen=false
+install_coqdev=false
responsefile="gnu"
ignore_coq_version=false
usage='Usage: ./configure [options] target
+For help on options and targets, do: ./configure -help
+'
+
+help='Usage: ./configure [options] target
Supported targets:
ppc-eabi (PowerPC, EABI with GNU/Unix tools)
@@ -76,13 +82,19 @@ Options:
-prefix <dir> Install in <dir>/bin and <dir>/lib/compcert
-bindir <dir> Install binaries in <dir>
-libdir <dir> Install libraries in <dir>
+ -coqdevdir <dir> Install Coq development (.vo files) in <dir>
-toolprefix <pref> Prefix names of tools ("gcc", etc) with <pref>
-no-runtime-lib Do not compile nor install the runtime support library
-no-standard-headers Do not install nor use the standard .h headers
- -clightgen Also compile the clightgen tool
+ -clightgen Also compile and install the clightgen tool
+ -install-coqdev Also install the Coq development (implied by -clightgen)
-ignore-coq-version Accept to use experimental or unsupported versions of Coq
'
+#
+# Remove Leftover Makefile.config (if any) (GPR#244)
+#
+rm -f Makefile.config
#
# Parse Command-Line Arguments
@@ -97,6 +109,8 @@ while : ; do
bindir="$2"; shift;;
-libdir|--libdir)
libdir="$2"; shift;;
+ -coqdevdir|--coqdevdir)
+ coqdevdir="$2"; install_coqdev=true; shift;;
-toolprefix|--toolprefix)
toolprefix="$2"; shift;;
-no-runtime-lib)
@@ -104,9 +118,18 @@ while : ; do
-no-standard-headers)
has_standard_headers=false;;
-clightgen)
- clightgen=true;;
+ clightgen=true
+ install_coqdev=true;;
-ignore-coq-version|--ignore-coq-version)
ignore_coq_version=true;;
+ -install-coqdev|--install-coqdev|-install-coq-dev|--install-coq-dev)
+ install_coqdev=true;;
+ -help|--help)
+ echo "$help"; exit 0;;
+ -*)
+ echo "Error: unknown option '$1'." 1>&2
+ echo "$usage" 1>&2
+ exit 2;;
*)
if test -n "$target"; then echo "$usage" 1>&2; exit 2; fi
target="$1";;
@@ -505,19 +528,19 @@ missingtools=false
echo "Testing Coq... " | tr -d '\n'
coq_ver=$(${COQBIN}coqc -v 2>/dev/null | sed -n -e 's/The Coq Proof Assistant, version \([^ ]*\).*$/\1/p')
case "$coq_ver" in
- 8.6.1|8.7.0|8.7.1|8.7.2)
+ 8.6.1|8.7.0|8.7.1|8.7.2|8.8.0|8.8.1|8.8.2)
echo "version $coq_ver -- good!";;
?*)
echo "version $coq_ver -- UNSUPPORTED"
if $ignore_coq_version; then
echo "Warning: this version of Coq is unsupported, proceed at your own risks."
else
- echo "Error: CompCert requires Coq version 8.6.1 or 8.7.0 or 8.7.1 or 8.7.2."
+ echo "Error: CompCert requires one of the following Coq versions: 8.8.2, 8.8.1, 8.8.0, 8.7.2, 8.7.1, 8.7.0, 8.6.1"
missingtools=true
fi;;
"")
echo "NOT FOUND"
- echo "Error: make sure Coq version 8.7.2 is installed."
+ echo "Error: make sure Coq version 8.8.1 is installed."
missingtools=true;;
esac
@@ -556,6 +579,8 @@ else
fi
MENHIR_REQUIRED=20161201
+MENHIR_NEW_API=20180530
+menhir_flags=''
echo "Testing Menhir... " | tr -d '\n'
menhir_ver=`menhir --version 2>/dev/null | sed -n -e 's/^.*version \([0-9]*\).*$/\1/p'`
case "$menhir_ver" in
@@ -563,11 +588,14 @@ case "$menhir_ver" in
if test "$menhir_ver" -ge $MENHIR_REQUIRED; then
echo "version $menhir_ver -- good!"
menhir_includes="-I `menhir --suggest-menhirLib`"
- else
+ if test "$menhir_ver" -ge $MENHIR_NEW_API; then
+ menhir_flags="--coq-lib-path compcert.cparser.MenhirLib"
+ fi
+ else
echo "version $menhir_ver -- UNSUPPORTED"
echo "Error: CompCert requires Menhir version $MENHIR_REQUIRED or later."
missingtools=true
- fi;;
+ fi;;
*)
echo "NOT FOUND"
echo "Error: make sure Menhir version $MENHIR_REQUIRED or later is installed."
@@ -648,8 +676,10 @@ BINDIR=$bindir
LIBDIR=$libdir
MANDIR=$sharedir/man
SHAREDIR=$sharedir
+COQDEVDIR=$coqdevdir
OCAML_OPT_COMP=$ocaml_opt_comp
MENHIR_INCLUDES=$menhir_includes
+MENHIR_FLAGS=$menhir_flags
COMPFLAGS=-bin-annot
EOF
@@ -671,6 +701,7 @@ CPREPRO_OPTIONS=$cprepro_options
ENDIANNESS=$endianness
HAS_RUNTIME_LIB=$has_runtime_lib
HAS_STANDARD_HEADERS=$has_standard_headers
+INSTALL_COQDEV=$install_coqdev
LIBMATH=$libmath
MODEL=$model
SYSTEM=$system
@@ -786,6 +817,7 @@ else
bindirexp=`echo "$bindir" | sed -e "s|\\\$(PREFIX)|$prefix|"`
libdirexp=`echo "$libdir" | sed -e "s|\\\$(PREFIX)|$prefix|"`
+coqdevdirexp=`echo "$coqdevdir" | sed -e "s|\\\$(PREFIX)|$prefix|"`
cat <<EOF
@@ -803,12 +835,23 @@ CompCert configuration:
Linker........................ $clinker
Linker needs '-no-pie'........ $clinker_needs_no_pie
Math library.................. $libmath
+ Build command to use.......... $make
Binaries installed in......... $bindirexp
Runtime library provided...... $has_runtime_lib
Library files installed in.... $libdirexp
Standard headers provided..... $has_standard_headers
Standard headers installed in. $libdirexp/include
- Build command to use.......... $make
+EOF
+if $install_coqdev; then
+cat <<EOF
+ Coq development installed in.. $coqdevdirexp
EOF
+else
+cat <<EOF
+ Coq development will not be installed
+EOF
+fi
+
fi
+
diff --git a/cparser/Bitfields.ml b/cparser/Bitfields.ml
index baf2b0ec..696a9a8d 100644
--- a/cparser/Bitfields.ml
+++ b/cparser/Bitfields.ml
@@ -40,7 +40,11 @@ type bitfield_info =
0 < pos + sz <= bitsizeof(int)
*)
-(* Mapping (struct identifier, bitfield name) -> bitfield info *)
+let carrier_field bf =
+ { fld_name = bf.bf_carrier; fld_typ = bf.bf_carrier_typ;
+ fld_bitfield = None; fld_anonymous = false }
+
+(* Mapping (struct/union identifier, bitfield name) -> bitfield info *)
let bitfield_table =
(Hashtbl.create 57: (ident * string, bitfield_info) Hashtbl.t)
@@ -49,6 +53,13 @@ let is_bitfield structid fieldname =
try Some (Hashtbl.find bitfield_table (structid, fieldname))
with Not_found -> None
+(* Mapping struct/union identifier -> list of members after transformation,
+ including the carrier fields, but without the bit fields.
+ structs and unions containing no bit fields are not put in this table. *)
+
+let composite_transformed_members =
+ (Hashtbl.create 57: (ident, C.field list) Hashtbl.t)
+
(* Signedness issues *)
let unsigned_ikind_for_carrier nbits =
@@ -179,9 +190,16 @@ let rec transf_union_members env id count = function
:: transf_union_members env id (count + 1) ms)
let transf_composite env su id attr ml =
- match su with
- | Struct -> (attr, transf_struct_members env id 1 ml)
- | Union -> (attr, transf_union_members env id 1 ml)
+ if List.for_all (fun f -> f.fld_bitfield = None) ml then
+ (attr, ml)
+ else begin
+ let ml' =
+ match su with
+ | Struct -> transf_struct_members env id 1 ml
+ | Union -> transf_union_members env id 1 ml in
+ Hashtbl.add composite_transformed_members id ml';
+ (attr, ml')
+ end
(* Bitfield manipulation expressions *)
@@ -336,12 +354,25 @@ let rec transf_struct_init id fld_init_list =
| Some bf ->
let (el, rem') =
pack_bitfield_init id bf.bf_carrier fld_init_list in
- ({fld_name = bf.bf_carrier; fld_typ = bf.bf_carrier_typ;
- fld_bitfield = None; fld_anonymous = false},
+ (carrier_field bf,
Init_single {edesc = ECast(bf.bf_carrier_typ, or_expr_list el);
etyp = bf.bf_carrier_typ})
:: transf_struct_init id rem'
+(* Add default initialization for carrier fields that are not listed in the output of
+ [transf_struct_init]. This happens with carrier fields that contain no named
+ bitfields, only anonymous bitfields. *)
+
+let rec completed_struct_init env actual expected =
+ match actual, expected with
+ | [], [] -> []
+ | (f_a, i) :: actual', f_e :: expected' when f_a.fld_name = f_e.fld_name ->
+ (f_a, i) :: completed_struct_init env actual' expected'
+ | _, f_e :: expected' ->
+ (f_e, default_init env f_e.fld_typ) :: completed_struct_init env actual expected'
+ | _, [] ->
+ assert false
+
(* Check whether a field access (e.f or e->f) is a bitfield access.
If so, return carrier expression (e and *e, respectively)
and bitfield_info *)
@@ -503,8 +534,19 @@ and transf_init env i =
| Init_struct(id, fld_init_list) ->
let fld_init_list' =
List.map (fun (f, i) -> (f, transf_init env i)) fld_init_list in
- Init_struct(id, transf_struct_init id fld_init_list')
- | Init_union(id, fld, i) -> Init_union(id, fld, transf_init env i)
+ begin match Hashtbl.find composite_transformed_members id with
+ | exception Not_found ->
+ Init_struct(id, fld_init_list')
+ | ml ->
+ Init_struct(id, completed_struct_init env (transf_struct_init id fld_init_list') ml)
+ end
+ | Init_union(id, fld, i) ->
+ let i' = transf_init env i in
+ match is_bitfield id fld.fld_name with
+ | None ->
+ Init_union(id, fld, i')
+ | Some bf ->
+ Init_union(id, carrier_field bf, Init_single (bitfield_initializer bf i'))
(* Declarations *)
@@ -528,6 +570,8 @@ let transf_fundef env f =
(* Programs *)
let program p =
+ Hashtbl.clear bitfield_table;
+ Hashtbl.clear composite_transformed_members;
Transform.program
~composite:transf_composite
~decl: transf_decl
diff --git a/cparser/C.mli b/cparser/C.mli
index cacdbe7c..cc8d4065 100644
--- a/cparser/C.mli
+++ b/cparser/C.mli
@@ -85,9 +85,10 @@ type attributes = attribute list
(** Storage classes *)
type storage =
- | Storage_default
+ | Storage_default (* used for toplevel names without explicit storage *)
| Storage_extern
| Storage_static
+ | Storage_auto (* used for block-scoped names without explicit storage *)
| Storage_register
(** Unary operators *)
@@ -219,7 +220,7 @@ and stmt_desc =
and slabel =
| Slabel of string
- | Scase of exp
+ | Scase of exp * int64
| Sdefault
(** Declarations *)
diff --git a/cparser/Cabs.v b/cparser/Cabs.v
index b3e4ffda..5865ab69 100644
--- a/cparser/Cabs.v
+++ b/cparser/Cabs.v
@@ -140,8 +140,7 @@ with expression :=
| MEMBEROFPTR : expression -> string -> expression
(* Non-standard *)
- | EXPR_ALIGNOF : expression -> expression
- | TYPE_ALIGNOF : (list spec_elem * decl_type) -> expression
+ | ALIGNOF : (list spec_elem * decl_type) -> expression
| BUILTIN_OFFSETOF : (list spec_elem * decl_type) -> list initwhat -> expression
with constant :=
diff --git a/cparser/Ceval.ml b/cparser/Ceval.ml
index c3d7eeeb..58dea5f4 100644
--- a/cparser/Ceval.ml
+++ b/cparser/Ceval.ml
@@ -13,7 +13,7 @@
(* *)
(* *********************************************************************)
-(* Evaluation of compile-time constants *)
+(* Evaluation and recognition of compile-time constants *)
open C
open Cutil
@@ -103,7 +103,7 @@ let cast env ty_to v =
else raise Notconst
| TPtr(ty, _), I n ->
I (normalize_int n (ptr_t_ikind ()))
- | TPtr(ty, _), (S _ | WS _) ->
+ | (TArray(ty, _, _) | TPtr (ty, _)), (S _ | WS _) ->
v
| TEnum(_, _), I n ->
I (normalize_int n enum_ikind)
@@ -217,8 +217,6 @@ let binop env op tyop tyres ty1 v1 ty2 v2 =
comparison env (<=) None tyop v1 v2
| Oge ->
comparison env (>=) None tyop v1 v2
- | Ocomma ->
- v2
| Ologand ->
if boolean_value v1
then if boolean_value v2 then I 1L else I 0L
@@ -274,8 +272,102 @@ let constant_expr env ty e =
match unroll env ty, cast env ty (expr env e) with
| TInt(ik, _), I n -> Some(CInt(n, ik, ""))
| TPtr(_, _), I n -> Some(CInt(n, IInt, ""))
- | TPtr(_, _), S s -> Some(CStr s)
- | TPtr(_, _), WS s -> Some(CWStr s)
+ | (TArray(_, _, _) | TPtr(_, _)), S s -> Some(CStr s)
+ | (TArray(_, _, _) | TPtr(_, _)), WS s -> Some(CWStr s)
| TEnum(_, _), I n -> Some(CInt(n, enum_ikind, ""))
| _ -> None
with Notconst -> None
+
+(* Recognition of constant initializers and constant expressions.
+ This is just a check: no evaluation of the constants is done.
+ Reference: ISO C99 section 6.6 *)
+
+let rec is_constant_init env = function
+ | Init_single e -> is_constant_expr env e
+ | Init_array il -> List.for_all (is_constant_init env) il
+ | Init_struct(id, fil) ->
+ List.for_all (fun (f, i) -> is_constant_init env i) fil
+ | Init_union(id, f, i) -> is_constant_init env i
+
+and is_constant_expr env e =
+ match e.edesc with
+ | EConst cst -> true
+ | ESizeof ty -> true
+ | EAlignof ty -> true
+ | EVar id ->
+ begin match Env.find_ident env id with
+ | Env.II_ident _ -> is_constant_rval_of_lval env e
+ | Env.II_enum _ -> true (* an enum value is a constant *)
+ | exception Env.Error _ -> false (* should not happen *)
+ end
+ | EUnop(op, e1) ->
+ begin match op with
+ | Ominus | Oplus | Olognot | Onot -> is_constant_expr env e1
+ | Oderef | Odot _ | Oarrow _ -> is_constant_rval_of_lval env e
+ | Oaddrof -> is_constant_lval env e1
+ | Opreincr | Opredecr | Opostincr | Opostdecr -> false
+ (* Constant expressions shall not contain increment or decrement *)
+ end
+ | EBinop(op, e1, e2, _) ->
+ begin match op with
+ | Oadd | Osub | Omul | Odiv | Omod
+ | Oand | Oor | Oxor | Oshl | Oshr
+ | Oeq | One | Olt | Ogt | Ole | Oge
+ | Ologand | Ologor ->
+ is_constant_expr env e1 && is_constant_expr env e2
+ | Oindex ->
+ is_constant_rval_of_lval env e
+ | Oassign
+ | Oadd_assign | Osub_assign | Omul_assign | Odiv_assign | Omod_assign
+ | Oand_assign | Oor_assign | Oxor_assign | Oshl_assign | Oshr_assign ->
+ false
+ (* constant expressions shall not contain assignments *)
+ | Ocomma ->
+ false
+ (* some C compilers accept "e1, e2" as a constant expression.
+ But this is not standard ISO C. *)
+ end
+ | EConditional(e1, e2, e3) ->
+ is_constant_expr env e1 && is_constant_expr env e2
+ && is_constant_expr env e3
+ | ECast(ty, e1) ->
+ is_constant_expr env e1
+ | ECompound(ty, i) ->
+ is_constant_init env i
+ | ECall(fn, args) ->
+ false
+ (* constant expressions shall not contain function calls *)
+
+and is_constant_rval_of_lval env e =
+ (* The value of an object shall not be accessed by use of the . -> * []
+ operators. This is the case if the object has array or function type.
+ A scalar type or a composite type implies a memory access. *)
+ match unroll env e.etyp with
+ | TArray _ | TFun _ -> is_constant_lval env e
+ | _ -> false
+
+and is_constant_lval env e =
+ match e.edesc with
+ | EConst (CStr _)
+ | EConst (CWStr _) -> true
+ | EVar id ->
+ begin match Env.find_ident env id with
+ | Env.II_ident(sto, _) ->
+ begin match sto with
+ | Storage_default | Storage_extern | Storage_static -> true
+ | Storage_auto | Storage_register -> false
+ end
+ | Env.II_enum _ -> false (* should not happen *)
+ | exception Env.Error _ -> false (* should not happen *)
+ end
+ | EUnop(Oderef, e1) -> is_constant_expr env e1
+ | EUnop(Odot f, e1) -> is_constant_lval env e1
+ | EUnop(Oarrow f, e1) -> is_constant_expr env e1
+ | EBinop(Oindex, e1, e2, _) ->
+ is_constant_expr env e1 && is_constant_expr env e2
+ | ECompound(ty, i) ->
+ is_constant_init env i
+ | _ -> false
+
+
+
diff --git a/cparser/Ceval.mli b/cparser/Ceval.mli
index 7425a332..32a0ed91 100644
--- a/cparser/Ceval.mli
+++ b/cparser/Ceval.mli
@@ -16,3 +16,5 @@
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
+val is_constant_init: Env.t -> C.init -> bool
+val is_constant_expr: Env.t -> C.exp -> bool
diff --git a/cparser/Cflow.ml b/cparser/Cflow.ml
index c7236ce8..cc257189 100644
--- a/cparser/Cflow.ml
+++ b/cparser/Cflow.ml
@@ -135,7 +135,7 @@ let catch_continue (s: flow) : flow = fun i ->
let o = s i in
{ o with onormal = o.onormal || o.ocontinue; ocontinue = false}
-(* Convert "continue" into "fallthrough". Typically applied to a loop. *)
+(* Convert "break" into "fallthrough". Typically applied to a loop. *)
let catch_break (s: flow) : flow = fun i ->
let o = s i in
diff --git a/cparser/Checks.ml b/cparser/Checks.ml
index ee36e226..62d85c1b 100644
--- a/cparser/Checks.ml
+++ b/cparser/Checks.ml
@@ -106,6 +106,7 @@ let unknown_attrs_program p =
let decl env loc d =
unknown_attrs_decl env loc d
and fundef env loc f =
+ List.iter (fun (id,typ) -> unknown_attrs_typ env loc typ) f.fd_params;
unknown_attrs loc f.fd_attrib;
unknown_attrs_stmt env f.fd_body;
List.iter (unknown_attrs_decl env loc) f.fd_locals;
diff --git a/cparser/Cleanup.ml b/cparser/Cleanup.ml
index fe674d9b..63ac8ac1 100644
--- a/cparser/Cleanup.ml
+++ b/cparser/Cleanup.ml
@@ -93,7 +93,7 @@ let rec add_stmt s =
| Scontinue -> ()
| Sswitch(e, s1) -> add_exp e; add_stmt s1
| Slabeled(lbl, s) ->
- begin match lbl with Scase e -> add_exp e | _ -> () end;
+ begin match lbl with Scase(e, _) -> add_exp e | _ -> () end;
add_stmt s
| Sgoto lbl -> ()
| Sreturn None -> ()
@@ -118,7 +118,12 @@ let add_enum e =
e
(* Saturate the set of referenced identifiers, starting with externally
- visible global declarations *)
+ visible global declarations.
+
+ Externally-visible globals include a minima:
+ - Definitions of functions, unless "static" or "inline".
+ - Declaration of variables with default storage.
+*)
let visible_decl (sto, id, ty, init) =
sto = Storage_default &&
@@ -129,7 +134,7 @@ let visible_fundef f =
| Storage_default -> not f.fd_inline
| Storage_extern -> true
| Storage_static -> false
- | Storage_register -> assert false
+ | Storage_auto | Storage_register -> assert false
let rec add_init_globdecls accu = function
| [] -> accu
diff --git a/cparser/Cprint.ml b/cparser/Cprint.ml
index d623ab96..9aeec421 100644
--- a/cparser/Cprint.ml
+++ b/cparser/Cprint.ml
@@ -361,6 +361,7 @@ let storage pp = function
| Storage_default -> ()
| Storage_extern -> fprintf pp "extern "
| Storage_static -> fprintf pp "static "
+ | Storage_auto -> () (* used only in blocks, where it can be omitted *)
| Storage_register -> fprintf pp "register "
let full_decl pp (sto, id, ty, int) =
@@ -477,7 +478,7 @@ let rec stmt pp s =
and slabel pp = function
| Slabel s ->
fprintf pp "%s" s
- | Scase e ->
+ | Scase(e, _) ->
fprintf pp "case %a" exp (0, e)
| Sdefault ->
fprintf pp "default"
diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml
index f3cd5d14..ea9713d5 100644
--- a/cparser/Cutil.ml
+++ b/cparser/Cutil.ml
@@ -110,7 +110,8 @@ let declare_attributes l =
List.iter (fun (n,c) -> declare_attribute n c) l
let class_of_attribute = function
- | AConst | AVolatile | ARestrict | AAlignas _ -> Attr_type
+ | AConst | AVolatile | ARestrict -> Attr_type
+ | AAlignas _ -> Attr_name
| Attr(name, args) ->
try Hashtbl.find attr_class (normalize_attrname name)
with Not_found -> Attr_unknown
@@ -124,9 +125,8 @@ let attr_is_standard = function
(* Is an attribute applicable to a whole array (true) or only to
array elements (false)? *)
-let attr_array_applicable = function
- | AConst | AVolatile | ARestrict | AAlignas _ -> false
- | Attr _ -> true
+let attr_array_applicable a =
+ class_of_attribute a <> Attr_type
(* Is an attribute of a composite type applicable to members of this type
when they are accessed? *)
@@ -175,11 +175,20 @@ let rec attributes_of_type env t =
| TFun(ty, params, vararg, a) -> a
| TNamed(s, a) -> attributes_of_type env (unroll env t)
| TStruct(s, a) ->
- let ci = Env.find_struct env s in add_attributes ci.ci_attr a
+ begin match Env.find_struct env s with
+ | ci -> add_attributes ci.ci_attr a
+ | exception Env.Error(Env.Unbound_tag _) -> a
+ end
| TUnion(s, a) ->
- let ci = Env.find_union env s in add_attributes ci.ci_attr a
+ begin match Env.find_union env s with
+ | ci -> add_attributes ci.ci_attr a
+ | exception Env.Error(Env.Unbound_tag _) -> a
+ end
| TEnum(s, a) ->
- let ei = Env.find_enum env s in add_attributes ei.ei_attr a
+ begin match Env.find_enum env s with
+ | ei -> add_attributes ei.ei_attr a
+ | exception Env.Error(Env.Unbound_tag _) -> a
+ end
(* Changing the attributes of a type (at top-level) *)
(* Same hack as above for array types. *)
@@ -249,15 +258,33 @@ let strip_last_attribute typ =
| TEnum (n,at) -> let l,r = hd_opt at in
l,TEnum(n,r)
+(* Check whether the attributes contain _Alignas attribute *)
+let has_std_alignas env typ =
+ List.exists (function | AAlignas _ -> true | _ -> false) (attributes_of_type env typ)
+
(* Extracting alignment value from a set of attributes. Return 0 if none. *)
let alignas_attribute al =
let rec alignas_attr accu = function
| [] -> accu
| AAlignas n :: al -> alignas_attr (max n accu) al
+ | Attr(("aligned" | "__aligned__"), [AInt n]) :: al ->
+ alignas_attr (max (Int64.to_int n) accu) al
| a :: al -> alignas_attr accu al
in alignas_attr 0 al
+(* Extracting struct packing parameters from a set of attributes.
+ Assume the parameters were checked earlier, e.g. alignments are
+ either 0 or powers of two. *)
+
+let packing_parameters al =
+ match find_custom_attributes ["packed";"__packed__"] al with
+ | [[]] -> (1, 0, false)
+ | [[AInt n]] -> (Int64.to_int n, 0, false)
+ | [[AInt n; AInt p]] -> (Int64.to_int n, Int64.to_int p, false)
+ | [[AInt n; AInt p; AInt q]] -> (Int64.to_int n, Int64.to_int p, q = 1L)
+ | _ -> (0, 0, false)
+
(* Type compatibility *)
exception Incompat
@@ -452,7 +479,10 @@ let rec alignof env t =
let ci = Env.find_union env name in ci.ci_alignof
| TEnum(_, _) -> Some(alignof_ikind enum_ikind)
-(* Compute the natural alignment of a struct or union. *)
+(* Compute the natural alignment of a struct or union.
+ Not done here but in composite_info_decl: taking into account
+ the packing parameters (max-field-alignment, min-struct-alignment)
+ and the alignas attributes. *)
let alignof_struct_union env members =
let rec align_rec al = function
@@ -521,7 +551,7 @@ let rec sizeof env t =
(* Compute the size of a union.
It is the size is the max of the sizes of fields.
- Not done here but in composite_info_decl: rounding size to alignment. *)
+ Not done here but in composite_info_def: rounding size to alignment. *)
let sizeof_union env members =
let rec sizeof_rec sz = function
@@ -534,69 +564,66 @@ let sizeof_union env members =
end
in sizeof_rec 0 members
-(* Compute the size of a struct.
+(* Compute the size of a struct and the byte offset of the members.
We lay out fields consecutively, inserting padding to preserve
their alignment.
- Not done here but in composite_info_decl: rounding size to alignment. *)
-let sizeof_struct env members =
- let rec sizeof_rec ofs = function
+ The [ma] parameter is the maximal alignment for each member.
+ It is used for packed structs. If [ma = 0], it is ignored.
+ Bitfields are taken into account for the size and offset computations
+ but not given an offset.
+ Not done here but in composite_info_def: rounding size to alignment. *)
+let sizeof_layout_struct env members ma =
+ let align_offset ofs a =
+ align ofs (if ma > 0 && a > ma then ma else a) in
+ let rec sizeof_rec ofs accu = function
| [] ->
- Some ofs
+ Some (ofs, accu)
| [ { fld_typ = TArray(_, None, _) } as m ] ->
(* C99: ty[] allowed as last field *)
begin match alignof env m.fld_typ with
- | Some a -> Some (align ofs a)
+ | Some a ->
+ let ofs = align_offset ofs a in
+ Some (ofs, (m.fld_name, ofs) :: accu)
| None -> None
end
| m :: rem as ml ->
if m.fld_bitfield = None then begin
match alignof env m.fld_typ, sizeof env m.fld_typ with
- | Some a, Some s -> sizeof_rec (align ofs a + s) rem
+ | Some a, Some s ->
+ let ofs = align_offset ofs a in
+ sizeof_rec (ofs + s) ((m.fld_name, ofs) :: accu) rem
| _, _ -> None
end else begin
let (s, a, ml') = pack_bitfields ml in
- sizeof_rec (align ofs a + s) ml'
+ sizeof_rec (align_offset ofs a + s) accu ml'
end
- in sizeof_rec 0 members
+ in sizeof_rec 0 [] members
+
+let sizeof_struct env members ma =
+ match sizeof_layout_struct env members ma with
+ | None -> None
+ | Some(sz, offsets) -> Some sz
+
+(* Compute the offsets of all non-bitfield members of a struct. *)
+let struct_layout env attrs members =
+ let (ma, _, _) = packing_parameters attrs in
+ match sizeof_layout_struct env members ma with
+ | Some(sz, offsets) -> offsets
+ | None -> []
(* Compute the offset of a struct member *)
let offsetof env ty field =
- let rec sub acc name = function
- | [] -> List.rev acc
- | m::rem -> if m.fld_name = name then
- List.rev acc
- else
- sub (m::acc) name rem in
match unroll env ty with
- | TStruct (id,_) ->
+ | TStruct (id, _) ->
let str = Env.find_struct env id in
- let pre = sub [] field.fld_name str.ci_members in
- begin match sizeof_struct env pre, alignof env field.fld_typ with
- | Some s, Some a ->
- align s a
- | _ -> assert false end
- | TUnion _ -> 0
- | _ -> assert false
-
-(* Simplified version to compute offsets on structs without bitfields *)
-let struct_layout env members =
- let rec struct_layout_rec mem ofs = function
- | [] ->
- mem
- | [ { fld_typ = TArray(_, None, _) } as m ] ->
- (* C99: ty[] allowed as last field *)
- begin match alignof env m.fld_typ with
- | Some a -> ( m.fld_name,align ofs a)::mem
- | None -> []
+ let offsets = struct_layout env str.ci_attr str.ci_members in
+ begin try
+ List.assoc field.fld_name offsets
+ with Not_found ->
+ raise (Env.Error(No_member(id.C.name, "struct", field.fld_name)))
end
- | m :: rem ->
- match alignof env m.fld_typ, sizeof env m.fld_typ with
- | Some a, Some s ->
- let offset = align ofs a in
- struct_layout_rec ((m.fld_name,offset)::mem) (offset + s) rem
- | _, _ -> []
- in struct_layout_rec [] 0 members
-
+ | TUnion _ -> 0
+ | _ -> assert false
(* Determine whether a type is incomplete *)
@@ -616,12 +643,35 @@ let composite_info_decl su attr =
ci_attr = attr }
let composite_info_def env su attr m =
+ let (max_field_align, min_struct_align, swapped) = packing_parameters attr in
+ let attr_align = alignas_attribute attr in
+ let natural_align = alignof_struct_union env m in
let al =
- let a = alignas_attribute attr in
- if a > 0 then Some a else alignof_struct_union env m
- and sz =
+ (* alignas takes precedence over packing *)
+ if attr_align > 0 then Some attr_align
+ (* ignore packing on unions for compatibility with earlier versions *)
+ else if su = Union then natural_align
+ else begin
+ match natural_align with
+ | None -> None
+ | Some a ->
+ (* If max_field_align is given, reduce natural alignment a
+ to be at most max_field_align *)
+ let a =
+ if max_field_align > 0 && a > max_field_align
+ then max_field_align
+ else a in
+ (* If min_struct_align is given, increase alignment a
+ to be at least min_struct_align *)
+ let a =
+ if min_struct_align > 0 && a < min_struct_align
+ then min_struct_align
+ else a in
+ Some a
+ end in
+ let sz =
match su with
- | Struct -> sizeof_struct env m
+ | Struct -> sizeof_struct env m max_field_align
| Union -> sizeof_union env m
in
{ ci_kind = su; ci_members = m;
@@ -749,6 +799,11 @@ let is_anonymous_composite = function
| TUnion (id,_) -> id.C.name = ""
| _ -> false
+let is_function_pointer_type env t =
+ match unroll env t with
+ | TPtr (ty, _) -> is_function_type env ty
+ | _ -> false
+
(* Find the info for a field access *)
let field_of_dot_access env t m =
@@ -780,6 +835,15 @@ let float_rank = function
| FDouble -> 2
| FLongDouble -> 3
+(* Test for qualified array types *)
+
+let rec is_qualified_array = function
+ | TArray (ty, _, attr) ->
+ List.exists attr_is_standard attr || is_qualified_array ty
+ | TPtr (ty, _) -> is_qualified_array ty
+ | TFun(ty_ret, _, _, _) -> is_qualified_array ty_ret
+ | _ -> false
+
(* Array and function types "decay" to pointer types in many cases *)
let pointer_decay env t =
@@ -857,7 +921,7 @@ let argument_conversion env t =
(* Arrays and functions degrade automatically to pointers *)
(* Other types are not changed *)
match unroll env t with
- | TArray(ty, _, _) -> TPtr(ty, [])
+ | TArray(ty, _, attr) -> TPtr(ty, attr)
| TFun _ as ty -> TPtr(ty, [])
| _ -> t (* preserve typedefs *)
@@ -923,8 +987,12 @@ let ptrdiff_t_ikind () = find_matching_signed_ikind !config.sizeof_ptrdiff_t
let type_of_constant = function
| CInt(_, ik, _) -> TInt(ik, [])
| CFloat(_, fk) -> TFloat(fk, [])
- | CStr _ -> TPtr(TInt(IChar, []), [])
- | CWStr _ -> TPtr(TInt(wchar_ikind(), []), [])
+ | CStr s ->
+ let size = Int64.of_int (String.length s + 1) in
+ TArray(TInt(IChar,[]), Some size, [])
+ | CWStr s ->
+ let size = Int64.of_int (List.length s + 1) in
+ TArray(TInt(wchar_ikind(), []), Some size, [])
| CEnum(_, _) -> TInt(IInt, [])
(* Check that a C expression is a lvalue *)
@@ -932,6 +1000,8 @@ let type_of_constant = function
let rec is_lvalue e =
match e.edesc with
| EVar id -> true
+ | EConst (CStr _)
+ | EConst (CWStr _) -> true
| EUnop((Oderef | Oarrow _), _) -> true
| EUnop(Odot _, e') -> is_lvalue e'
| EBinop(Oindex, _, _, _) -> true
@@ -998,6 +1068,17 @@ let is_bitfield env e =
fld.fld_bitfield <> None
| _ -> false
+let contains_flex_array_mem env ty =
+ match unroll env ty with
+ | TStruct (id,_) ->
+ let ci = Env.find_struct env id in
+ let rec check_mem = function
+ | [] -> false
+ | [ { fld_typ = TArray(ty_elt, None, _) } ] -> true
+ | _::rem -> check_mem rem in
+ check_mem ci.ci_members
+ | _ -> false
+
(* Assignment compatibility check over attributes.
Standard attributes ("const", "volatile", "restrict") can safely
be added (to the rhs type to get the lhs type) but must not be dropped.
diff --git a/cparser/Cutil.mli b/cparser/Cutil.mli
index fb875b0d..dc9dc0cc 100644
--- a/cparser/Cutil.mli
+++ b/cparser/Cutil.mli
@@ -34,8 +34,14 @@ val remove_attributes : attributes -> attributes -> attributes
val incl_attributes : attributes -> attributes -> bool
(* Check that first set of attributes is a subset of second set. *)
val alignas_attribute : attributes -> int
- (* Extract the value of the [_Alignas] attributes, if any.
+ (* Extract the value of the [_Alignas] and [attribute((aligned(N)))]
+ attributes, if any.
Return 0 if none, a (positive) power of two alignment if some. *)
+val packing_parameters : attributes -> int * int * bool
+ (* Extract the value of the [__packed__] attributes, if any.
+ Return a triple
+ (maximum field alignment, minimum struct alignment, byte swapping).
+ Alignments of 0 mean default alignment. *)
val find_custom_attributes : string list -> attributes -> attr_arg list list
(* Extract arguments of custom [Attr] attributes whose names appear
in the given list of names. *)
@@ -52,6 +58,8 @@ val erase_attributes_type : Env.t -> typ -> typ
(* Erase the attributes of the given type. *)
val change_attributes_type : Env.t -> (attributes -> attributes) -> typ -> typ
(* Apply the given function to the top-level attributes of the given type *)
+val has_std_alignas : Env.t -> typ -> bool
+ (* Do the attributes of the type contain the C11 _Alignas attribute *)
type attribute_class =
| Attr_name (* Attribute applies to the names being declared *)
@@ -127,7 +135,7 @@ val composite_info_decl:
val composite_info_def:
Env.t -> struct_or_union -> attributes -> field list -> Env.composite_info
val struct_layout:
- Env.t -> field list -> (string * int) list
+ Env.t -> attributes -> field list -> (string * int) list
val offsetof:
Env.t -> typ -> field -> int
(* Compute the offset of a struct member *)
@@ -153,8 +161,12 @@ val is_composite_type : Env.t -> typ -> bool
(* Is type a struct or union? *)
val is_function_type : Env.t -> typ -> bool
(* Is type a function type? (not pointer to function) *)
+val is_function_pointer_type : Env.t -> typ -> bool
+ (* Is type a pointer to function type? *)
val is_anonymous_composite : typ -> bool
- (* Is type an anonymous composite? *)
+ (* Is type an anonymous composite? *)
+val is_qualified_array : typ -> bool
+ (* Does the type contain a qualified array type (e.g. int[const 5])? *)
val pointer_arithmetic_ok : Env.t -> typ -> bool
(* Is the type [*ty] appropriate for pointer arithmetic?
[ty] must not be void, nor a function type, nor an incomplete type. *)
@@ -245,6 +257,8 @@ val is_volatile_variable: Env.t -> exp -> bool
(* Test whether the expression is an access to a volatile variable *)
val is_bitfield: Env.t -> exp -> bool
(* Test whether the expression is a bit-field *)
+val contains_flex_array_mem : Env.t -> typ -> bool
+ (* Is this a struct with a flexible array member *)
(* Constructors *)
diff --git a/cparser/Diagnostics.ml b/cparser/Diagnostics.ml
index f18d1b2d..172affab 100644
--- a/cparser/Diagnostics.ml
+++ b/cparser/Diagnostics.ml
@@ -92,12 +92,17 @@ type warning_type =
| Unused_parameter
| Wrong_ais_parameter
| Unused_ais_parameter
+ | Ignored_attributes
+ | Extern_after_definition
+ | Static_in_inline
+ | Flexible_array_extensions
+ | Tentative_incomplete_static
+ | Reduced_alignment
(* List of active warnings *)
let active_warnings: warning_type list ref = ref [
Unnamed;
Unknown_attribute;
- Celeven_extension;
Gnu_empty_struct;
Missing_declarations;
Constant_conversion;
@@ -114,6 +119,9 @@ let active_warnings: warning_type list ref = ref [
Inline_asm_sdump;
Wrong_ais_parameter;
Unused_ais_parameter;
+ Ignored_attributes;
+ Extern_after_definition;
+ Static_in_inline;
]
(* List of errors treated as warning *)
@@ -145,6 +153,12 @@ let string_of_warning = function
| Unused_parameter -> "unused-parameter"
| Wrong_ais_parameter -> "wrong-ais-parameter"
| Unused_ais_parameter -> "unused-ais-parameter"
+ | Ignored_attributes -> "ignored-attributes"
+ | Extern_after_definition -> "extern-after-definition"
+ | Static_in_inline -> "static-in-inline"
+ | Flexible_array_extensions -> "flexible-array-extensions"
+ | Tentative_incomplete_static -> "tentative-incomplete-static"
+ | Reduced_alignment -> "reduced-alignment"
(* Activate the given warning *)
let activate_warning w () =
@@ -192,6 +206,12 @@ let wall () =
Unused_variable;
Unused_parameter;
Wrong_ais_parameter;
+ Ignored_attributes;
+ Extern_after_definition;
+ Static_in_inline;
+ Flexible_array_extensions;
+ Tentative_incomplete_static;
+ Reduced_alignment;
]
let wnothing () =
@@ -223,6 +243,12 @@ let werror () =
Unused_variable;
Wrong_ais_parameter;
Unused_ais_parameter;
+ Ignored_attributes;
+ Extern_after_definition;
+ Static_in_inline;
+ Flexible_array_extensions;
+ Tentative_incomplete_static;
+ Reduced_alignment;
]
(* Generate the warning key for the message *)
@@ -401,6 +427,12 @@ let warning_options =
error_option Unused_parameter @
error_option Wrong_ais_parameter @
error_option Unused_ais_parameter @
+ error_option Ignored_attributes @
+ error_option Extern_after_definition @
+ error_option Static_in_inline @
+ error_option Flexible_array_extensions @
+ error_option Tentative_incomplete_static @
+ error_option Reduced_alignment @
[Exact ("-Wfatal-errors"), Set error_fatal;
Exact ("-fdiagnostics-color"), Ignore; (* Either output supports it or no color *)
Exact ("-fno-diagnostics-color"), Unset color_diagnostics;
diff --git a/cparser/Diagnostics.mli b/cparser/Diagnostics.mli
index 75865cb2..ded8019f 100644
--- a/cparser/Diagnostics.mli
+++ b/cparser/Diagnostics.mli
@@ -49,6 +49,12 @@ type warning_type =
| Unused_parameter (** unused function parameter *)
| Wrong_ais_parameter (** wrong parameter type for ais replacement *)
| Unused_ais_parameter (** unused builtin ais parameter *)
+ | Ignored_attributes (** attributes declarations after definition *)
+ | Extern_after_definition (** extern declaration after non-extern definition *)
+ | Static_in_inline (** static variable in non-static inline function *)
+ | Flexible_array_extensions (** usange of structs with flexible arrays in structs and arrays *)
+ | Tentative_incomplete_static (** static tentative definition with incomplete type *)
+ | Reduced_alignment (** alignment reduction *)
val warning : (string * int) -> warning_type -> ('a, Format.formatter, unit, unit, unit, unit) format6 -> 'a
(** [warning (f,c) w fmt arg1 ... argN] formats the arguments [arg1] to [argN] as warining according to
diff --git a/cparser/Elab.ml b/cparser/Elab.ml
index a1f85886..718261b4 100644
--- a/cparser/Elab.ml
+++ b/cparser/Elab.ml
@@ -69,6 +69,20 @@ let top_declarations = ref ([] : globdecl list)
let top_environment = ref Env.empty
+(* Set of all globals with a definitions *)
+
+module StringSet = Set.Make(String)
+
+let global_defines = ref StringSet.empty
+
+let add_global_define loc name =
+ if StringSet.mem name !global_defines then
+ error loc "redefinition of '%s'" name;
+ global_defines := StringSet.add name !global_defines
+
+let is_global_defined name =
+ StringSet.mem name !global_defines
+
let emit_elab ?(debuginfo = true) ?(linkage = false) env loc td =
let loc = elab_loc loc in
let dec ={ gdesc = td; gloc = loc } in
@@ -84,7 +98,7 @@ let emit_elab ?(debuginfo = true) ?(linkage = false) env loc td =
| _ -> ()
end
-let reset() = top_declarations := []; top_environment := Env.empty
+let reset() = top_declarations := []; top_environment := Env.empty; global_defines := StringSet.empty
let elaborated_program () =
let p = !top_declarations in
@@ -101,6 +115,15 @@ let rec mmap f env = function
let (tl', env2) = mmap f env1 tl in
(hd' :: tl', env2)
+let rec mmap2 f env l1 l2 =
+ match l1,l2 with
+ | [],[] -> [],env
+ | a1::l1,a2::l2 ->
+ let hd,env1 = f env a1 a2 in
+ let tl,env2 = mmap2 f env1 l1 l2 in
+ (hd::tl,env2)
+ | _, _ -> invalid_arg "mmap2"
+
(* To detect redefinitions within the same scope *)
let previous_def fn env arg =
@@ -116,6 +139,13 @@ let redef fn env arg =
(* Auxiliaries for handling declarations and redeclarations *)
+let name_of_storage_class = function
+ | Storage_default -> "<default>"
+ | Storage_extern -> "'extern'"
+ | Storage_static -> "'static'"
+ | Storage_auto -> "'auto'"
+ | Storage_register -> "'register'"
+
let combine_toplevel_definitions loc env s old_sto old_ty sto ty =
let new_ty =
match combine_types AttrCompat env old_ty ty with
@@ -126,26 +156,43 @@ let combine_toplevel_definitions loc env s old_sto old_ty sto ty =
"redefinition of '%s' with a different type: %a vs %a"
s (print_typ env) old_ty (print_typ env) ty;
ty in
+ if is_global_defined s then begin
+ let old_attrs = attributes_of_type env old_ty
+ and new_attrs = attributes_of_type env ty in
+ if not (Cutil.incl_attributes new_attrs old_attrs) then
+ warning loc Ignored_attributes "attribute declaration must precede definition"
+ end;
let new_sto =
(* The only case not allowed is removing static *)
match old_sto,sto with
| Storage_static,Storage_static
| Storage_extern,Storage_extern
- | Storage_register,Storage_register
| Storage_default,Storage_default -> sto
| _,Storage_static ->
error loc "static declaration of '%s' follows non-static declaration" s;
sto
| Storage_static,_ -> Storage_static (* Static stays static *)
| Storage_extern,_ -> sto
- | Storage_default,Storage_extern -> Storage_extern
+ | Storage_default,Storage_extern ->
+ if is_global_defined s && is_function_type env ty then
+ warning loc Extern_after_definition "this extern declaration follows a non-extern definition and is ignored";
+ Storage_extern
| _,Storage_extern -> old_sto
+ (* "auto" and "register" don't appear in toplevel definitions.
+ Normally this was checked earlier. Generate error message
+ instead of "assert false", just in case. *)
+ | _,Storage_auto
+ | Storage_auto,_
| _,Storage_register
- | Storage_register,_ -> Storage_register
+ | Storage_register,_ ->
+ error loc "unexpected %s declaration of '%s'"
+ (name_of_storage_class sto) s;
+ sto
in
(new_sto, new_ty)
-let enter_or_refine_ident local loc env s sto ty =
+let enter_or_refine_ident_base local loc env new_id sto ty =
+ let s = new_id.C.name in
(* Check for illegal redefinitions:
- a name that was previously a typedef
- a variable that was already declared in the same local scope
@@ -155,41 +202,67 @@ let enter_or_refine_ident local loc env s sto ty =
if redef Env.lookup_typedef env s then
error loc "redefinition of '%s' as different kind of symbol" s;
begin match previous_def Env.lookup_ident env s with
- | Some(id, Env.II_ident(old_sto, old_ty))
- when local && Env.in_current_scope env id
+ | Some(old_id, Env.II_ident(old_sto, old_ty))
+ when local && Env.in_current_scope env old_id
&& not (sto = Storage_extern && old_sto = Storage_extern) ->
error loc "redefinition of '%s'" s
- | Some(id, Env.II_enum _) when Env.in_current_scope env id ->
+ | Some(old_id, Env.II_enum _) when Env.in_current_scope env old_id ->
error loc "redefinition of '%s' as different kind of symbol" s;
| _ ->
()
end;
- (* For a block-scoped, non-"extern" variable, a new declaration
- is entered, and it has no linkage. *)
- if local && sto <> Storage_extern then begin
- let (id, env') = Env.enter_ident env s sto ty in
- (id, sto, env', ty, false)
+ (* For a block-scoped, "static" or "auto" or "register" variable,
+ a new declaration is entered, and it has no linkage. *)
+ if local
+ && (sto = Storage_auto || sto = Storage_register || sto = Storage_static)
+ then begin
+ (new_id, sto, Env.add_ident env new_id sto ty, ty, false)
end else begin
(* For a file-scoped or "extern" variable, we need to check against
prior declarations of this variable with internal or external linkage.
The variable has linkage. *)
match previous_def Env.lookup_ident !top_environment s with
- | Some(id, Env.II_ident(old_sto, old_ty)) ->
+ | Some(old_id, Env.II_ident(old_sto, old_ty)) ->
let (new_sto, new_ty) =
combine_toplevel_definitions loc env s old_sto old_ty sto ty in
- (id, new_sto, Env.add_ident env id new_sto new_ty, new_ty, true)
+ (old_id, new_sto, Env.add_ident env old_id new_sto new_ty, new_ty, true)
| _ ->
- let (id, env') = Env.enter_ident env s sto ty in
- (id, sto, env', ty, true)
+ (new_id, sto, Env.add_ident env new_id sto ty, ty, true)
end
+(* We use two variants of [enter_or_refine]:
+
+ - [enter_or_refine_ident] is to be used for all declarations,
+ block-scoped ([local = true]) or top-level ([local = false]).
+ The name of the declared thing is given as a string [s]. If a
+ previous declaration with this name exists in the current scope,
+ its unique identifier is returned. Otherwise a fresh identifier
+ named [s] is created in the current scope of [env] and returned.
+
+ - [enter_or_refine_function] is to be used for function definitions.
+ Such definitions are always global, hence the [local] parameter
+ defaults to [false] and is omitted. The function name is given
+ as an identifier, created in advance by the caller. This
+ identifier is used if no previous declaration exists for the
+ function. Otherwise, the identifier of the previous declaration is
+ used. By creating the identifier in advance, [elab_fundef] makes
+ sure that it is properly scoped to file scope and not to the local
+ scope of function parameters.
+*)
+
+let enter_or_refine_ident local loc env s sto ty =
+ enter_or_refine_ident_base local loc env (Env.fresh_ident s) sto ty
+
+let enter_or_refine_function loc env id sto ty =
+ enter_or_refine_ident_base false loc env id sto ty
+
(* Forward declarations *)
let elab_expr_f : (cabsloc -> Env.t -> Cabs.expression -> C.exp * Env.t) ref
= ref (fun _ _ _ -> assert false)
-let elab_funbody_f : (C.typ -> bool -> Env.t -> statement -> C.stmt) ref
- = ref (fun _ _ _ _ -> assert false)
+let elab_funbody_f : (C.typ -> bool -> bool -> Env.t -> statement -> C.stmt) ref
+ = ref (fun _ _ _ _ _ -> assert false)
(** * Elaboration of constants - C99 section 6.4.4 *)
@@ -422,35 +495,53 @@ let elab_gcc_attr loc env = function
let is_power_of_two n = n > 0L && Int64.logand n (Int64.pred n) = 0L
-let extract_alignas loc a =
+(* Check alignment parameter *)
+let check_alignment loc n =
+ if not (is_power_of_two n || n = 0L) then begin
+ error loc "requested alignment %Ld is not a power of 2" n; false
+ end else
+ if n <> Int64.of_int (Int64.to_int n) then begin
+ error loc "requested alignment %Ld is too large" n; false
+ end else
+ true
+
+(* Process GCC attributes that have special significance. Currently we
+ have two: "aligned" and "packed". *)
+let enter_gcc_attr loc a =
match a with
| Attr(("aligned"|"__aligned__"), args) ->
begin match args with
- | [AInt n] when is_power_of_two n -> AAlignas (Int64.to_int n)
- | [AInt n] -> error loc "requested alignment is not a power of 2"; a
- | [_] -> error loc "requested alignment is not an integer constant"; a
- | [] -> a (* Use the default alignment as the gcc does *)
- | _ -> error loc "'aligned' attribute takes no more than 1 argument"; a
+ | [AInt n] -> if check_alignment loc n then [a] else []
+ | [_] -> error loc "requested alignment is not an integer constant"; []
+ | [] -> [] (* Use default alignment, like gcc does *)
+ | _ -> error loc "'aligned' attribute takes no more than 1 argument"; []
+ end
+ | Attr(("packed"|"__packed__"), args) ->
+ begin match args with
+ | [] -> [a]
+ | [AInt n] -> if check_alignment loc n then [a] else []
+ | [AInt n; AInt p] ->
+ if check_alignment loc n && check_alignment loc p then [a] else []
+ | [AInt n; AInt p; AInt q] when q = 0L || q = 1L ->
+ if check_alignment loc n && check_alignment loc p then [a] else []
+ | _ -> error loc "ill-formed 'packed' attribute"; []
end
- | _ -> a
+ | _ -> [a]
let elab_attribute env = function
| GCC_ATTR (l, loc) ->
List.fold_left add_attributes []
- (List.map (fun attr -> [attr])
- (List.map (extract_alignas loc)
- (List.flatten
- (List.map (elab_gcc_attr loc env) l))))
+ (List.map (enter_gcc_attr loc)
+ (List.flatten
+ (List.map (elab_gcc_attr loc env) l)))
| PACKED_ATTR (args, loc) ->
- [Attr("__packed__", List.map (elab_attr_arg loc env) args)]
+ enter_gcc_attr loc
+ (Attr("__packed__", List.map (elab_attr_arg loc env) args))
| ALIGNAS_ATTR ([a], loc) ->
+ warning loc Celeven_extension "'_Alignas' is a C11 extension";
begin match elab_attr_arg loc env a with
| AInt n ->
- if is_power_of_two n then
- [AAlignas (Int64.to_int n)]
- else begin
- error loc "requested alignment is not a power of 2"; []
- end
+ if check_alignment loc n then [AAlignas (Int64.to_int n)] else []
| _ -> error loc "requested alignment is not an integer constant"; []
| exception Wrong_attr_arg -> error loc "bad _Alignas value"; []
end
@@ -460,6 +551,22 @@ let elab_attribute env = function
let elab_attributes env al =
List.fold_left add_attributes [] (List.map (elab_attribute env) al)
+(* Warning for alignment requests that reduce the alignment below the
+ natural alignment. *)
+
+let warn_if_reduced_alignment loc ~actual ~natural =
+ match actual, natural with
+ | Some act, Some nat when act < nat ->
+ warning loc Reduced_alignment
+ "requested alignment (%d) is less than natural alignment (%d)"
+ act nat
+ | _, _ -> ()
+
+let check_reduced_alignment loc env typ =
+ warn_if_reduced_alignment loc
+ ~actual: (wrap alignof loc env typ)
+ ~natural: (wrap alignof loc env (erase_attributes_type env typ))
+
(* Auxiliary for typespec elaboration *)
let typespec_rank = function (* Don't change this *)
@@ -491,14 +598,15 @@ let get_nontype_attrs env ty =
let nta = List.filter to_be_removed (attributes_of_type env ty) in
(remove_attributes_type env nta ty, nta)
-(* Elaboration of a type specifier. Returns 5-tuple:
- (storage class, "inline" flag, "typedef" flag, elaborated type, new env)
+(* Elaboration of a type specifier. Returns 6-tuple:
+ (storage class, "inline" flag, "noreturn" flag, "typedef" flag,
+ elaborated type, new env)
Optional argument "only" is true if this is a standalone
struct or union declaration, without variable names.
C99 section 6.7.2.
*)
-let rec elab_specifier keep_ty ?(only = false) loc env specifier =
+let rec elab_specifier ?(only = false) loc env specifier =
(* We first divide the parts of the specifier as follows:
- a storage class
- a set of attributes (const, volatile, restrict)
@@ -506,18 +614,20 @@ let rec elab_specifier keep_ty ?(only = false) loc env specifier =
let sto = ref Storage_default
and inline = ref false
and noreturn = ref false
+ and restrict = ref false
and attr = ref []
and tyspecs = ref []
and typedef = ref false in
let do_specifier = function
| SpecCV cv ->
+ restrict := cv = CV_RESTRICT;
attr := add_attributes (elab_cvspec env cv) !attr
| SpecStorage st ->
if !sto <> Storage_default && st <> TYPEDEF then
- error loc "multiple storage-classes in declaration specifier";
+ error loc "multiple storage classes in declaration specifier";
begin match st with
- | AUTO -> ()
+ | AUTO -> sto := Storage_auto
| STATIC -> sto := Storage_static
| EXTERN -> sto := Storage_extern
| REGISTER -> sto := Storage_register
@@ -530,9 +640,18 @@ let rec elab_specifier keep_ty ?(only = false) loc env specifier =
| SpecFunction NORETURN -> noreturn := true
| SpecType tys -> tyspecs := tys :: !tyspecs in
+ let restrict_check ty =
+ if !restrict then
+ if not (is_pointer_type env ty) then
+ error loc "restrict requires a pointer type (%a is invalid)" (print_typ env) ty
+ else if is_function_pointer_type env ty then
+ error loc "pointer to function type %a may not be 'restrict' qualified" (print_typ env) ty in
+
List.iter do_specifier specifier;
- let simple ty = (!sto, !inline, !noreturn ,!typedef, add_attributes_type !attr ty, env) in
+ let simple ty =
+ restrict_check ty;
+ (!sto, !inline, !noreturn ,!typedef, add_attributes_type !attr ty, env) in
(* As done in CIL, partition !attr into struct-related attributes,
which are returned, and other attributes, which are left in !attr.
@@ -603,22 +722,28 @@ let rec elab_specifier keep_ty ?(only = false) loc env specifier =
let a' =
add_attributes (get_struct_attrs()) (elab_attributes env a) in
let (id', env') =
- elab_struct_or_union keep_ty only Struct loc id optmembers a' env in
- (!sto, !inline, !noreturn, !typedef, TStruct(id', !attr), env')
+ elab_struct_or_union only Struct loc id optmembers a' env in
+ let ty = TStruct(id', !attr) in
+ restrict_check ty;
+ (!sto, !inline, !noreturn, !typedef, ty, env')
| [Cabs.Tstruct_union(UNION, id, optmembers, a)] ->
let a' =
add_attributes (get_struct_attrs()) (elab_attributes env a) in
let (id', env') =
- elab_struct_or_union keep_ty only Union loc id optmembers a' env in
- (!sto, !inline, !noreturn, !typedef, TUnion(id', !attr), env')
+ elab_struct_or_union only Union loc id optmembers a' env in
+ let ty = TUnion(id', !attr) in
+ restrict_check ty;
+ (!sto, !inline, !noreturn, !typedef, ty, env')
| [Cabs.Tenum(id, optmembers, a)] ->
let a' =
add_attributes (get_struct_attrs()) (elab_attributes env a) in
let (id', env') =
elab_enum only loc id optmembers a' env in
- (!sto, !inline, !noreturn, !typedef, TEnum(id', !attr), env')
+ let ty = TEnum (id', !attr) in
+ restrict_check ty;
+ (!sto, !inline, !noreturn, !typedef, ty, env')
(* Specifier doesn't make sense *)
| _ ->
@@ -644,12 +769,23 @@ and elab_return_type loc env ty =
error loc "function cannot return function type %a" (print_typ env) ty
| _ -> ()
-and elab_type_declarator keep_ty loc env ty kr_ok = function
+(* The [?fundef] parameter is true if we're elaborating a function definition
+ and false otherwise. When [fundef = true], K&R function declarators
+ are allowed, and the returned environment includes bindings for the
+ function parameters and the struct/unions they may define.
+ When [fundef = false], K&R function declarators are rejected
+ and declarations in parameters are not returned. *)
+
+and elab_type_declarator ?(fundef = false) loc env ty = function
| Cabs.JUSTBASE ->
((ty, None), env)
| Cabs.ARRAY(d, cv_specs, sz) ->
let (ty, a) = get_nontype_attrs env ty in
let a = add_attributes a (elab_cvspecs env cv_specs) in
+ if wrap incomplete_type loc env ty then
+ error loc "array type has incomplete element type %a" (print_typ env) ty;
+ if wrap contains_flex_array_mem loc env ty then
+ warning loc Flexible_array_extensions "%a may not be used as an array element due to flexible array member" (print_typ env) ty;
let sz' =
match sz with
| None ->
@@ -666,33 +802,45 @@ and elab_type_declarator keep_ty loc env ty kr_ok = function
| None ->
error loc "size of array is not a compile-time constant";
Some 1L in (* produces better error messages later *)
- elab_type_declarator keep_ty loc env (TArray(ty, sz', a)) kr_ok d
+ elab_type_declarator ~fundef loc env (TArray(ty, sz', a)) d
| Cabs.PTR(cv_specs, d) ->
let (ty, a) = get_nontype_attrs env ty in
let a = add_attributes a (elab_cvspecs env cv_specs) in
- elab_type_declarator keep_ty loc env (TPtr(ty, a)) kr_ok d
+ if is_function_type env ty && incl_attributes [ARestrict] a then
+ error loc "pointer to function type %a may not be 'restrict' qualified" (print_typ env) ty;
+ elab_type_declarator ~fundef loc env (TPtr(ty, a)) d
| Cabs.PROTO(d, (params, vararg)) ->
elab_return_type loc env ty;
let (ty, a) = get_nontype_attrs env ty in
- let params',env' = elab_parameters keep_ty env params in
- let env = if keep_ty then Env.add_types env env' else env in
- elab_type_declarator keep_ty loc env (TFun(ty, Some params', vararg, a)) kr_ok d
+ let (params', env') = elab_parameters env params in
+ (* For a function declaration (fundef = false), the scope introduced
+ to treat parameters ends here, so we discard the extended
+ environment env' returned by elab_parameters.
+ For a function definition (fundef = true) we return the
+ extended environment env' so that it can serve as the basis
+ to elaborating the function body. *)
+ let env'' = if fundef then env' else env in
+ elab_type_declarator ~fundef loc env'' (TFun(ty, Some params', vararg, a)) d
| Cabs.PROTO_OLD(d, params) ->
elab_return_type loc env ty;
let (ty, a) = get_nontype_attrs env ty in
+ (* For consistency with the PROTO case above, for a function definition
+ (fundef = true) we open a new scope, even though we do not
+ add any bindings for the parameters. *)
+ let env'' = if fundef then Env.new_scope env else env in
match params with
| [] ->
- elab_type_declarator keep_ty loc env (TFun(ty, None, false, a)) kr_ok d
+ elab_type_declarator ~fundef loc env'' (TFun(ty, None, false, a)) d
| _ ->
- if not kr_ok || d <> Cabs.JUSTBASE then
+ if not fundef || d <> Cabs.JUSTBASE then
fatal_error loc "illegal old-style K&R function definition";
- ((TFun(ty, None, false, a), Some params), env)
+ ((TFun(ty, None, false, a), Some params), env'')
(* Elaboration of parameters in a prototype *)
-and elab_parameters keep_ty env params =
+and elab_parameters env params =
(* Prototype introduces a new scope *)
- let (vars, env) = mmap (elab_parameter keep_ty) (Env.new_scope env) params in
+ let (vars, env) = mmap elab_parameter (Env.new_scope env) params in
(* Catch special case f(t) where t is void or a typedef to void *)
match vars with
| [ ( {C.name=""}, t) ] when is_void_type env t -> [],env
@@ -700,42 +848,62 @@ and elab_parameters keep_ty env params =
(* Elaboration of a function parameter *)
-and elab_parameter keep_ty env (PARAM (spec, id, decl, attr, loc)) =
- let (sto, inl, noret, tydef, bty, env1) = elab_specifier keep_ty loc env spec in
+and elab_parameter env (PARAM (spec, id, decl, attr, loc)) =
+ let (sto, inl, noret, tydef, bty, env1) = elab_specifier loc env spec in
if tydef then
error loc "'typedef' used in function parameter";
- let ((ty, _), _) = elab_type_declarator keep_ty loc env1 bty false decl in
+ let ((ty, _), _) = elab_type_declarator loc env1 bty decl in
let ty = add_attributes_type (elab_attributes env attr) ty in
if sto <> Storage_default && sto <> Storage_register then
- error loc
- "invalid storage-class specifier in function declarator";
+ error loc (* NB: 'auto' not allowed *)
+ "invalid storage class %s for function parameter"
+ (name_of_storage_class sto);
if inl then
error loc "'inline' can only appear on functions";
if noret then
error loc "'_Noreturn' can only appear on functions";
let id = match id with None -> "" | Some id -> id in
+ if id <> "" && is_void_type env1 ty then
+ error loc "argument '%s' may not have 'void' type" id;
if id <> "" && redef Env.lookup_ident env id then
error loc "redefinition of parameter '%s'" id;
(* replace array and function types by pointer types *)
let ty1 = argument_conversion env1 ty in
+ if is_qualified_array ty1 then
+ error loc "type qualifier used in non-outermost array type derivation";
+ if has_std_alignas env ty then begin
+ if id <> "" then
+ error loc "alignment specified for parameter '%s'" id
+ else
+ error loc "alignment specified for unnamed parameter"
+ end;
let (id', env2) = Env.enter_ident env1 id sto ty1 in
( (id', ty1) , env2)
-(* Elaboration of a (specifier, Cabs "name") pair *)
-
-and elab_fundef_name keep_ty env spec (Name (id, decl, attr, loc)) =
- let (sto, inl, noret, tydef, bty, env') = elab_specifier keep_ty loc env spec in
+(* Elaboration of a (specifier, Cabs "name") pair as found in a function
+ definition. Returns two environments: the first is [env]
+ enriched with struct/union definitions from the return type,
+ as usual; the second is like the first, plus a new scope.
+ For a prototyped function ([kr_params = None]) the new scope
+ includes bindings for the function parameters and the struct/unions
+ they may define. For a K&R function ([kr_params <> None]) the new
+ scope is empty. *)
+
+and elab_fundef_name env spec (Name (s, decl, attr, loc)) =
+ let (sto, inl, noret, tydef, bty, env') = elab_specifier loc env spec in
if tydef then
error loc "'typedef' is forbidden here";
- let ((ty, kr_params), env'') = elab_type_declarator keep_ty loc env' bty true decl in
+ let id = Env.fresh_ident s in
+ let ((ty, kr_params), env'') =
+ elab_type_declarator ~fundef:true loc env' bty decl in
let a = elab_attributes env attr in
- (id, sto, inl, noret, add_attributes_type a ty, kr_params, env'')
+ (id, sto, inl, noret, add_attributes_type a ty, kr_params, env', env'')
(* Elaboration of a name group. C99 section 6.7.6 *)
-and elab_name_group keep_ty loc env (spec, namelist) =
+and elab_name_group loc env (spec, namelist) =
let (sto, inl, noret, tydef, bty, env') =
- elab_specifier keep_ty loc env spec in
+ elab_specifier loc env spec in
if tydef then
error loc "'typedef' is forbidden here";
if inl then
@@ -744,35 +912,40 @@ and elab_name_group keep_ty loc env (spec, namelist) =
error loc "'_Noreturn' is forbidden here";
let elab_one_name env (Name (id, decl, attr, loc)) =
let ((ty, _), env1) =
- elab_type_declarator keep_ty loc env bty false decl in
+ elab_type_declarator loc env bty decl in
let a = elab_attributes env attr in
((id, add_attributes_type a ty), env1) in
(mmap elab_one_name env' namelist, sto)
(* Elaboration of an init-name group *)
-and elab_init_name_group keep_ty loc env (spec, namelist) =
+and elab_init_name_group loc env (spec, namelist) =
let (sto, inl, noret, tydef, bty, env') =
- elab_specifier keep_ty ~only:(namelist=[]) loc env spec in
+ elab_specifier ~only:(namelist=[]) loc env spec in
+ if noret && tydef then
+ error loc "'_Noreturn' can only appear on functions";
let elab_one_name env (Init_name (Name (id, decl, attr, loc), init)) =
let ((ty, _), env1) =
- elab_type_declarator keep_ty loc env bty false decl in
+ elab_type_declarator loc env bty decl in
let a = elab_attributes env attr in
- if inl && not (is_function_type env ty) then
+ let has_fun_typ = is_function_type env ty in
+ if inl && not has_fun_typ then
error loc "'inline' can only appear on functions";
let a' =
if noret then begin
warning loc Celeven_extension "_Noreturn functions are a C11 extension";
- if not (is_function_type env ty) then
+ if not has_fun_typ then
error loc "'_Noreturn' can only appear on functions";
add_attributes [Attr("noreturn",[])] a
end else a in
+ if has_std_alignas env ty && has_fun_typ then
+ error loc "alignment specified for function '%s'" id;
((id, add_attributes_type a' ty, init), env1) in
(mmap elab_one_name env' namelist, sto, tydef)
(* Elaboration of a field group *)
-and elab_field_group keep_ty env (Field_group (spec, fieldlist, loc)) =
+and elab_field_group env (Field_group (spec, fieldlist, loc)) =
let fieldlist = List.map
(function (None, x) -> (Name ("", JUSTBASE, [], loc), x)
@@ -781,7 +954,7 @@ and elab_field_group keep_ty env (Field_group (spec, fieldlist, loc)) =
in
let ((names, env'), sto) =
- elab_name_group keep_ty loc env (spec, List.map fst fieldlist) in
+ elab_name_group loc env (spec, List.map fst fieldlist) in
if sto <> Storage_default then
error loc "non-default storage in struct or union";
@@ -789,10 +962,10 @@ and elab_field_group keep_ty env (Field_group (spec, fieldlist, loc)) =
(* This should actually never be triggered, empty structs are captured earlier *)
warning loc Missing_declarations "declaration does not declare anything";
- let elab_bitfield (Name (_, _, _, loc), optbitsize) (id, ty) =
- let optbitsize' =
+ let elab_bitfield env (Name (_, _, _, loc), optbitsize) (id, ty) =
+ let optbitsize',env' =
match optbitsize with
- | None -> None
+ | None -> None,env
| Some sz ->
let ik =
match unroll env' ty with
@@ -802,40 +975,45 @@ and elab_field_group keep_ty env (Field_group (spec, fieldlist, loc)) =
if integer_rank ik > integer_rank IInt then begin
error loc
"the type of bit-field '%a' must be an integer type no bigger than 'int'" pp_field id;
- None
+ None,env
+ end else if has_std_alignas env' ty then begin
+ error loc "alignment specified for bit-field '%a'" pp_field id;
+ None, env
end else begin
let expr,env' =(!elab_expr_f loc env sz) in
match Ceval.integer_expr env' expr with
| Some n ->
if n < 0L then begin
error loc "bit-field '%a' has negative width (%Ld)" pp_field id n;
- None
+ None,env
end else
let max = Int64.of_int(sizeof_ikind ik * 8) in
if n > max then begin
error loc "size of bit-field '%a' (%Ld bits) exceeds its type (%Ld bits)" pp_field id n max;
- None
+ None,env
end else
if n = 0L && id <> "" then begin
error loc "named bit-field '%a' has zero width" pp_field id;
- None
+ None,env
end else
- Some(Int64.to_int n)
+ Some(Int64.to_int n),env'
| None ->
error loc "bit-field '%a' width not an integer constant" pp_field id;
- None
+ None,env
end in
+ if is_qualified_array ty then
+ error loc "type qualifier used in array declarator outside of function prototype";
let anon_composite = is_anonymous_composite ty in
if id = "" && not anon_composite && optbitsize = None then
warning loc Missing_declarations "declaration does not declare anything";
- { fld_name = id; fld_typ = ty; fld_bitfield = optbitsize'; fld_anonymous = id = "" && anon_composite}
+ { fld_name = id; fld_typ = ty; fld_bitfield = optbitsize'; fld_anonymous = id = "" && anon_composite},env'
in
- (List.map2 elab_bitfield fieldlist names, env')
+ (mmap2 elab_bitfield env' fieldlist names)
(* Elaboration of a struct or union. C99 section 6.7.2.1 *)
-and elab_struct_or_union_info keep_ty kind loc env members attrs =
- let (m, env') = mmap (elab_field_group keep_ty) env members in
+and elab_struct_or_union_info kind loc env members attrs =
+ let (m, env') = mmap elab_field_group env members in
let m = List.flatten m in
let m,_ = mmap (fun c fld ->
if fld.fld_anonymous then
@@ -866,16 +1044,22 @@ and elab_struct_or_union_info keep_ty kind loc env members attrs =
duplicate acc rest in
duplicate [] m;
(* Check for incomplete types *)
- let rec check_incomplete = function
+ let rec check_incomplete only = function
| [] -> ()
- | [ { fld_typ = TArray(ty_elt, None, _) } ] when kind = Struct -> ()
- (* C99: ty[] allowed as last field of a struct *)
+ | [ { fld_typ = TArray(ty_elt, None, _) as typ; fld_name = name } ] when kind = Struct ->
+ (* C99: ty[] allowed as last field of a struct, provided this is not the only field *)
+ if only then
+ error loc "flexible array member '%a' not allowed in otherwise empty struct" pp_field name;
+ check_reduced_alignment loc env' typ
| fld :: rem ->
if wrap incomplete_type loc env' fld.fld_typ then
(* Must be fatal otherwise we get problems constructing the init *)
fatal_error loc "member '%a' has incomplete type" pp_field fld.fld_name;
- check_incomplete rem in
- check_incomplete m;
+ if wrap contains_flex_array_mem loc env' fld.fld_typ && kind = Struct then
+ warning loc Flexible_array_extensions "%a may not be used as a struct member due to flexible array member" (print_typ env) fld.fld_typ;
+ check_reduced_alignment loc env' fld.fld_typ;
+ check_incomplete false rem in
+ check_incomplete true m;
(* Warn for empty structs or unions *)
if m = [] then
if kind = Struct then begin
@@ -883,16 +1067,26 @@ and elab_struct_or_union_info keep_ty kind loc env members attrs =
end else begin
fatal_error loc "empty union is a GNU extension"
end;
+ let ci = composite_info_def env' kind attrs m in
+ (* Warn for reduced alignment *)
+ if attrs <> [] then begin
+ let ci_nat = composite_info_def env' kind [] m in
+ warn_if_reduced_alignment loc
+ ~actual:ci.Env.ci_alignof ~natural:ci_nat.Env.ci_alignof
+ end;
+ (* Final result *)
(composite_info_def env' kind attrs m, env')
-and elab_struct_or_union keep_ty only kind loc tag optmembers attrs env =
+and elab_struct_or_union only kind loc tag optmembers attrs env =
let warn_attrs () =
if attrs <> [] then
- warning loc Unnamed "attribute declaration must precede definition" in
+ warning loc Ignored_attributes "attribute declaration must precede definition" in
let optbinding, tag =
match tag with
| None -> None, ""
| Some s ->
+ if redef Env.lookup_enum env s then
+ error loc "'%s' redeclared as different kind of symbol" s;
Env.lookup_composite env s, s
in
match optbinding, optmembers with
@@ -910,9 +1104,9 @@ and elab_struct_or_union keep_ty only kind loc tag optmembers attrs env =
| Some(tag', ({Env.ci_sizeof = None} as ci)), Some members
when Env.in_current_scope env tag' ->
if ci.Env.ci_kind <> kind then
- error loc "use of '%s' with tag type that does not match previous declaration" tag;
+ fatal_error loc "use of '%s' with tag type that does not match previous declaration" tag;
(* finishing the definition of an incomplete struct or union *)
- let (ci', env') = elab_struct_or_union_info keep_ty kind loc env members attrs in
+ let (ci', env') = elab_struct_or_union_info kind loc env members attrs in
(* Emit a global definition for it *)
emit_elab env' loc (Gcompositedef(kind, tag', attrs, ci'.Env.ci_members));
(* Replace infos but keep same ident *)
@@ -939,7 +1133,7 @@ and elab_struct_or_union keep_ty only kind loc tag optmembers attrs env =
emit_elab env' loc (Gcompositedecl(kind, tag', attrs));
(* elaborate the members *)
let (ci2, env'') =
- elab_struct_or_union_info keep_ty kind loc env' members attrs in
+ elab_struct_or_union_info kind loc env' members attrs in
(* emit a definition *)
emit_elab env'' loc (Gcompositedef(kind, tag', attrs, ci2.Env.ci_members));
(* Replace infos but keep same ident *)
@@ -965,7 +1159,7 @@ and elab_enum_item env ((s, exp), loc) nextval =
if redef Env.lookup_typedef env s then
error loc "'%s' redeclared as different kind of symbol" s;
if not (int_representable v (8 * sizeof_ikind enum_ikind) (is_signed_ikind enum_ikind)) then
- warning loc Constant_conversion "integer literal '%Ld' is too large to be represented in any integer type"
+ warning loc Constant_conversion "integer literal '%Ld' is too large to be represented in the enumeration integer type"
v;
let (id, env') = Env.enter_enum_item env s v in
((id, v, exp'), Int64.succ v, env')
@@ -973,10 +1167,15 @@ and elab_enum_item env ((s, exp), loc) nextval =
(* Elaboration of an enumeration declaration. C99 section 6.7.2.2 *)
and elab_enum only loc tag optmembers attrs env =
- let tag = match tag with None -> "" | Some s -> s in
+ let tag = match tag with
+ | None -> ""
+ | Some s ->
+ if redef Env.lookup_struct env s || redef Env.lookup_union env s then
+ error loc "'%s' redeclared as different kind of symbol" s;
+ s in
match optmembers with
| None ->
- if only then
+ if only && not (redef Env.lookup_enum env tag) then
fatal_error loc
"forward declaration of 'enum %s' is not allowed in ISO C" tag;
let (tag', info) = wrap Env.lookup_enum loc env tag in (tag', env)
@@ -998,10 +1197,12 @@ and elab_enum only loc tag optmembers attrs env =
(* Elaboration of a naked type, e.g. in a cast *)
let elab_type loc env spec decl =
- let (sto, inl, noret, tydef, bty, env') = elab_specifier false loc env spec in
- let ((ty, _), env'') = elab_type_declarator false loc env' bty false decl in
+ let (sto, inl, noret, tydef, bty, env') = elab_specifier loc env spec in
+ let ((ty, _), env'') = elab_type_declarator loc env' bty decl in
+ (* NB: it seems the parser doesn't accept any of the specifiers below.
+ We keep the error message as extra safety. *)
if sto <> Storage_default || inl || noret || tydef then
- error loc "'typedef', 'extern', 'static', 'register' and 'inline' are meaningless in cast";
+ error loc "'typedef', 'extern', 'static', 'auto', 'register' and 'inline' are meaningless in cast";
(ty, env'')
@@ -1040,11 +1241,11 @@ let check_init_type loc env a ty =
else if wrap2 valid_cast loc env a.etyp ty then
if wrap2 int_pointer_conversion loc env a.etyp ty then
warning loc Int_conversion
- "incompatible integer-pointer conversion initializer has type %a instead of the expected type %a"
+ "incompatible integer-pointer conversion: initializer has type %a instead of the expected type %a"
(print_typ env) a.etyp (print_typ env) ty
else
warning loc Unnamed
- "incompatible conversion initializer has type %a instead of the expected type %a"
+ "incompatible conversion: initializer has type %a instead of the expected type %a"
(print_typ env) a.etyp (print_typ env) ty
else
error loc
@@ -1087,6 +1288,9 @@ module I = struct
(* Change the initializer for the current point *)
let set (z, i) i' = (z, i')
+ (* Is the current point at top? *)
+ let at_top = function Ztop(_, _), _ -> true | _, _ -> false
+
(* Put the current point back to the top *)
let rec to_top = function
| Ztop(name, ty), i as zi -> zi
@@ -1372,7 +1576,13 @@ and elab_single zi a il =
from the expression: do as above *)
elab_list (I.set zi (Init_single a)) il false
| TStruct _ | TUnion _ | TArray _ ->
- (* This is an aggregate: we need to drill into it, recursively *)
+ (* This is an aggregate.
+ At top, explicit { } are required. *)
+ if I.at_top zi then begin
+ error loc "invalid initializer, an initializer list was expected";
+ raise Exit
+ end;
+ (* Otherwise we need to drill into the aggregate, recursively *)
begin match I.first env zi with
| I.OK zi' ->
elab_single zi' a il
@@ -1434,23 +1644,51 @@ let elab_initializer loc env root ty ie =
(fixup_typ loc env ty init, Some init)
+(* Contexts for elaborating statements and expressions *)
+
+type elab_context = {
+ ctx_return_typ: typ; (**r return type for the function *)
+ ctx_labels: StringSet.t; (**r all labels defined in the function *)
+ ctx_break: bool; (**r is 'break' allowed? *)
+ ctx_continue: bool; (**r is 'continue' allowed? *)
+ ctx_in_switch: bool; (**r are 'case' and 'default' allowed? *)
+ ctx_vararg: bool; (**r is this a vararg function? *)
+ ctx_nonstatic_inline: bool (**r is this a nonstatic inline function? *)
+}
+
+(* Context for evaluating compile-time constant expressions.
+ Only the [ctx_vararg] and [ctx_nonstatic_inline] fields matter. *)
+let ctx_constexp = {
+ ctx_return_typ = TVoid [];
+ ctx_labels = StringSet.empty;
+ ctx_break = false; ctx_continue = false; ctx_in_switch = false;
+ ctx_vararg = false; ctx_nonstatic_inline = false
+}
+
+
(* Elaboration of expressions *)
-let elab_expr vararg loc env a =
+let elab_expr ctx loc env a =
- let err fmt = error loc fmt in (* non-fatal error *)
- let error fmt = fatal_error loc fmt in
- let warning t fmt =
- warning loc t fmt in
+ let error fmt = error loc fmt in
+ let fatal_error fmt = fatal_error loc fmt in
+ let warning t fmt = warning loc t fmt in
let check_ptr_arith env ty s =
match unroll env ty with
| TVoid _ ->
- err "illegal arithmetic on a pointer to void in binary '%c'" s
+ error "illegal arithmetic on a pointer to void in binary '%c'" s
| TFun _ ->
- err "illegal arithmetic on a pointer to the function type %a in binary '%c'" (print_typ env) ty s
+ error "illegal arithmetic on a pointer to the function type %a in binary '%c'" (print_typ env) ty s
| _ -> if incomplete_type env ty then
- err "arithmetic on a pointer to an incomplete type %a in binary '%c'" (print_typ env) ty s
+ error "arithmetic on a pointer to an incomplete type %a in binary '%c'" (print_typ env) ty s
+ in
+
+ let check_static_var id sto ty =
+ if ctx.ctx_nonstatic_inline
+ && sto = Storage_static
+ && List.mem AConst (attributes_of_type env ty)
+ then warning Static_in_inline "static variable '%s' is used in an inline function with external linkage" id.C.name
in
let rec elab env = function
@@ -1459,7 +1697,8 @@ let elab_expr vararg loc env a =
| VARIABLE s ->
begin match wrap Env.lookup_ident loc env s with
- | (id, Env.II_ident(sto, ty)) ->
+ | (id, Env.II_ident(sto, ty)) ->
+ check_static_var id sto ty;
{ edesc = EVar id; etyp = ty },env
| (id, Env.II_enum v) ->
{ edesc = EConst(CEnum(id, v)); etyp = TInt(enum_ikind, []) },env
@@ -1478,7 +1717,7 @@ let elab_expr vararg loc env a =
match (unroll env b1.etyp, unroll env b2.etyp) with
| (TPtr(t, _) | TArray(t, _, _)), (TInt _ | TEnum _) -> t
| (TInt _ | TEnum _), (TPtr(t, _) | TArray(t, _, _)) -> t
- | t1, t2 -> error "subscripted value is neither an array nor pointer" in
+ | t1, t2 -> fatal_error "subscripted value is neither an array nor pointer" in
{ edesc = EBinop(Oindex, b1, b2, TPtr(tres, [])); etyp = tres },env
| MEMBEROF(a1, fieldname) ->
@@ -1490,7 +1729,7 @@ let elab_expr vararg loc env a =
| TUnion(id, attrs) ->
(wrap Env.find_union_member loc env (id, fieldname), attrs)
| _ ->
- error "request for member '%s' in something not a structure or union" fieldname in
+ fatal_error "request for member '%s' in something not a structure or union" fieldname in
(* A field of a const/volatile struct or union is itself const/volatile *)
let rec access = function
| [] -> b1
@@ -1512,10 +1751,10 @@ let elab_expr vararg loc env a =
| TUnion(id, attrs) ->
(wrap Env.find_union_member loc env (id, fieldname), attrs)
| _ ->
- error "request for member '%s' in something not a structure or union" fieldname
+ fatal_error "request for member '%s' in something not a structure or union" fieldname
end
| _ ->
- error "member reference type %a is not a pointer" (print_typ env) b1.etyp in
+ fatal_error "member reference type %a is not a pointer" (print_typ env) b1.etyp in
let rec access = function
| [] -> assert false
| [fld] ->
@@ -1538,8 +1777,8 @@ let elab_expr vararg loc env a =
(elaboration) --> __builtin_va_arg(ap, sizeof(ty))
*)
| CALL((VARIABLE "__builtin_va_start" as a1), [a2; a3]) ->
- if not vararg then
- err "'va_start' used in function with fixed args";
+ if not ctx.ctx_vararg then
+ error "'va_start' used in function with fixed args";
let b1,env = elab env a1 in
let b2,env = elab env a2 in
let _b3,env = elab env a3 in
@@ -1584,9 +1823,9 @@ let elab_expr vararg loc env a =
| TPtr(ty, a) ->
begin match unroll env ty with
| TFun(res, args, vararg, a) -> (res, args, vararg)
- | _ -> error "called object type %a is neither a function nor function pointer" (print_typ env) b1.etyp
+ | _ -> fatal_error "called object type %a is neither a function nor function pointer" (print_typ env) b1.etyp
end
- | _ -> error "called object type %a is neither a function nor function pointer" (print_typ env) b1.etyp
+ | _ -> fatal_error "called object type %a is neither a function nor function pointer" (print_typ env) b1.etyp
in
(* Type-check the arguments against the prototype *)
let bl',env =
@@ -1608,18 +1847,18 @@ let elab_expr vararg loc env a =
if not (wrap2 valid_cast loc env b1.etyp ty) then
begin match unroll env b1.etyp, unroll env ty with
| _, (TStruct _|TUnion _ | TVoid _) ->
- err "used type %a where arithmetic or pointer type is required"
+ error "used type %a where arithmetic or pointer type is required"
(print_typ env) ty
| (TStruct _| TUnion _ | TVoid _),_ ->
- err "operand of type %a where arithmetic or pointer type is required"
+ error "operand of type %a where arithmetic or pointer type is required"
(print_typ env) b1.etyp
| TFloat _, TPtr _ ->
- err "operand of type %a cannot be cast to a pointer type"
+ error "operand of type %a cannot be cast to a pointer type"
(print_typ env) b1.etyp
| TPtr _ , TFloat _ ->
- err "pointer cannot be cast to type %a" (print_typ env) ty
+ error "pointer cannot be cast to type %a" (print_typ env) ty
| _ ->
- err "illegal cast from %a to %a" (print_typ env) b1.etyp (print_typ env) ty
+ error "illegal cast from %a to %a" (print_typ env) b1.etyp (print_typ env) ty
end;
{ edesc = ECast(ty, b1); etyp = ty },env
@@ -1629,7 +1868,7 @@ let elab_expr vararg loc env a =
let (ty, env) = elab_type loc env spec dcl in
begin match elab_initializer loc env "<compound literal>" ty ie with
| (ty', Some i) -> { edesc = ECompound(ty', i); etyp = ty' },env
- | (ty', None) -> error "ill-formed compound literal"
+ | (ty', None) -> fatal_error "ill-formed compound literal"
end
(* 6.5.3 Unary expressions *)
@@ -1637,54 +1876,39 @@ let elab_expr vararg loc env a =
| EXPR_SIZEOF a1 ->
let b1,env = elab env a1 in
if wrap incomplete_type loc env b1.etyp then
- error "invalid application of 'sizeof' to an incomplete type %a" (print_typ env) b1.etyp;
+ fatal_error "invalid application of 'sizeof' to an incomplete type %a" (print_typ env) b1.etyp;
if wrap is_bitfield loc env b1 then
- error "invalid application of 'sizeof' to a bit-field";
- 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(), []) },env
+ fatal_error "invalid application of 'sizeof' to a bit-field";
+ { edesc = ESizeof b1.etyp; etyp = TInt(size_t_ikind(), []) },env
| TYPE_SIZEOF (spec, dcl) ->
let (ty, env') = elab_type loc env spec dcl in
if wrap incomplete_type loc env' ty then
- error "invalid application of 'sizeof' to an incomplete type %a" (print_typ env) ty;
+ fatal_error "invalid application of 'sizeof' to an incomplete type %a" (print_typ env) ty;
{ edesc = ESizeof ty; etyp = TInt(size_t_ikind(), []) },env'
- | EXPR_ALIGNOF a1 ->
- let b1,env = elab env a1 in
- if wrap incomplete_type loc env b1.etyp then
- error "invalid application of '_Alignof' to an incomplete type %a" (print_typ env) b1.etyp;
- if wrap is_bitfield loc env b1 then
- error "invalid application of '_Alignof' to a bit-field";
- { edesc = EAlignof b1.etyp; etyp = TInt(size_t_ikind(), []) },env
-
- | TYPE_ALIGNOF (spec, dcl) ->
+ | ALIGNOF (spec, dcl) ->
let (ty, env') = elab_type loc env spec dcl in
+ warning Celeven_extension "'_Alignof' is a C11 extension";
if wrap incomplete_type loc env' ty then
- error "invalid application of 'alignof' to an incomplete type %a" (print_typ env) ty;
+ fatal_error "invalid application of 'alignof' to an incomplete type %a" (print_typ env) ty;
{ edesc = EAlignof ty; etyp = TInt(size_t_ikind(), []) },env'
| BUILTIN_OFFSETOF ((spec,dcl), mem) ->
let (ty,env) = elab_type loc env spec dcl in
if incomplete_type env ty then
- error "offsetof of incomplete type %a" (print_typ env) ty;
+ fatal_error "offsetof of incomplete type %a" (print_typ env) ty;
let members env ty mem =
match ty with
| TStruct (id,_) -> wrap Env.find_struct_member loc env (id,mem)
| TUnion (id,_) -> wrap Env.find_union_member loc env (id,mem)
- | _ -> error "request for member '%s' in something not a structure or union" mem in
+ | _ -> fatal_error "request for member '%s' in something not a structure or union" mem in
let rec offset_of_list acc env ty = function
| [] -> acc,ty
- | fld::rest -> let off = offsetof env ty fld in
+ | fld::rest ->
+ if fld.fld_bitfield <> None then
+ fatal_error "cannot compute offset of bit-field '%s'" fld.fld_name;
+ let off = offsetof env ty fld in
offset_of_list (acc+off) env fld.fld_typ rest in
let offset_of_member (env,off_accu,ty) mem =
match mem,unroll env ty with
@@ -1696,16 +1920,16 @@ let elab_expr vararg loc env a =
| ATINDEX_INIT e,TArray (sub_ty,_,_) ->
let e,env = elab env e in
let e = match Ceval.integer_expr env e with
- | None -> error "array element designator for is not an integer constant expression"
+ | None -> fatal_error "array element designator is not an integer constant expression"
| Some n-> n in
let size = match sizeof env sub_ty with
| None -> assert false (* We expect only complete types *)
| Some s -> s in
let off_accu = match cautious_mul e size with
- | None -> error "'offsetof' overflows"
+ | None -> fatal_error "'offsetof' overflows"
| Some s -> off_accu + s in
env,off_accu,sub_ty
- | ATINDEX_INIT _,_ -> error "subscripted value is not an array" in
+ | ATINDEX_INIT _,_ -> fatal_error "subscripted value is not an array" in
let env,offset,_ = List.fold_left offset_of_member (env,0,ty) mem in
let size_t = size_t_ikind () in
let offset = Ceval.normalize_int (Int64.of_int offset) size_t in
@@ -1715,46 +1939,46 @@ let elab_expr vararg loc env a =
| UNARY(PLUS, a1) ->
let b1,env = elab env a1 in
if not (is_arith_type env b1.etyp) then
- error "invalid argument type %a to unary '+'" (print_typ env) b1.etyp;
+ fatal_error "invalid argument type %a to unary '+'" (print_typ env) b1.etyp;
{ edesc = EUnop(Oplus, b1); etyp = unary_conversion env b1.etyp },env
| UNARY(MINUS, a1) ->
let b1,env = elab env a1 in
if not (is_arith_type env b1.etyp) then
- error "invalid argument type %a to unary '-'" (print_typ env) b1.etyp;
+ fatal_error "invalid argument type %a to unary '-'" (print_typ env) b1.etyp;
{ edesc = EUnop(Ominus, b1); etyp = unary_conversion env b1.etyp },env
| UNARY(BNOT, a1) ->
let b1,env = elab env a1 in
if not (is_integer_type env b1.etyp) then
- error "invalid argument type %a to unary '~'" (print_typ env) b1.etyp;
+ fatal_error "invalid argument type %a to unary '~'" (print_typ env) b1.etyp;
{ edesc = EUnop(Onot, b1); etyp = unary_conversion env b1.etyp },env
| UNARY(NOT, a1) ->
let b1,env = elab env a1 in
if not (is_scalar_type env b1.etyp) then
- error "invalid argument type %a to unary '!'" (print_typ env) b1.etyp;
+ fatal_error "invalid argument type %a to unary '!'" (print_typ env) b1.etyp;
{ edesc = EUnop(Olognot, b1); etyp = TInt(IInt, []) },env
| UNARY(ADDROF, a1) ->
let b1,env = elab env a1 in
if not (is_lvalue b1 || is_function_type env b1.etyp) then
- err "argument of '&' is not an lvalue (invalid %a)" (print_typ env) b1.etyp;
+ error "argument of '&' is not an lvalue (invalid %a)" (print_typ env) b1.etyp;
begin match b1.edesc with
| EVar id ->
begin match wrap Env.find_ident loc env id with
| Env.II_ident(Storage_register, _) ->
- err "address of register variable '%s' requested" id.C.name
+ error "address of register variable '%s' requested" id.C.name
| _ -> ()
end
| EUnop(Odot f, b2) ->
let fld = wrap2 field_of_dot_access loc env b2.etyp f in
if fld.fld_bitfield <> None then
- err "address of bit-field '%s' requested" f
+ error "address of bit-field '%s' requested" f
| EUnop(Oarrow f, b2) ->
let fld = wrap2 field_of_arrow_access loc env b2.etyp f in
if fld.fld_bitfield <> None then
- err "address of bit-field '%s' requested" f
+ error "address of bit-field '%s' requested" f
| _ -> ()
end;
{ edesc = EUnop(Oaddrof, b1); etyp = TPtr(b1.etyp, []) },env
@@ -1767,7 +1991,7 @@ let elab_expr vararg loc env a =
| TPtr(ty, _) | TArray(ty, _, _) ->
{ edesc = EUnop(Oderef, b1); etyp = ty },env
| _ ->
- error "arguemnt of unary '*' is not a pointer (%a invalid)"
+ fatal_error "argument of unary '*' is not a pointer (%a invalid)"
(print_typ env) b1.etyp
end
@@ -1798,7 +2022,7 @@ let elab_expr vararg loc env a =
match unroll env b1.etyp, unroll env b2.etyp with
| (TPtr(ty, a) | TArray(ty, _, a)), (TInt _ | TEnum _) -> ty
| (TInt _ | TEnum _), (TPtr(ty, a) | TArray(ty, _, a)) -> ty
- | _, _ -> error "invalid operands to binary '+' (%a and %a)"
+ | _, _ -> fatal_error "invalid operands to binary '+' (%a and %a)"
(print_typ env) b1.etyp (print_typ env) b2.etyp
in
check_ptr_arith env ty '+';
@@ -1817,21 +2041,19 @@ let elab_expr vararg loc env a =
match wrap unroll loc env b1.etyp, wrap unroll loc env b2.etyp with
| (TPtr(ty, a) | TArray(ty, _, a)), (TInt _ | TEnum _) ->
if not (wrap pointer_arithmetic_ok loc env ty) then
- err "illegal pointer arithmetic in binary '-'";
- (TPtr(ty, []), TPtr(ty, []))
- | (TInt _ | TEnum _), (TPtr(ty, a) | TArray(ty, _, a)) ->
- check_ptr_arith env ty '-';
+ error "illegal pointer arithmetic in binary '-'";
(TPtr(ty, []), TPtr(ty, []))
| (TPtr(ty1, a1) | TArray(ty1, _, a1)),
(TPtr(ty2, a2) | TArray(ty2, _, a2)) ->
if not (compatible_types AttrIgnoreAll env ty1 ty2) then
- err "%a and %a are not pointers to compatible types"
+ error "%a and %a are not pointers to compatible types"
(print_typ env) b1.etyp (print_typ env) b1.etyp;
check_ptr_arith env ty1 '-';
+ check_ptr_arith env ty2 '-';
if wrap sizeof loc env ty1 = Some 0 then
- err "subtraction between two pointers to zero-sized objects";
+ error "subtraction between two pointers to zero-sized objects";
(TPtr(ty1, []), TInt(ptrdiff_t_ikind(), []))
- | _, _ -> error "invalid operands to binary '-' (%a and %a)"
+ | _, _ -> fatal_error "invalid operands to binary '-' (%a and %a)"
(print_typ env) b1.etyp (print_typ env) b2.etyp
end in
{ edesc = EBinop(Osub, b1, b2, tyop); etyp = tyres },env
@@ -1875,7 +2097,7 @@ let elab_expr vararg loc env a =
let b2,env = elab env a2 in
let b3,env = elab env a3 in
if not (is_scalar_type env b1.etyp) then
- err "first argument of '?:' is not a scalar type (invalid %a)"
+ error "first argument of '?:' is not a scalar type (invalid %a)"
(print_typ env) b1.etyp;
begin match pointer_decay env b2.etyp, pointer_decay env b3.etyp with
| (TInt _ | TFloat _ | TEnum _), (TInt _ | TFloat _ | TEnum _) ->
@@ -1903,7 +2125,7 @@ let elab_expr vararg loc env a =
| ty1, ty2 ->
match combine_types AttrIgnoreAll env ty1 ty2 with
| None ->
- error "the second and third argument of '?:' incompatible types (%a and %a)"
+ fatal_error "the second and third argument of '?:' incompatible types (%a and %a)"
(print_typ env) ty1 (print_typ env) ty2
| Some tyres ->
{ edesc = EConditional(b1, b2, b3); etyp = tyres },env
@@ -1917,7 +2139,7 @@ let elab_expr vararg loc env a =
if List.mem AConst (attributes_of_type env b1.etyp) then
error "left-hand side of assignment has 'const' type";
if not (is_modifiable_lvalue env b1) then
- err "expression is not assignable";
+ error "expression is not assignable";
if not (wrap2 valid_assignment loc env b2 b1.etyp) then begin
if wrap2 valid_cast loc env b2.etyp b1.etyp then
if wrap2 int_pointer_conversion loc env b2.etyp b1.etyp then
@@ -1926,10 +2148,10 @@ let elab_expr vararg loc env a =
(print_typ env) b1.etyp (print_typ env) b2.etyp
else
warning Unnamed
- "incompatible conversion assigning to %a from %a"
+ "incompatible conversion: assigning to %a from %a"
(print_typ env) b1.etyp (print_typ env) b2.etyp
else
- err "assigning to %a from incompatible type %a"
+ error "assigning to %a from incompatible type %a"
(print_typ env) b1.etyp (print_typ env) b2.etyp;
end;
{ edesc = EBinop(Oassign, b1, b2, b1.etyp); etyp = b1.etyp },env
@@ -1953,9 +2175,9 @@ let elab_expr vararg loc env a =
begin match elab env (BINARY(sop, a1, a2)) with
| ({ edesc = EBinop(_, b1, b2, _); etyp = ty } as b),env ->
if List.mem AConst (attributes_of_type env b1.etyp) then
- err "left-hand side of assignment has 'const' type";
+ error "left-hand side of assignment has 'const' type";
if not (is_modifiable_lvalue env b1) then
- err "expression is not assignable";
+ error "expression is not assignable";
if not (wrap2 valid_assignment loc env b b1.etyp) then begin
if wrap2 valid_cast loc env ty b1.etyp then
if wrap2 int_pointer_conversion loc env ty b1.etyp then
@@ -1964,10 +2186,10 @@ let elab_expr vararg loc env a =
(print_typ env) b1.etyp (print_typ env) ty
else
warning Unnamed
- "incompatible conversion assigning to %a from %a"
+ "incompatible conversion: assigning to %a from %a"
(print_typ env) b1.etyp (print_typ env) ty
else
- err "assigning to %a from incompatible type %a"
+ error "assigning to %a from incompatible type %a"
(print_typ env) b1.etyp (print_typ env) ty;
end;
{ edesc = EBinop(top, b1, b2, ty); etyp = b1.etyp },env
@@ -1986,9 +2208,9 @@ let elab_expr vararg loc env a =
and elab_pre_post_incr_decr op msg a1 =
let b1,env = elab env a1 in
if not (is_modifiable_lvalue env b1) then
- err "expression is not assignable";
+ error "expression is not assignable";
if not (is_scalar_type env b1.etyp) then
- err "cannot %s value of type %a" msg (print_typ env) b1.etyp;
+ error "cannot %s value of type %a" msg (print_typ env) b1.etyp;
{ edesc = EUnop(op, b1); etyp = b1.etyp },env
(* Elaboration of binary operators over integers *)
@@ -1996,7 +2218,7 @@ let elab_expr vararg loc env a =
let b1,env = elab env a1 in
let b2,env = elab env a2 in
if not ((is_integer_type env b1.etyp) && (is_integer_type env b2.etyp)) then
- error "invalid operands to binary '%s' (%a and %a)" msg
+ fatal_error "invalid operands to binary '%s' (%a and %a)" msg
(print_typ env) b1.etyp (print_typ env) b2.etyp;
let tyres = binary_conversion env b1.etyp b2.etyp in
{ edesc = EBinop(op, b1, b2, tyres); etyp = tyres },env
@@ -2006,7 +2228,7 @@ let elab_expr vararg loc env a =
let b1,env = elab env a1 in
let b2,env = elab env a2 in
if not ((is_arith_type env b1.etyp) && (is_arith_type env b2.etyp)) then
- error "invalid operands to binary '%s' (%a and %a)" msg
+ fatal_error "invalid operands to binary '%s' (%a and %a)" msg
(print_typ env) b1.etyp (print_typ env) b2.etyp;
let tyres = binary_conversion env b1.etyp b2.etyp in
{ edesc = EBinop(op, b1, b2, tyres); etyp = tyres },env
@@ -2016,7 +2238,7 @@ let elab_expr vararg loc env a =
let b1,env = elab env a1 in
let b2,env = elab env a2 in
if not ((is_integer_type env b1.etyp) && (is_integer_type env b2.etyp)) then
- error "invalid operands to '%s' (%a and %a)" msg
+ fatal_error "invalid operands to '%s' (%a and %a)" msg
(print_typ env) b1.etyp (print_typ env) b2.etyp;
let tyres = unary_conversion env b1.etyp in
{ edesc = EBinop(op, b1, b2, tyres); etyp = tyres },env
@@ -2043,6 +2265,10 @@ let elab_expr vararg loc env a =
if not (compatible_types AttrIgnoreAll env ty1 ty2) then
warning Compare_distinct_pointer_types "comparison of distinct pointer types (%a and %a)"
(print_typ env) b1.etyp (print_typ env) b2.etyp;
+ let incomp_ty1 = wrap incomplete_type loc env ty1
+ and incomp_ty2 = wrap incomplete_type loc env ty2 in
+ if incomp_ty1 <> incomp_ty2 then
+ warning Unnamed "comparison of complete and incomplete pointers";
EBinop(op, b1, b2, TPtr(ty1, []))
| TPtr _, (TInt _ | TEnum _)
| (TInt _ | TEnum _), TPtr _ ->
@@ -2050,7 +2276,7 @@ let elab_expr vararg loc env a =
(print_typ env) b1.etyp (print_typ env) b2.etyp;
EBinop(op, b1, b2, TPtr(TVoid [], []))
| ty1, ty2 ->
- error "illegal comparison between types@ %a@ and %a"
+ fatal_error "illegal comparison between types@ %a@ and %a"
(print_typ env) b1.etyp (print_typ env) b2.etyp; in
{ edesc = resdesc; etyp = TInt(IInt, []) },env
@@ -2059,7 +2285,7 @@ let elab_expr vararg loc env a =
let b1,env = elab env a1 in
let b2,env = elab env a2 in
if not ((is_scalar_type env b1.etyp) && (is_scalar_type env b2.etyp)) then
- error "invalid operands to binary %s (%a and %a)" msg
+ fatal_error "invalid operands to binary '%s' (%a and %a)" msg
(print_typ env) b1.etyp (print_typ env) b2.etyp;
{ edesc = EBinop(op, b1, b2, TInt(IInt, [])); etyp = TInt(IInt, []) },env
@@ -2071,14 +2297,14 @@ let elab_expr vararg loc env a =
let found = argno - 1 in
let expected = List.length params + found in
let vararg = if vararg then "at least " else "" in
- err "too few arguments to function call, expected %s%d, have %d" vararg expected found; [],env
+ error "too few arguments to function call, expected %s%d, have %d" vararg expected found; [],env
| (_::_,env), [] ->
if vararg
then args
else
let expected = argno - 1 in
let found = List.length (fst args) + expected in
- (err "too many arguments to function call, expected %d, have %d" expected found; args)
+ (error "too many arguments to function call, expected %d, have %d" expected found; args)
| (arg1 :: argl,env), (_, ty_p) :: paraml ->
let ty_a = argument_conversion env arg1.etyp in
if not (wrap2 valid_assignment loc env {arg1 with etyp = ty_a} ty_p)
@@ -2090,10 +2316,10 @@ let elab_expr vararg loc env a =
(print_typ env) ty_a argno (print_typ env) ty_p
else
warning Unnamed
- "incompatible conversion passing %a to parameter %d of type %a"
+ "incompatible conversion: passing %a to parameter %d of type %a"
(print_typ env) ty_a argno (print_typ env) ty_p end
else
- err
+ error
"passing %a to parameter %d of incompatible type %a"
(print_typ env) ty_a argno (print_typ env) ty_p
end;
@@ -2102,16 +2328,16 @@ let elab_expr vararg loc env a =
in elab env a
(* Filling in forward declaration *)
-let _ = elab_expr_f := (elab_expr false)
+let _ = elab_expr_f := (elab_expr ctx_constexp)
-let elab_opt_expr vararg loc env = function
+let elab_opt_expr ctx loc env = function
| None -> None,env
- | Some a -> let a,env = (elab_expr vararg loc env a) in
+ | Some a -> let a,env = (elab_expr ctx loc env a) in
Some a,env
-let elab_for_expr vararg loc env = function
+let elab_for_expr ctx loc env = function
| None -> { sdesc = Sskip; sloc = elab_loc loc },env
- | Some a -> let a,env = elab_expr vararg loc env a in
+ | Some a -> let a,env = elab_expr ctx loc env a in
{ sdesc = Sdo a; sloc = elab_loc loc },env
(* Handling of __func__ (section 6.4.2.2) *)
@@ -2125,49 +2351,69 @@ let __func__type_and_init s =
let enter_typedefs loc env sto dl =
if sto <> Storage_default then
- error loc "non-default storage-class on 'typedef' definition";
+ error loc "non-default storage class on 'typedef' definition";
+ if dl = [] then
+ warning loc Missing_declarations "typedef requires a name";
List.fold_left (fun env (s, ty, init) ->
if init <> NO_INIT then
error loc "initializer in typedef";
+ if has_std_alignas env ty then
+ error loc "alignment specified for typedef '%s'" s;
match previous_def Env.lookup_typedef env s with
- | Some (s',ty') ->
+ | Some (s',ty') when Env.in_current_scope env s' ->
if equal_types env ty ty' then begin
- warning loc Celeven_extension "redefinition of typedef '%s' is C11 extension" s;
+ warning loc Celeven_extension "redefinition of typedef '%s' is a C11 extension" s;
env
end else begin
error loc "typedef redefinition with different types (%a vs %a)"
(print_typ env) ty (print_typ env) ty';
env
end
- | None ->
+ | _ ->
if redef Env.lookup_ident env s then
error loc "redefinition of '%s' as different kind of symbol" s;
let (id, env') = Env.enter_typedef env s ty in
+ check_reduced_alignment loc env' ty;
emit_elab env loc (Gtypedef(id, ty));
env') env dl
-let enter_decdefs local loc env sto dl =
+let enter_decdefs local nonstatic_inline loc env sto dl =
(* Sanity checks on storage class *)
- if sto = Storage_register && not local then
- fatal_error loc "'register' storage-class on file-scoped variable";
+ if (sto = Storage_auto || sto = Storage_register) && not local then
+ fatal_error loc "illegal storage class %s on file-scoped variable"
+ (name_of_storage_class sto);
if sto <> Storage_default && dl = [] then
warning loc Missing_declarations "declaration does not declare anything";
let enter_decdef (decls, env) (s, ty, init) =
let isfun = is_function_type env ty in
+ if sto = Storage_register && has_std_alignas env ty then
+ error loc "alignment specified for 'register' object '%s'" s;
if sto = Storage_extern && init <> NO_INIT then
- error loc "'extern' declaration variable has an initializer";
+ error loc "'extern' declaration variable has an initializer";
if local && isfun then begin
match sto with
- | Storage_static -> error loc "function declared in block scope cannot have 'static' storage-class";
- | Storage_register -> error loc "invalid 'register' storage-class on function";
+ | Storage_static ->
+ error loc "function declared in block scope cannot have 'static' storage class"
+ | Storage_auto | Storage_register ->
+ error loc "illegal storage class %s on function"
+ (name_of_storage_class sto)
| _ -> ()
end;
- (* Local function declarations are always treated as extern *)
- let sto1 = if local && isfun then Storage_extern else sto in
+ if is_qualified_array ty then
+ error loc "type qualifier used in array declarator outside of function prototype";
+ (* Local variable declarations with default storage are treated as 'auto'.
+ Local function declarations with default storage remain with
+ default storage. *)
+ let sto1 =
+ if local && sto = Storage_default && not isfun
+ then Storage_auto
+ else sto in
(* enter ident in environment with declared type, because
initializer can refer to the ident *)
let (id, sto', env1, ty, linkage) =
enter_or_refine_ident local loc env s sto1 ty in
+ if init <> NO_INIT && not local then
+ add_global_define loc s;
if not isfun && is_void_type env ty then
fatal_error loc "'%s' has incomplete type" s;
(* process the initializer *)
@@ -2175,16 +2421,30 @@ let enter_decdefs local loc env sto dl =
(* update environment with refined type *)
let env2 = Env.add_ident env1 id sto' ty' in
(* check for incomplete type *)
- if local && sto' <> Storage_extern
- && not isfun
- && wrap incomplete_type loc env ty' then
- error loc "variable has incomplete type %a" (print_typ env) ty';
+ if not isfun && wrap incomplete_type loc env ty' then
+ if not local && sto' = Storage_static then begin
+ warning loc Tentative_incomplete_static "tentative static definition with incomplete type";
+ end else if local && sto' <> Storage_extern then
+ error loc "variable has incomplete type %a" (print_typ env) ty';
+ (* check if alignment is reduced *)
+ check_reduced_alignment loc env ty';
+ (* check for static variables in nonstatic inline functions *)
+ if local && nonstatic_inline
+ && sto' = Storage_static
+ && not (List.mem AConst (attributes_of_type env ty')) then
+ warning loc Static_in_inline "non-constant static local variable '%s' in inline function may be different in different files" s;
if local && not isfun && sto' <> Storage_extern && sto' <> Storage_static then
(* Local definition *)
((sto', id, ty', init') :: decls, env2)
else begin
(* Global definition *)
emit_elab ~linkage env2 loc (Gdecl(sto', id, ty', init'));
+ (* Make sure the initializer is constant. *)
+ begin match init' with
+ | Some i when not (Ceval.is_constant_init env2 i) ->
+ error loc "initializer is not a compile-time constant"
+ | _ -> ()
+ end;
(decls, env2)
end in
let (decls, env') = List.fold_left enter_decdef ([], env) dl in
@@ -2216,7 +2476,7 @@ let elab_KR_function_parameters env params defs loc =
(* Check that the declarations only declare parameters *)
let extract_name (Init_name(Name(s, dty, attrs, loc') as name, ie)) =
if not (List.mem s params) then
- error loc' "Declaration of '%s' which is not a function parameter" s;
+ error loc' "declaration of '%s' which is not a function parameter" s;
if ie <> NO_INIT then
error loc' "illegal initialization of parameter '%s'" s;
name
@@ -2225,18 +2485,17 @@ let elab_KR_function_parameters env params defs loc =
let elab_param_def env = function
| DECDEF((spec', name_init_list), loc') ->
let name_list = List.map extract_name name_init_list in
- let (paramsenv, sto) = elab_name_group true loc' env (spec', name_list) in
- begin match sto with
- | Storage_extern ->
- error loc' "invalid 'extern' storage-class specifier for function parameter"
- | Storage_static ->
- error loc' "invalid 'static' storage-class specifier for function parameter"
- | _ -> ()
- end;
+ if name_list = [] then
+ error loc' "declaration does not declare a parameter";
+ let (paramsenv, sto) = elab_name_group loc' env (spec', name_list) in
+ if sto <> Storage_default && sto <> Storage_register then
+ error loc' (* NB: 'auto' not allowed *)
+ "invalid storage class %s for function parameter"
+ (name_of_storage_class sto);
paramsenv
| d -> (* Should never be produced by the parser *)
fatal_error (Cabshelper.get_definitionloc d)
- "Illegal declaration of function parameter" in
+ "illegal declaration of function parameter" in
let kr_params_defs,paramsenv =
let params,paramsenv = mmap elab_param_def env defs in
List.concat params,paramsenv in
@@ -2296,11 +2555,22 @@ let inherit_vararg env s sto ty =
(* Function definitions *)
-let elab_fundef env spec name defs body loc =
- let (s, sto, inline, noret, ty, kr_params, env1) =
- elab_fundef_name true env spec name in
- if sto = Storage_register then
- fatal_error loc "invalid 'register' storage-class on function";
+let elab_fundef genv spec name defs body loc =
+ (* We maintain two environments:
+ - genv is the "global", file-scope environment. It is enriched
+ with the declaration of the function, and also with
+ structs and unions defined as part of its return type.
+ - lenv is the "local" environment used to elaborate the function body.
+ It contains everything that genv contains, including
+ a declaration for the function, so as to support recursive calls.
+ In addition, it contains declarations for function parameters
+ and structs and unions defined in the parameter list. *)
+ let (fun_id, sto, inline, noret, ty, kr_params, genv, lenv) =
+ elab_fundef_name genv spec name in
+ let s = fun_id.C.name in
+ if sto = Storage_auto || sto = Storage_register then
+ fatal_error loc "invalid storage class %s on function"
+ (name_of_storage_class sto);
begin match kr_params, defs with
| None, d::_ ->
error (Cabshelper.get_definitionloc d)
@@ -2310,54 +2580,77 @@ let elab_fundef env spec name defs body loc =
(* Process the parameters and the K&R declarations, if any, to obtain:
- [ty]: the full, prototyped type of the function
- [extra_decls]: extra declarations to be inserted at the
- beginning of the function *)
- let (ty, extra_decls,env1) =
+ beginning of the function
+ - [lenv]: a first cut at the local environment, containing in particular
+ the structs and unions defined in the parameter list. *)
+ let (ty, extra_decls, lenv) =
match ty, kr_params with
| TFun(ty_ret, None, vararg, attr), None ->
- (TFun(ty_ret, Some [], vararg, attr), [],env1)
+ (TFun(ty_ret, Some [], vararg, attr), [], lenv)
| ty, None ->
- (ty, [],env1)
+ (ty, [], lenv)
| TFun(ty_ret, None, false, attr), Some params ->
warning loc CompCert_conformance "non-prototype, pre-standard function definition, converting to prototype form";
- let (params', extra_decls,env) =
- elab_KR_function_parameters env params defs loc in
- (TFun(ty_ret, Some params', inherit_vararg env s sto ty, attr), extra_decls,env)
+ let (params', extra_decls, lenv) =
+ elab_KR_function_parameters lenv params defs loc in
+ (TFun(ty_ret, Some params', inherit_vararg genv s sto ty, attr), extra_decls, lenv)
| _, Some params ->
assert false
in
- (* Extract infos from the type of the function *)
+ (* Extract infos from the type of the function.
+ Checks on the return type must be done in the global environment. *)
let (ty_ret, params, vararg, attr) =
match ty with
| TFun(ty_ret, Some params, vararg, attr) ->
- if wrap incomplete_type loc env1 ty_ret && not (is_void_type env ty_ret) then
+ if has_std_alignas genv ty then
+ error loc "alignment specified for function '%s'" s;
+ if wrap incomplete_type loc genv ty_ret && not (is_void_type genv ty_ret) then
fatal_error loc "incomplete result type %a in function definition"
- (print_typ env) ty_ret;
+ (print_typ genv) ty_ret;
(ty_ret, params, vararg, attr)
| _ -> fatal_error loc "wrong type for function definition" in
- (* Enter function in the environment, for recursive references *)
- let (fun_id, sto1, env1, _, _) =
- enter_or_refine_ident false loc env1 s sto ty in
- let incomplete_param env ty =
+ (* Enter function in the global environment *)
+ let (fun_id, sto1, genv, new_ty, _) =
+ enter_or_refine_function loc genv fun_id sto ty in
+ add_global_define loc s;
+ (* Also enter it in the local environment, for recursive references *)
+ let lenv = Env.add_ident lenv fun_id sto new_ty in
+ (* Take into account attributes from previous declarations of the function *)
+ let attr = attributes_of_type genv new_ty in
+ (* Additional checks on function parameters. They should have a complete type
+ and additionally they should have an identifier. In both cases a fatal
+ error is raised in order to avoid problems at later places. *)
+ let add_param env (id, ty) =
if wrap incomplete_type loc env ty then
- fatal_error loc "parameter has incomplete type" in
- (* Enter parameters and extra declarations in the environment *)
- let env2 =
- List.fold_left (fun e (id, ty) -> incomplete_param e ty;
- Env.add_ident e id Storage_default ty)
- (Env.new_scope env1) params in
- let env2 =
+ fatal_error loc "parameter has incomplete type";
+ if id.C.name = "" then
+ fatal_error loc "parameter name omitted";
+ Env.add_ident env id Storage_default ty
+ in
+ (* Enter parameters and extra declarations in the local environment.
+ For K&R functions this hasn't been done yet.
+ For prototyped functions this has been done by [elab_fundef_name]
+ already, but some parameter may have been shadowed by the
+ function name, while it should be the other way around, e.g.
+ [int f(int f) { return f+1; }], with [f] refering to the
+ parameter [f] and not to the function [f] within the body of the
+ function. *)
+ let lenv =
+ List.fold_left add_param lenv params in
+ let lenv =
List.fold_left (fun e (sto, id, ty, init) -> Env.add_ident e id sto ty)
- env2 extra_decls in
- (* Define "__func__" and enter it in the environment *)
+ lenv extra_decls in
+ (* Define "__func__" and enter it in the local environment *)
let (func_ty, func_init) = __func__type_and_init s in
- let (func_id, _, env3, func_ty, _) =
- enter_or_refine_ident true loc env2 "__func__" Storage_static func_ty in
- emit_elab ~debuginfo:false env3 loc
+ let (func_id, _, lenv, func_ty, _) =
+ enter_or_refine_ident true loc lenv "__func__" Storage_static func_ty in
+ emit_elab ~debuginfo:false lenv loc
(Gdecl(Storage_static, func_id, func_ty, Some func_init));
(* Elaborate function body *)
- let body1 = !elab_funbody_f ty_ret vararg env3 body in
+ let body1 = !elab_funbody_f ty_ret vararg (inline && sto <> Storage_static)
+ lenv body in
(* Analyse it for returns *)
- let (can_return, can_fallthrough) = Cflow.function_returns env3 body1 in
+ let (can_return, can_fallthrough) = Cflow.function_returns lenv body1 in
(* Special treatment of the "main" function. *)
let body2 =
if s = "main" then begin
@@ -2365,7 +2658,7 @@ let elab_fundef env spec name defs body loc =
error loc "'main' is not allowed to be declared inline";
if noret then
warning loc Unnamed "'main' is not allowed to be declared _Noreturn";
- match unroll env ty_ret with
+ match unroll genv ty_ret with
| TInt(IInt, []) ->
(* Add implicit "return 0;" at end of function body.
If we trusted the return analysis, we would do this only if
@@ -2378,7 +2671,7 @@ let elab_fundef env spec name defs body loc =
end else begin
(* For non-"main" functions, warn if the body can fall through
and the return type is not "void". *)
- if can_fallthrough && not (is_void_type env ty_ret) then
+ if can_fallthrough && not (is_void_type genv ty_ret) then
warning loc Return_type "control reaches end of non-void function";
body1
end in
@@ -2407,12 +2700,13 @@ let elab_fundef env spec name defs body loc =
fd_vararg = vararg;
fd_locals = [];
fd_body = body3 } in
- emit_elab ~linkage:true env1 loc (Gfundef fn);
- env1
+ emit_elab ~linkage:true genv loc (Gfundef fn);
+ genv
(* Definitions *)
-let rec elab_definition (local: bool) (env: Env.t) (def: Cabs.definition)
+let elab_definition (for_loop: bool) (local: bool) (nonstatic_inline: bool)
+ (env: Env.t) (def: Cabs.definition)
: decl list * Env.t =
match def with
(* "int f(int x) { ... }" *)
@@ -2425,44 +2719,32 @@ let rec elab_definition (local: bool) (env: Env.t) (def: Cabs.definition)
(* "int x = 12, y[10], *z" *)
| DECDEF(init_name_group, loc) ->
let ((dl, env1), sto, tydef) =
- elab_init_name_group false loc env init_name_group in
+ elab_init_name_group loc env init_name_group in
+ if for_loop then begin
+ let fun_declaration = List.exists (fun (_, ty, _) -> is_function_type env ty) dl in
+ if fun_declaration || sto = Storage_extern || sto = Storage_static || tydef then
+ error loc "declaration of non-local variable in 'for' loop" ;
+ end;
if tydef then
let env2 = enter_typedefs loc env1 sto dl
in ([], env2)
else
- enter_decdefs local loc env1 sto dl
+ enter_decdefs local nonstatic_inline loc env1 sto dl
(* pragma *)
| PRAGMA(s, loc) ->
emit_elab env loc (Gpragma s);
([], env)
-and elab_definitions local env = function
- | [] -> ([], env)
- | d1 :: dl ->
- let (decl1, env1) = elab_definition local env d1 in
- let (decl2, env2) = elab_definitions local env1 dl in
- (decl1 @ decl2, env2)
-
(* Extended asm *)
-let elab_asm_operand vararg loc env (ASMOPERAND(label, wide, chars, e)) =
+let elab_asm_operand ctx loc env (ASMOPERAND(label, wide, chars, e)) =
let s = elab_simple_string loc wide chars in
- let e',env = elab_expr vararg loc env e in
+ let e',env = elab_expr ctx loc env e in
(label, s, e'),env
-(* Contexts for elaborating statements *)
-
-module StringSet = Set.Make(String)
-
-type stmt_context = {
- ctx_return_typ: typ; (**r return type for the function *)
- ctx_labels: StringSet.t; (**r all labels defined in the function *)
- ctx_break: bool; (**r is 'break' allowed? *)
- ctx_continue: bool; (**r is 'continue' allowed? *)
- ctx_vararg: bool; (**r is this a vararg function? *)
-}
+(* Operations over contexts *)
let stmt_labels stmt =
let lbls = ref StringSet.empty in
@@ -2487,7 +2769,48 @@ let stmt_labels stmt =
let ctx_loop ctx = { ctx with ctx_break = true; ctx_continue = true }
-let ctx_switch ctx = { ctx with ctx_break = true }
+let ctx_switch ctx = { ctx with ctx_break = true; ctx_in_switch = true }
+
+(* Check the uniqueness of 'case' and 'default' in a 'switch' *)
+
+module Int64Set = Set.Make(Int64)
+
+let check_switch_cases switch_body =
+ let cases = ref Int64Set.empty
+ and default = ref false in
+ let rec check s =
+ match s.sdesc with
+ | Sskip -> ()
+ | Sdo _ -> ()
+ | Sseq(s1, s2) -> check s1; check s2
+ | Sif(_, s1, s2) -> check s1; check s2
+ | Swhile(_, s1) -> check s1
+ | Sdowhile(s1, _) -> check s1
+ | Sfor(s1, _, s2, s3) -> check s1; check s2; check s3
+ | Sbreak -> ()
+ | Scontinue -> ()
+ | Sswitch(_, _) -> () (* already checked during elaboration of this switch *)
+ | Slabeled(lbl, s1) ->
+ begin match lbl with
+ | Slabel _ -> ()
+ | Scase(_, n) ->
+ if Int64Set.mem n !cases then
+ Diagnostics.error s.sloc "duplicate case value '%Ld'" n
+ else
+ cases := Int64Set.add n !cases
+ | Sdefault ->
+ if !default then
+ Diagnostics.error s.sloc "multiple default labels in one switch"
+ else
+ default := true
+ end;
+ check s1
+ | Sgoto _ -> ()
+ | Sreturn _ -> ()
+ | Sblock sl -> List.iter check sl
+ | Sdecl _ -> ()
+ | Sasm _ -> ()
+ in check switch_body
(* Elaboration of statements *)
@@ -2498,7 +2821,7 @@ let rec elab_stmt env ctx s =
(* 6.8.3 Expression statements *)
| COMPUTATION(a, loc) ->
- let a,env = (elab_expr ctx.ctx_vararg loc env a) in
+ let a,env = elab_expr ctx loc env a in
{ sdesc = Sdo a; sloc = elab_loc loc },env
(* 6.8.1 Labeled statements *)
@@ -2508,16 +2831,20 @@ let rec elab_stmt env ctx s =
{ sdesc = Slabeled(Slabel lbl, s1); sloc = elab_loc loc },env
| CASE(a, s1, loc) ->
- let a',env = elab_expr ctx.ctx_vararg loc env a in
- begin match Ceval.integer_expr env a' with
+ if not ctx.ctx_in_switch then
+ error loc "'case' statement not in switch statement";
+ let a',env = elab_expr ctx loc env a in
+ let n =
+ match Ceval.integer_expr env a' with
| None ->
- error loc "expression of 'case' label is not an integer constant expression"
- | Some n -> ()
- end;
+ error loc "expression of 'case' label is not an integer constant expression"; 0L
+ | Some n -> n in
let s1,env = elab_stmt env ctx s1 in
- { sdesc = Slabeled(Scase a', s1); sloc = elab_loc loc },env
+ { sdesc = Slabeled(Scase(a', n), s1); sloc = elab_loc loc },env
| DEFAULT(s1, loc) ->
+ if not ctx.ctx_in_switch then
+ error loc "'case' statement not in switch statement";
let s1,env = elab_stmt env ctx s1 in
{ sdesc = Slabeled(Sdefault, s1); sloc = elab_loc loc },env
@@ -2529,7 +2856,7 @@ let rec elab_stmt env ctx s =
(* 6.8.4 Conditional statements *)
| If(a, s1, s2, loc) ->
- let a',env = elab_expr ctx.ctx_vararg loc env a in
+ let a',env = elab_expr ctx loc env a in
if not (is_scalar_type env a'.etyp) then
error loc "controlling expression of 'if' does not have scalar type (%a invalid)"
(print_typ env) a'.etyp;
@@ -2544,7 +2871,7 @@ let rec elab_stmt env ctx s =
(* 6.8.5 Iterative statements *)
| WHILE(a, s1, loc) ->
- let a',env = elab_expr ctx.ctx_vararg loc env a in
+ let a',env = elab_expr ctx loc env a in
if not (is_scalar_type env a'.etyp) then
error loc "controlling expression of 'while' does not have scalar type (%a invalid)"
(print_typ env) a'.etyp;
@@ -2553,7 +2880,7 @@ let rec elab_stmt env ctx s =
| DOWHILE(a, s1, loc) ->
let s1',env = elab_stmt env (ctx_loop ctx) s1 in
- let a',env = elab_expr ctx.ctx_vararg loc env a in
+ let a',env = elab_expr ctx loc env a in
if not (is_scalar_type env a'.etyp) then
error loc "controlling expression of 'while' does not have scalar type (%a invalid)"
(print_typ env) a'.etyp;
@@ -2563,24 +2890,25 @@ let rec elab_stmt env ctx s =
let (a1', env_decls, decls') =
match fc with
| Some (FC_EXP a1) ->
- let a1,env = elab_for_expr ctx.ctx_vararg loc env (Some a1) in
+ let a1,env = elab_for_expr ctx loc env (Some a1) in
(a1, env, None)
| None ->
- let a1,env = elab_for_expr ctx.ctx_vararg loc env None in
+ let a1,env = elab_for_expr ctx loc env None in
(a1, env, None)
| Some (FC_DECL def) ->
- let (dcl, env') = elab_definition true (Env.new_scope env) def in
+ let (dcl, env') = elab_definition true true ctx.ctx_nonstatic_inline
+ (Env.new_scope env) def in
let loc = elab_loc (Cabshelper.get_definitionloc def) in
(sskip, env',
Some(List.map (fun d -> {sdesc = Sdecl d; sloc = loc}) dcl)) in
let a2',env_test =
match a2 with
| None -> intconst 1L IInt,env_decls
- | Some a2 -> elab_expr ctx.ctx_vararg loc env_decls a2
+ | Some a2 -> elab_expr ctx loc env_decls a2
in
if not (is_scalar_type env_test a2'.etyp) then
error loc "controlling expression of 'for' does not have scalar type (%a invalid)" (print_typ env) a2'.etyp;
- let a3',env_for = elab_for_expr ctx.ctx_vararg loc env_test a3 in
+ let a3',env_for = elab_for_expr ctx loc env_test a3 in
let s1',env_body = elab_stmt env_for (ctx_loop ctx) s1 in
let sfor = { sdesc = Sfor(a1', a2', a3', s1'); sloc = elab_loc loc } in
begin match decls' with
@@ -2590,11 +2918,12 @@ let rec elab_stmt env ctx s =
(* 6.8.4 Switch statement *)
| SWITCH(a, s1, loc) ->
- let a',env = elab_expr ctx.ctx_vararg loc env a in
+ let a',env = elab_expr ctx loc env a in
if not (is_integer_type env a'.etyp) then
error loc "controlling expression of 'switch' does not have integer type (%a invalid)"
(print_typ env) a'.etyp;
let s1',env = elab_stmt env (ctx_switch ctx) s1 in
+ check_switch_cases s1';
{ sdesc = Sswitch(a', s1'); sloc = elab_loc loc },env
(* 6.8.6 Break and continue statements *)
@@ -2609,7 +2938,7 @@ let rec elab_stmt env ctx s =
(* 6.8.6 Return statements *)
| RETURN(a, loc) ->
- let a',env = elab_opt_expr ctx.ctx_vararg loc env a in
+ let a',env = elab_opt_expr ctx loc env a in
begin match (unroll env ctx.ctx_return_typ, a') with
| TVoid _, None -> ()
| TVoid _, Some _ ->
@@ -2628,7 +2957,7 @@ let rec elab_stmt env ctx s =
(print_typ env) b.etyp (print_typ env) ctx.ctx_return_typ
else
warning loc Unnamed
- "incompatible conversion returning %a from a function with result type %a"
+ "incompatible conversion: returning %a from a function with result type %a"
(print_typ env) b.etyp (print_typ env) ctx.ctx_return_typ
else
error loc
@@ -2652,8 +2981,13 @@ let rec elab_stmt env ctx s =
| ASM(cv_specs, wide, chars, outputs, inputs, flags, loc) ->
let a = elab_cvspecs env cv_specs in
let s = elab_simple_string loc wide chars in
- let outputs,env = mmap (elab_asm_operand ctx.ctx_vararg loc) env outputs in
- let inputs ,env= mmap (elab_asm_operand ctx.ctx_vararg loc) env inputs in
+ let outputs,env = mmap (elab_asm_operand ctx loc) env outputs in
+ List.iter
+ (fun (lbl, cst, e) ->
+ if not (is_modifiable_lvalue env e) then
+ error loc "asm output is not a modifiable l-value";)
+ outputs;
+ let inputs ,env= mmap (elab_asm_operand ctx loc) env inputs in
let flags = List.map (fun (w,c) -> elab_simple_string loc w c) flags in
{ sdesc = Sasm(a, s, outputs, inputs, flags);
sloc = elab_loc loc },env
@@ -2672,7 +3006,8 @@ and elab_block_body env ctx sl =
| [] ->
[],env
| DEFINITION def :: sl1 ->
- let (dcl, env') = elab_definition true env def in
+ let (dcl, env') =
+ elab_definition false true ctx.ctx_nonstatic_inline env def in
let loc = elab_loc (Cabshelper.get_definitionloc def) in
let dcl = List.map (fun ((sto,id,ty,_) as d) ->
Debug.insert_local_declaration sto id ty loc;
@@ -2686,14 +3021,24 @@ and elab_block_body env ctx sl =
(* Elaboration of a function body. Return the corresponding C statement. *)
-let elab_funbody return_typ vararg env b =
+let elab_funbody return_typ vararg nonstatic_inline env b =
let ctx =
{ ctx_return_typ = return_typ;
ctx_labels = stmt_labels b;
ctx_break = false;
ctx_continue = false;
- ctx_vararg = vararg;} in
- fst(elab_stmt env ctx b)
+ ctx_in_switch = false;
+ ctx_vararg = vararg;
+ ctx_nonstatic_inline = nonstatic_inline } in
+ (* The function body appears as a block in the AST but should not create
+ a new scope. Instead, the scope used for function parameters must be
+ used for the body. *)
+ match b with
+ | BLOCK (b,loc) ->
+ let b',_ = elab_block_body env ctx b in
+ { sdesc = Sblock b'; sloc = elab_loc loc }
+ | _ ->
+ assert false
(* Filling in forward declaration *)
let _ = elab_funbody_f := elab_funbody
@@ -2703,7 +3048,9 @@ let _ = elab_funbody_f := elab_funbody
let elab_file prog =
reset();
- ignore (elab_definitions false (Builtins.environment()) prog);
+ let env = Builtins.environment () in
+ let elab_def env d = snd (elab_definition false false false env d) in
+ ignore (List.fold_left elab_def env prog);
let p = elaborated_program () in
Checks.unused_variables p;
Checks.unknown_attrs_program p;
diff --git a/cparser/ExtendedAsm.ml b/cparser/ExtendedAsm.ml
index 6cd95aec..257e9cf7 100644
--- a/cparser/ExtendedAsm.ml
+++ b/cparser/ExtendedAsm.ml
@@ -73,7 +73,7 @@ let set_label_const lbl pos n subst =
let is_reg_pair env ty =
match unroll env ty with
- | TInt(ik, _) -> sizeof_ikind ik > !config.sizeof_ptr
+ | TInt(ik, _) -> sizeof_ikind ik > !config.sizeof_intreg
| _ -> false
(* Transform the input operands:
@@ -126,8 +126,6 @@ let transf_outputs loc env = function
| [] ->
(None, [], StringMap.empty, 0, 0)
| [(lbl, cstr, e)] ->
- if not (is_modifiable_lvalue env e) then
- error loc "asm output is not a modifiable l-value";
let valid = Str.string_match re_valid_output cstr 0 in
if valid && String.contains cstr 'r' then
if is_reg_pair env e.etyp then
diff --git a/cparser/GNUmakefile b/cparser/GNUmakefile
index a2646c7b..ce326463 100644
--- a/cparser/GNUmakefile
+++ b/cparser/GNUmakefile
@@ -164,11 +164,11 @@ concrete: $(DATABASE).raw deLexer
# We declare a type name "t", which the de-lexer uses as a type name.
@ f=0 ; \
while read -r line ; do \
- filename=`printf "tests/generated/%03d.c" $$f` ; \
+ filename=`printf "tests/generated/parser_%03d.c" $$f` ; \
rm -f $$filename ; \
echo "typedef int t;" >> $$filename ; \
echo "$$line" \
- | $(CUT) --fields="1" --delimiter=" " --complement \
+ | $(CUT) -f 2- -d " " \
| ./deLexer \
>> $$filename ; \
f=$$((f+1)) ; \
diff --git a/cparser/Lexer.mll b/cparser/Lexer.mll
index cf8788c5..b2a668f0 100644
--- a/cparser/Lexer.mll
+++ b/cparser/Lexer.mll
@@ -21,7 +21,7 @@ open Pre_parser_aux
module SSet = Set.Make(String)
let lexicon : (string, Cabs.cabsloc -> token) Hashtbl.t = Hashtbl.create 17
-let ignored_keyworkds : SSet.t ref = ref SSet.empty
+let ignored_keywords : SSet.t ref = ref SSet.empty
let () =
List.iter (fun (key, builder) -> Hashtbl.add lexicon key builder)
@@ -85,7 +85,7 @@ let () =
("while", fun loc -> WHILE loc)];
if Configuration.system <> "diab" then
(* We can ignore the __extension__ GCC keyword. *)
- ignored_keyworkds := SSet.add "__extension__" !ignored_keyworkds
+ ignored_keywords := SSet.add "__extension__" !ignored_keywords
let init_ctx = SSet.singleton "__builtin_va_list"
let types_context : SSet.t ref = ref init_ctx
@@ -135,7 +135,7 @@ let error lb fmt =
let warning lb fmt =
Diagnostics.warning
- (lb.lex_curr_p.pos_fname,lb.lex_curr_p.pos_lnum) Diagnostics.Unnamed ("warning: " ^^ fmt)
+ (lb.lex_curr_p.pos_fname,lb.lex_curr_p.pos_lnum) Diagnostics.Unnamed fmt
(* Simple character escapes *)
@@ -329,7 +329,7 @@ rule initial = parse
| "," { COMMA(currentLoc lexbuf) }
| "." { DOT(currentLoc lexbuf) }
| identifier as id {
- if SSet.mem id !ignored_keyworkds then
+ if SSet.mem id !ignored_keywords then
initial lexbuf
else
try Hashtbl.find lexicon id (currentLoc lexbuf)
diff --git a/cparser/Machine.ml b/cparser/Machine.ml
index bd524cf8..28c6f8a6 100644
--- a/cparser/Machine.ml
+++ b/cparser/Machine.ml
@@ -44,6 +44,7 @@ type t = {
wchar_signed: bool;
sizeof_size_t: int;
sizeof_ptrdiff_t: int;
+ sizeof_intreg: int;
alignof_ptr: int;
alignof_short: int;
alignof_int: int;
@@ -78,6 +79,7 @@ let ilp32ll64 = {
wchar_signed = true;
sizeof_size_t = 4;
sizeof_ptrdiff_t = 4;
+ sizeof_intreg = 4;
alignof_ptr = 4;
alignof_short = 2;
alignof_int = 4;
@@ -112,6 +114,7 @@ let i32lpll64 = {
wchar_signed = true;
sizeof_size_t = 8;
sizeof_ptrdiff_t = 8;
+ sizeof_intreg = 8;
alignof_ptr = 8;
alignof_short = 2;
alignof_int = 4;
@@ -146,6 +149,7 @@ let il32pll64 = {
wchar_signed = true;
sizeof_size_t = 8;
sizeof_ptrdiff_t = 8;
+ sizeof_intreg = 8;
alignof_ptr = 8;
alignof_short = 2;
alignof_int = 4;
@@ -202,11 +206,20 @@ let ppc_32_bigendian =
struct_passing_style = SP_ref_caller;
struct_return_style = SR_int1to8; }
+let ppc_32_r64_bigendian =
+ { ppc_32_bigendian with sizeof_intreg = 8;}
+
let ppc_32_diab_bigendian =
{ ppc_32_bigendian with sizeof_wchar = 2; wchar_signed = false }
+let ppc_32_r64_diab_bigendian =
+ { ppc_32_diab_bigendian with sizeof_intreg = 8;}
+
let ppc_32_linux_bigendian = {ppc_32_bigendian with struct_return_style = SR_ref;}
+let ppc_32_r64_linux_bigendian =
+ { ppc_32_linux_bigendian with sizeof_intreg = 8;}
+
let arm_littleendian =
{ ilp32ll64 with name = "arm"; struct_passing_style = SP_split_args;
struct_return_style = SR_int1to4;}
@@ -260,6 +273,7 @@ let undef = {
wchar_signed = true;
sizeof_size_t = 0;
sizeof_ptrdiff_t = 0;
+ sizeof_intreg = 0;
alignof_ptr = 0;
alignof_short = 0;
alignof_int = 0;
diff --git a/cparser/Machine.mli b/cparser/Machine.mli
index 32f9a4de..56d8d0b9 100644
--- a/cparser/Machine.mli
+++ b/cparser/Machine.mli
@@ -43,6 +43,7 @@ type t = {
wchar_signed: bool;
sizeof_size_t: int;
sizeof_ptrdiff_t: int;
+ sizeof_intreg: int;
alignof_ptr: int;
alignof_short: int;
alignof_int: int;
@@ -78,6 +79,9 @@ val win64 : t
val ppc_32_bigendian : t
val ppc_32_diab_bigendian : t
val ppc_32_linux_bigendian : t
+val ppc_32_r64_bigendian : t
+val ppc_32_r64_diab_bigendian : t
+val ppc_32_r64_linux_bigendian : t
val arm_littleendian : t
val arm_bigendian : t
val rv32 : t
diff --git a/cparser/validator/Alphabet.v b/cparser/MenhirLib/Alphabet.v
index a13f69b0..a13f69b0 100644
--- a/cparser/validator/Alphabet.v
+++ b/cparser/MenhirLib/Alphabet.v
diff --git a/cparser/validator/Automaton.v b/cparser/MenhirLib/Automaton.v
index fc995298..fc995298 100644
--- a/cparser/validator/Automaton.v
+++ b/cparser/MenhirLib/Automaton.v
diff --git a/cparser/validator/Grammar.v b/cparser/MenhirLib/Grammar.v
index 8e427cd9..8e427cd9 100644
--- a/cparser/validator/Grammar.v
+++ b/cparser/MenhirLib/Grammar.v
diff --git a/cparser/validator/Interpreter.v b/cparser/MenhirLib/Interpreter.v
index 4ac02693..4ac02693 100644
--- a/cparser/validator/Interpreter.v
+++ b/cparser/MenhirLib/Interpreter.v
diff --git a/cparser/validator/Interpreter_complete.v b/cparser/MenhirLib/Interpreter_complete.v
index f76731d5..2e64b8da 100644
--- a/cparser/validator/Interpreter_complete.v
+++ b/cparser/MenhirLib/Interpreter_complete.v
@@ -220,7 +220,7 @@ Lemma ptlz_past_ptlz_prod:
(ptlz:ptl_zipper hole_symbs hole_word hole_sems),
rev_append hole_symbs (ptlz_past ptlz) = prod_rhs_rev (ptlz_prod ptlz).
Proof.
-fix 4.
+fix ptlz_past_ptlz_prod 4.
destruct ptlz; simpl.
rewrite <- rev_alt, rev_involutive; reflexivity.
apply (ptlz_past_ptlz_prod _ _ _ ptlz).
@@ -298,7 +298,7 @@ Lemma build_pt_dot_cost:
(ptlz:ptl_zipper hole_symbs hole_word hole_sems),
ptd_cost (build_pt_dot ptl ptlz) = ptl_size ptl + ptlz_cost ptlz.
Proof.
-fix 4.
+fix build_pt_dot_cost 4.
destruct ptl; intros.
reflexivity.
destruct p.
@@ -313,7 +313,7 @@ Lemma build_pt_dot_buffer:
(ptlz:ptl_zipper hole_symbs hole_word hole_sems),
ptd_buffer (build_pt_dot ptl ptlz) = hole_word ++ ptlz_buffer ptlz.
Proof.
-fix 4.
+fix build_pt_dot_buffer 4.
destruct ptl; intros.
reflexivity.
destruct p.
@@ -330,7 +330,7 @@ Lemma ptd_stack_compat_build_pt_dot:
ptlz_stack_compat ptlz stack ->
ptd_stack_compat (build_pt_dot ptl ptlz) stack.
Proof.
-fix 4.
+fix ptd_stack_compat_build_pt_dot 4.
destruct ptl; intros.
eauto.
destruct p.
@@ -375,7 +375,7 @@ Lemma pop_ptlz_cost:
let 'existT _ word (existT _ sem (ptz, pt)) := pop_ptlz ptl ptlz in
ptlz_cost ptlz = ptz_cost ptz.
Proof.
-fix 5.
+fix pop_ptlz_cost 5.
destruct ptlz.
reflexivity.
simpl; apply pop_ptlz_cost.
@@ -388,7 +388,7 @@ Lemma pop_ptlz_buffer:
let 'existT _ word (existT _ sem (ptz, pt)) := pop_ptlz ptl ptlz in
ptlz_buffer ptlz = ptz_buffer ptz.
Proof.
-fix 5.
+fix pop_ptlz_buffer 5.
destruct ptlz.
reflexivity.
simpl; apply pop_ptlz_buffer.
@@ -428,7 +428,7 @@ Lemma pop_ptlz_pop_stack_compat:
end.
Proof.
Opaque AlphabetComparable AlphabetComparableUsualEq.
-fix 5.
+fix pop_ptlz_pop_stack_compat 5.
destruct ptlz. intros; simpl.
split.
apply H.
@@ -591,7 +591,7 @@ Lemma parse_fix_complete:
| Err => True
end.
Proof.
-fix 3.
+fix parse_fix_complete 3.
destruct n_steps; intros; simpl.
apply Nat.lt_0_succ.
apply step_next_ptd in H.
diff --git a/cparser/validator/Interpreter_correct.v b/cparser/MenhirLib/Interpreter_correct.v
index 1263d4e3..1263d4e3 100644
--- a/cparser/validator/Interpreter_correct.v
+++ b/cparser/MenhirLib/Interpreter_correct.v
diff --git a/cparser/validator/Interpreter_safe.v b/cparser/MenhirLib/Interpreter_safe.v
index a1aa35b8..a1aa35b8 100644
--- a/cparser/validator/Interpreter_safe.v
+++ b/cparser/MenhirLib/Interpreter_safe.v
diff --git a/cparser/validator/Main.v b/cparser/MenhirLib/Main.v
index 1a17e988..1a17e988 100644
--- a/cparser/validator/Main.v
+++ b/cparser/MenhirLib/Main.v
diff --git a/cparser/validator/Tuples.v b/cparser/MenhirLib/Tuples.v
index 3fd2ec03..3fd2ec03 100644
--- a/cparser/validator/Tuples.v
+++ b/cparser/MenhirLib/Tuples.v
diff --git a/cparser/validator/Validator_complete.v b/cparser/MenhirLib/Validator_complete.v
index a9823278..a9823278 100644
--- a/cparser/validator/Validator_complete.v
+++ b/cparser/MenhirLib/Validator_complete.v
diff --git a/cparser/validator/Validator_safe.v b/cparser/MenhirLib/Validator_safe.v
index 183d661b..183d661b 100644
--- a/cparser/validator/Validator_safe.v
+++ b/cparser/MenhirLib/Validator_safe.v
diff --git a/cparser/PackedStructs.ml b/cparser/PackedStructs.ml
index e1287eb8..a2c91c0a 100644
--- a/cparser/PackedStructs.ml
+++ b/cparser/PackedStructs.ml
@@ -81,47 +81,33 @@ let transf_field_decl mfa swapped loc env struct_id f =
(* Rewriting struct declarations *)
let transf_struct_decl mfa msa swapped loc env struct_id attrs ml =
+ let attrs' =
+ remove_custom_attributes ["packed";"__packed__"] attrs in
let ml' =
List.map (transf_field_decl mfa swapped loc env struct_id) ml in
- if msa = 0 then (attrs, ml') else begin
- let al' = (* natural alignment of the transformed struct *)
- List.fold_left
- (fun a f' -> max a (safe_alignof loc env f'.fld_typ))
- 1 ml' in
- (set_alignas_attr (max msa al') attrs, ml')
+ if msa = 0 then (attrs', ml') else begin
+ (* [Cutil.composite_info_def] takes packing parameters into account.
+ Hence the alignment it returns is the correct alignment for
+ the transformed struct. *)
+ let ci = Cutil.composite_info_def env Struct attrs ml in
+ match ci.ci_alignof with
+ | None -> error loc "incomplete struct"; (attrs', ml')
+ | Some al -> (set_alignas_attr al attrs', ml')
end
(* Rewriting composite declarations *)
-let is_pow2 n = n > 0 && n land (n - 1) = 0
-
-let packed_param_value loc n =
- let m = Int64.to_int n in
- if n <> Int64.of_int m then
- (error loc "__packed__ parameter `%Ld' is too large" n; 0)
- else if m = 0 || is_pow2 m then
- m
- else
- (error loc "__packed__ parameter `%Ld' must be a power of 2" n; 0)
-
let transf_composite loc env su id attrs ml =
match su with
| Union -> (attrs, ml)
| Struct ->
let (mfa, msa, swapped) =
match find_custom_attributes ["packed";"__packed__"] attrs with
- | [] -> (0L, 0L, false)
- | [[]] -> (1L, 0L, false)
- | [[AInt n]] -> (n, 0L, false)
- | [[AInt n; AInt p]] -> (n, p, false)
- | [[AInt n; AInt p; AInt q]] -> (n, p, q <> 0L)
- | _ ->
- error loc "ill-formed or ambiguous __packed__ attribute";
- (0L, 0L, false) in
- let mfa = packed_param_value loc mfa in
- let msa = packed_param_value loc msa in
- let attrs' = remove_custom_attributes ["packed";"__packed__"] attrs in
- transf_struct_decl mfa msa swapped loc env id attrs' ml
+ | [] -> (0, 0, false)
+ | [_] -> Cutil.packing_parameters attrs
+ | _ -> error loc "multiple __packed__ attributes";
+ (0, 0, false) in
+ transf_struct_decl mfa msa swapped loc env id attrs ml
(* Accessor functions *)
diff --git a/cparser/Parse.ml b/cparser/Parse.ml
index b2c83698..154e3dcf 100644
--- a/cparser/Parse.ml
+++ b/cparser/Parse.ml
@@ -69,7 +69,7 @@ let preprocessed_file transfs name sourcefile =
| Parser.Parser.Inter.Fail_pr ->
(* Theoretically impossible : implies inconsistencies
between grammars. *)
- Diagnostics.fatal_error Diagnostics.no_loc "Internal error while parsing"
+ Diagnostics.fatal_error Diagnostics.no_loc "internal error while parsing"
| Parser.Parser.Inter.Timeout_pr -> assert false
| Parser.Parser.Inter.Parsed_pr (ast, _ ) -> ast) in
let p1 = Timing.time "Elaboration" Elab.elab_file ast in
diff --git a/cparser/Parser.vy b/cparser/Parser.vy
index 7fe686f1..79e3793d 100644
--- a/cparser/Parser.vy
+++ b/cparser/Parser.vy
@@ -172,10 +172,8 @@ unary_expression:
| loc = SIZEOF LPAREN typ = type_name RPAREN
{ (TYPE_SIZEOF typ, loc) }
(* Non-standard *)
-| loc = ALIGNOF expr = unary_expression
- { (EXPR_ALIGNOF (fst expr), loc) }
| loc = ALIGNOF LPAREN typ = type_name RPAREN
- { (TYPE_ALIGNOF typ, loc) }
+ { (ALIGNOF typ, loc) }
unary_operator:
| loc = AND
@@ -546,7 +544,7 @@ attribute_specifier:
| loc = ALIGNAS LPAREN args = argument_expression_list RPAREN
{ (ALIGNAS_ATTR (rev' args) loc, loc) }
| loc = ALIGNAS LPAREN typ = type_name RPAREN
- { (ALIGNAS_ATTR [TYPE_ALIGNOF typ] loc, loc) }
+ { (ALIGNAS_ATTR [ALIGNOF typ] loc, loc) }
gcc_attribute_list:
| a = gcc_attribute
@@ -562,7 +560,7 @@ gcc_attribute:
| w = gcc_attribute_word LPAREN RPAREN
{ GCC_ATTR_ARGS w [] }
| w = gcc_attribute_word LPAREN args = argument_expression_list RPAREN
- { GCC_ATTR_ARGS w args }
+ { GCC_ATTR_ARGS w (rev' args) }
gcc_attribute_word:
| i = OTHER_NAME
diff --git a/cparser/Rename.ml b/cparser/Rename.ml
index d63fa47d..eb31eaf0 100644
--- a/cparser/Rename.ml
+++ b/cparser/Rename.ml
@@ -188,7 +188,7 @@ and stmt_or_decl env s =
(stmt env s, env)
and slabel env = function
- | Scase e -> Scase(exp env e)
+ | Scase(e, n) -> Scase(exp env e, n)
| sl -> sl
let fundef env f =
diff --git a/cparser/Unblock.ml b/cparser/Unblock.ml
index 5df2e2cf..da8049a5 100644
--- a/cparser/Unblock.ml
+++ b/cparser/Unblock.ml
@@ -31,7 +31,7 @@ let rec local_initializer env path init k =
let (ty_elt, sz) =
match unroll env path.etyp with
| TArray(ty_elt, Some sz, _) -> (ty_elt, sz)
- | _ -> Diagnostics.fatal_error Diagnostics.no_loc "Wrong type for array initializer" in
+ | _ -> Diagnostics.fatal_error Diagnostics.no_loc "wrong type for array initializer" in
let rec array_init pos il =
if pos >= sz then k else begin
let (i1, il') =
diff --git a/cparser/deLexer.ml b/cparser/deLexer.ml
index 3aa168da..de0e9b6e 100644
--- a/cparser/deLexer.ml
+++ b/cparser/deLexer.ml
@@ -115,6 +115,7 @@ let delex (symbol : string) : string =
| "COMMA" -> ","
| "DOT" -> "."
| "PRAGMA" -> "#pragma \n"
+ | "BUILTIN_OFFSETOF" -> "__builtin_offsetof"
| "EOF" -> "" (* this should be ok *)
| _ -> raise Not_found (* this should not happen *)
diff --git a/cparser/handcrafted.messages b/cparser/handcrafted.messages
index 567fdd6b..95077739 100644
--- a/cparser/handcrafted.messages
+++ b/cparser/handcrafted.messages
@@ -181,7 +181,7 @@
translation_unit_file: ALIGNAS LPAREN INT XOR_ASSIGN
##
-## Ends in an error in state: 341.
+## Ends in an error in state: 314.
##
## attribute_specifier -> ALIGNAS LPAREN type_name . RPAREN [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER RBRACK PRE_NAME PLUS PACKED NORETURN MINUS LPAREN LONG LBRACK LBRACE INT INLINE INC FLOAT EXTERN EQ ENUM DOUBLE DEC CONSTANT CONST COMMA COLON CHAR BUILTIN_VA_ARG BUILTIN_OFFSETOF BANG AUTO ATTRIBUTE AND ALIGNOF ALIGNAS ]
##
@@ -192,9 +192,9 @@ translation_unit_file: ALIGNAS LPAREN INT XOR_ASSIGN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 156, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
-## In state 330, spurious reduction of production option(abstract_declarator(type_name)) ->
-## In state 336, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
+## In state 67, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
+## In state 306, spurious reduction of production option(abstract_declarator(type_name)) ->
+## In state 312, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
##
# Maybe the type name was not complete, but we have reduced anyway
@@ -216,7 +216,6 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ ALIGNOF LPAREN VOID XOR_ASSIGN
##
## Ends in an error in state: 304.
##
-## postfix_expression -> LPAREN type_name . RPAREN LBRACE initializer_list option(COMMA) RBRACE [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
## unary_expression -> ALIGNOF LPAREN type_name . RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LEQ LEFT_ASSIGN LEFT HAT GT GEQ EQEQ EQ DIV_ASSIGN COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
## The known suffix of the stack is as follows:
@@ -226,13 +225,13 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ ALIGNOF LPAREN VOID XOR_ASSIGN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 156, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
-## In state 330, spurious reduction of production option(abstract_declarator(type_name)) ->
-## In state 336, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
+## In state 67, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
+## In state 306, spurious reduction of production option(abstract_declarator(type_name)) ->
+## In state 312, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ SIZEOF LPAREN VOID XOR_ASSIGN
##
-## Ends in an error in state: 389.
+## Ends in an error in state: 388.
##
## postfix_expression -> LPAREN type_name . RPAREN LBRACE initializer_list option(COMMA) RBRACE [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
## unary_expression -> SIZEOF LPAREN type_name . RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LEQ LEFT_ASSIGN LEFT HAT GT GEQ EQEQ EQ DIV_ASSIGN COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -244,9 +243,9 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ SIZEOF LPAREN VOID XOR_ASSIGN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 156, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
-## In state 330, spurious reduction of production option(abstract_declarator(type_name)) ->
-## In state 336, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
+## In state 67, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
+## In state 306, spurious reduction of production option(abstract_declarator(type_name)) ->
+## In state 312, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
##
Ill-formed use of $2.
@@ -259,7 +258,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ BUILTIN_VA_ARG LPAREN PRE_NAME VAR_NAME COMMA VOID XOR_ASSIGN
##
-## Ends in an error in state: 353.
+## Ends in an error in state: 333.
##
## postfix_expression -> BUILTIN_VA_ARG LPAREN assignment_expression COMMA type_name . RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -270,9 +269,9 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ BUILTIN_VA_ARG LPAREN PRE_NAME V
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 156, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
-## In state 330, spurious reduction of production option(abstract_declarator(type_name)) ->
-## In state 336, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
+## In state 67, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
+## In state 306, spurious reduction of production option(abstract_declarator(type_name)) ->
+## In state 312, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
##
Ill-formed use of __builtin_va_arg.
@@ -285,7 +284,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ INC LPAREN VOID XOR_ASSIGN
##
-## Ends in an error in state: 383.
+## Ends in an error in state: 363.
##
## postfix_expression -> LPAREN type_name . RPAREN LBRACE initializer_list option(COMMA) RBRACE [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -296,9 +295,9 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ INC LPAREN VOID XOR_ASSIGN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 156, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
-## In state 330, spurious reduction of production option(abstract_declarator(type_name)) ->
-## In state 336, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
+## In state 67, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
+## In state 306, spurious reduction of production option(abstract_declarator(type_name)) ->
+## In state 312, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
##
# gcc simply says it expects a closing parenthesis,
@@ -314,7 +313,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LPAREN VOID XOR_ASSIGN
##
-## Ends in an error in state: 386.
+## Ends in an error in state: 385.
##
## cast_expression -> LPAREN type_name . RPAREN cast_expression [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LEQ LEFT_ASSIGN LEFT HAT GT GEQ EQEQ EQ DIV_ASSIGN COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
## postfix_expression -> LPAREN type_name . RPAREN LBRACE initializer_list option(COMMA) RBRACE [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -326,9 +325,9 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ LPAREN VOID XOR_ASSIGN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 156, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
-## In state 330, spurious reduction of production option(abstract_declarator(type_name)) ->
-## In state 336, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
+## In state 67, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
+## In state 306, spurious reduction of production option(abstract_declarator(type_name)) ->
+## In state 312, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
##
# gcc and clang say they expect a closing parenthesis.
@@ -342,7 +341,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: ALIGNAS LPAREN PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 343.
+## Ends in an error in state: 316.
##
## argument_expression_list -> argument_expression_list . COMMA assignment_expression [ RPAREN COMMA ]
## attribute_specifier -> ALIGNAS LPAREN argument_expression_list . RPAREN [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER RBRACK PRE_NAME PLUS PACKED NORETURN MINUS LPAREN LONG LBRACK LBRACE INT INLINE INC FLOAT EXTERN EQ ENUM DOUBLE DEC CONSTANT CONST COMMA COLON CHAR BUILTIN_VA_ARG BUILTIN_OFFSETOF BANG AUTO ATTRIBUTE AND ALIGNOF ALIGNAS ]
@@ -354,21 +353,21 @@ translation_unit_file: ALIGNAS LPAREN PRE_NAME VAR_NAME SEMICOLON
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 143, spurious reduction of production argument_expression_list -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 230, spurious reduction of production argument_expression_list -> assignment_expression
##
# We are trying to recognize an alignas specifier.
@@ -392,7 +391,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: ALIGNAS LPAREN INT LBRACK RPAREN
##
-## Ends in an error in state: 240.
+## Ends in an error in state: 151.
##
## direct_abstract_declarator -> option(direct_abstract_declarator) LBRACK option(type_qualifier_list) . optional(assignment_expression,RBRACK) [ RPAREN LPAREN LBRACK COMMA ]
## type_qualifier_list -> option(type_qualifier_list) . type_qualifier_noattr [ VOLATILE TILDE STRING_LITERAL STAR SIZEOF RESTRICT RBRACK PRE_NAME PLUS PACKED MINUS LPAREN INC DEC CONSTANT CONST BUILTIN_VA_ARG BUILTIN_OFFSETOF BANG ATTRIBUTE AND ALIGNOF ALIGNAS ]
@@ -514,7 +513,7 @@ At this point, a closing parenthesis ')' is expected.
translation_unit_file: ALIGNAS LPAREN INT LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 331.
+## Ends in an error in state: 307.
##
## direct_abstract_declarator -> LPAREN . save_context abstract_declarator(type_name) RPAREN [ RPAREN LPAREN LBRACK COMMA ]
## direct_abstract_declarator -> LPAREN . option(context_parameter_type_list) RPAREN [ RPAREN LPAREN LBRACK COMMA ]
@@ -537,7 +536,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 234.
+## Ends in an error in state: 145.
##
## direct_abstract_declarator -> LPAREN . save_context abstract_declarator(type_name) RPAREN [ RPAREN LPAREN LBRACK COMMA ]
## direct_abstract_declarator -> LPAREN . option(context_parameter_type_list) RPAREN [ RPAREN LPAREN LBRACK COMMA ]
@@ -625,7 +624,7 @@ At this point, an opening parenthesis '(' is expected.
translation_unit_file: ATTRIBUTE LPAREN LPAREN COMMA XOR_ASSIGN
##
-## Ends in an error in state: 365.
+## Ends in an error in state: 345.
##
## gcc_attribute_list -> gcc_attribute_list COMMA . gcc_attribute [ RPAREN COMMA ]
##
@@ -647,7 +646,7 @@ At this point, a gcc attribute is expected.
translation_unit_file: ATTRIBUTE LPAREN LPAREN RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 363.
+## Ends in an error in state: 343.
##
## attribute_specifier -> ATTRIBUTE LPAREN LPAREN gcc_attribute_list RPAREN . RPAREN [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER RBRACK PRE_NAME PLUS PACKED NORETURN MINUS LPAREN LONG LBRACK LBRACE INT INLINE INC FLOAT EXTERN EQ ENUM DOUBLE DEC CONSTANT CONST COMMA COLON CHAR BUILTIN_VA_ARG BUILTIN_OFFSETOF BANG AUTO ATTRIBUTE AND ALIGNOF ALIGNAS ]
##
@@ -662,7 +661,7 @@ At this point, a second closing parenthesis ')' is expected.
translation_unit_file: ATTRIBUTE LPAREN LPAREN PRE_NAME VAR_NAME LPAREN RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 362.
+## Ends in an error in state: 342.
##
## attribute_specifier -> ATTRIBUTE LPAREN LPAREN gcc_attribute_list . RPAREN RPAREN [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER RBRACK PRE_NAME PLUS PACKED NORETURN MINUS LPAREN LONG LBRACK LBRACE INT INLINE INC FLOAT EXTERN EQ ENUM DOUBLE DEC CONSTANT CONST COMMA COLON CHAR BUILTIN_VA_ARG BUILTIN_OFFSETOF BANG AUTO ATTRIBUTE AND ALIGNOF ALIGNAS ]
## gcc_attribute_list -> gcc_attribute_list . COMMA gcc_attribute [ RPAREN COMMA ]
@@ -685,7 +684,7 @@ At this point, one of the following is expected:
translation_unit_file: ATTRIBUTE LPAREN LPAREN PRE_NAME VAR_NAME LPAREN PRE_NAME TYPEDEF_NAME COMMA PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 358.
+## Ends in an error in state: 338.
##
## argument_expression_list -> argument_expression_list . COMMA assignment_expression [ RPAREN COMMA ]
## gcc_attribute -> gcc_attribute_word LPAREN typedef_name COMMA argument_expression_list . RPAREN [ RPAREN COMMA ]
@@ -697,21 +696,21 @@ translation_unit_file: ATTRIBUTE LPAREN LPAREN PRE_NAME VAR_NAME LPAREN PRE_NAME
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 143, spurious reduction of production argument_expression_list -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 230, spurious reduction of production argument_expression_list -> assignment_expression
##
# We know for sure that we are parsing a gcc attribute.
@@ -729,7 +728,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: ATTRIBUTE LPAREN LPAREN PRE_NAME VAR_NAME LPAREN PRE_NAME TYPEDEF_NAME COMMA XOR_ASSIGN
##
-## Ends in an error in state: 357.
+## Ends in an error in state: 337.
##
## gcc_attribute -> gcc_attribute_word LPAREN typedef_name COMMA . argument_expression_list RPAREN [ RPAREN COMMA ]
##
@@ -746,7 +745,7 @@ At this point, an expression is expected.
translation_unit_file: ATTRIBUTE LPAREN LPAREN PRE_NAME VAR_NAME LPAREN PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 356.
+## Ends in an error in state: 336.
##
## gcc_attribute -> gcc_attribute_word LPAREN typedef_name . COMMA argument_expression_list RPAREN [ RPAREN COMMA ]
##
@@ -861,7 +860,7 @@ At this point, two opening parentheses '((' are expected.
translation_unit_file: ENUM LBRACE PRE_NAME VAR_NAME COMMA XOR_ASSIGN
##
-## Ends in an error in state: 373.
+## Ends in an error in state: 353.
##
## enumerator_list -> enumerator_list COMMA . declare_varname(enumerator) [ RBRACE COMMA ]
## option(COMMA) -> COMMA . [ RBRACE ]
@@ -882,7 +881,7 @@ At this point, an enumerator is expected.
translation_unit_file: ENUM LBRACE PRE_NAME VAR_NAME EQ CONSTANT SEMICOLON
##
-## Ends in an error in state: 372.
+## Ends in an error in state: 352.
##
## enum_specifier -> ENUM attribute_specifier_list option(other_identifier) LBRACE enumerator_list . option(COMMA) RBRACE [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF STRUCT STATIC STAR SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK INT INLINE FLOAT EXTERN ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
## enumerator_list -> enumerator_list . COMMA declare_varname(enumerator) [ RBRACE COMMA ]
@@ -894,22 +893,22 @@ translation_unit_file: ENUM LBRACE PRE_NAME VAR_NAME EQ CONSTANT SEMICOLON
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 67, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 377, spurious reduction of production enumerator -> enumeration_constant EQ conditional_expression
-## In state 374, spurious reduction of production declare_varname(enumerator) -> enumerator
-## In state 381, spurious reduction of production enumerator_list -> declare_varname(enumerator)
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 154, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 357, spurious reduction of production enumerator -> enumeration_constant EQ conditional_expression
+## In state 354, spurious reduction of production declare_varname(enumerator) -> enumerator
+## In state 361, spurious reduction of production enumerator_list -> declare_varname(enumerator)
##
#
# At first sight, it seems that the last enumerator that we have recognized
@@ -940,7 +939,7 @@ then at this point, a closing brace '}' is expected.
translation_unit_file: ENUM LBRACE PRE_NAME VAR_NAME EQ XOR_ASSIGN
##
-## Ends in an error in state: 376.
+## Ends in an error in state: 356.
##
## enumerator -> enumeration_constant EQ . conditional_expression [ RBRACE COMMA ]
##
@@ -955,7 +954,7 @@ At this point, a constant expression is expected.
translation_unit_file: ENUM LBRACE PRE_NAME VAR_NAME XOR_ASSIGN
##
-## Ends in an error in state: 375.
+## Ends in an error in state: 355.
##
## enumerator -> enumeration_constant . [ RBRACE COMMA ]
## enumerator -> enumeration_constant . EQ conditional_expression [ RBRACE COMMA ]
@@ -976,7 +975,7 @@ At this point, one of the following is expected:
translation_unit_file: ENUM LBRACE XOR_ASSIGN
##
-## Ends in an error in state: 370.
+## Ends in an error in state: 350.
##
## enum_specifier -> ENUM attribute_specifier_list option(other_identifier) LBRACE . enumerator_list option(COMMA) RBRACE [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF STRUCT STATIC STAR SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK INT INLINE FLOAT EXTERN ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
##
@@ -994,7 +993,7 @@ At this point, an enumerator is expected.
translation_unit_file: ENUM XOR_ASSIGN
##
-## Ends in an error in state: 368.
+## Ends in an error in state: 348.
##
## enum_specifier -> ENUM attribute_specifier_list . option(other_identifier) LBRACE enumerator_list option(COMMA) RBRACE [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF STRUCT STATIC STAR SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK INT INLINE FLOAT EXTERN ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
## enum_specifier -> ENUM attribute_specifier_list . general_identifier [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF STRUCT STATIC STAR SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK INT INLINE FLOAT EXTERN ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -1023,8 +1022,6 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ ALIGNOF LPAREN XOR_ASSIGN
##
## Ends in an error in state: 65.
##
-## postfix_expression -> LPAREN . type_name RPAREN LBRACE initializer_list option(COMMA) RBRACE [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
-## primary_expression -> LPAREN . expression RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
## unary_expression -> ALIGNOF LPAREN . type_name RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LEQ LEFT_ASSIGN LEFT HAT GT GEQ EQEQ EQ DIV_ASSIGN COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
## The known suffix of the stack is as follows:
@@ -1058,12 +1055,18 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ ALIGNOF XOR_ASSIGN
##
## Ends in an error in state: 64.
##
-## unary_expression -> ALIGNOF . unary_expression [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LEQ LEFT_ASSIGN LEFT HAT GT GEQ EQEQ EQ DIV_ASSIGN COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
## unary_expression -> ALIGNOF . LPAREN type_name RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LEQ LEFT_ASSIGN LEFT HAT GT GEQ EQEQ EQ DIV_ASSIGN COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
## The known suffix of the stack is as follows:
## ALIGNOF
##
+
+Ill-formed use of $0.
+At this point, an opening parenthesis '(' is expected,
+followed with a type name.
+
+# ------------------------------------------------------------------------------
+
translation_unit_file: INT PRE_NAME VAR_NAME EQ SIZEOF XOR_ASSIGN
##
## Ends in an error in state: 23.
@@ -1075,7 +1078,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ SIZEOF XOR_ASSIGN
## SIZEOF
##
-# Let's not reveal that _Alignof and sizeof can be used without parentheses.
+# Let's not reveal that sizeof can be used without parentheses.
# gcc and clang say they expect an expression, which seems both surprising
# (they don't request a parenthesis) and incomplete (they don't allow a type name).
@@ -1088,7 +1091,7 @@ followed with an expression or a type name.
translation_unit_file: INT PRE_NAME VAR_NAME EQ BUILTIN_VA_ARG LPAREN PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 351.
+## Ends in an error in state: 331.
##
## postfix_expression -> BUILTIN_VA_ARG LPAREN assignment_expression . COMMA type_name RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -1099,20 +1102,20 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ BUILTIN_VA_ARG LPAREN PRE_NAME V
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
##
Ill-formed use of $2.
@@ -1125,7 +1128,7 @@ then at this point, a comma ',' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ BUILTIN_VA_ARG LPAREN PRE_NAME VAR_NAME COMMA XOR_ASSIGN
##
-## Ends in an error in state: 352.
+## Ends in an error in state: 332.
##
## postfix_expression -> BUILTIN_VA_ARG LPAREN assignment_expression COMMA . type_name RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -1194,7 +1197,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ INC LPAREN INT RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 384.
+## Ends in an error in state: 364.
##
## postfix_expression -> LPAREN type_name RPAREN . LBRACE initializer_list option(COMMA) RBRACE [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -1246,7 +1249,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME EQ LPAREN PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 338.
+## Ends in an error in state: 382.
##
## expression -> expression . COMMA assignment_expression [ RPAREN COMMA ]
## primary_expression -> LPAREN expression . RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -1258,21 +1261,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ LPAREN PRE_NAME VAR_NAME SEMICOL
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
# Since we are saying "if this expression is complete",
@@ -1290,7 +1293,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LPAREN INT RPAREN LBRACE PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 327.
+## Ends in an error in state: 379.
##
## initializer_list -> initializer_list . COMMA option(designation) c_initializer [ RBRACE COMMA ]
## postfix_expression -> LPAREN type_name RPAREN LBRACE initializer_list . option(COMMA) RBRACE [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -1302,22 +1305,22 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ LPAREN INT RPAREN LBRACE PRE_NAM
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 320, spurious reduction of production c_initializer -> assignment_expression
-## In state 326, spurious reduction of production initializer_list -> option(designation) c_initializer
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 372, spurious reduction of production c_initializer -> assignment_expression
+## In state 378, spurious reduction of production initializer_list -> option(designation) c_initializer
##
# Let's ignore the fact that a comma can precede a closing brace.
@@ -1332,7 +1335,7 @@ then at this point, a closing brace '}' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LPAREN INT RPAREN LBRACE XOR_ASSIGN
##
-## Ends in an error in state: 306.
+## Ends in an error in state: 365.
##
## postfix_expression -> LPAREN type_name RPAREN LBRACE . initializer_list option(COMMA) RBRACE [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -1349,7 +1352,7 @@ At this point, an initializer is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LPAREN INT RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 387.
+## Ends in an error in state: 386.
##
## cast_expression -> LPAREN type_name RPAREN . cast_expression [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LEQ LEFT_ASSIGN LEFT HAT GT GEQ EQEQ EQ DIV_ASSIGN COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
## postfix_expression -> LPAREN type_name RPAREN . LBRACE initializer_list option(COMMA) RBRACE [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -1393,7 +1396,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME EQ TILDE XOR_ASSIGN
##
-## Ends in an error in state: 66.
+## Ends in an error in state: 153.
##
## unary_expression -> unary_operator . cast_expression [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LEQ LEFT_ASSIGN LEFT HAT GT GEQ EQEQ EQ DIV_ASSIGN COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -1410,7 +1413,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME AND XOR_ASSIGN
##
-## Ends in an error in state: 126.
+## Ends in an error in state: 213.
##
## and_expression -> and_expression AND . equality_expression [ SEMICOLON RPAREN RBRACK RBRACE QUESTION HAT COMMA COLON BARBAR BAR ANDAND AND ]
##
@@ -1419,7 +1422,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME AND XOR_ASSIGN
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME ANDAND XOR_ASSIGN
##
-## Ends in an error in state: 115.
+## Ends in an error in state: 202.
##
## logical_and_expression -> logical_and_expression ANDAND . inclusive_or_expression [ SEMICOLON RPAREN RBRACK RBRACE QUESTION COMMA COLON BARBAR ANDAND ]
##
@@ -1428,7 +1431,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME ANDAND XOR_ASS
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME BAR XOR_ASSIGN
##
-## Ends in an error in state: 117.
+## Ends in an error in state: 204.
##
## inclusive_or_expression -> inclusive_or_expression BAR . exclusive_or_expression [ SEMICOLON RPAREN RBRACK RBRACE QUESTION COMMA COLON BARBAR BAR ANDAND ]
##
@@ -1437,7 +1440,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME BAR XOR_ASSIGN
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME BARBAR XOR_ASSIGN
##
-## Ends in an error in state: 138.
+## Ends in an error in state: 225.
##
## logical_or_expression -> logical_or_expression BARBAR . logical_and_expression [ SEMICOLON RPAREN RBRACK RBRACE QUESTION COMMA COLON BARBAR ]
##
@@ -1446,7 +1449,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME BARBAR XOR_ASS
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME HAT XOR_ASSIGN
##
-## Ends in an error in state: 119.
+## Ends in an error in state: 206.
##
## exclusive_or_expression -> exclusive_or_expression HAT . and_expression [ SEMICOLON RPAREN RBRACK RBRACE QUESTION HAT COMMA COLON BARBAR BAR ANDAND ]
##
@@ -1455,7 +1458,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME HAT XOR_ASSIGN
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME LT XOR_ASSIGN
##
-## Ends in an error in state: 109.
+## Ends in an error in state: 196.
##
## relational_expression -> relational_expression relational_operator . shift_expression [ SEMICOLON RPAREN RBRACK RBRACE QUESTION NEQ LT LEQ HAT GT GEQ EQEQ COMMA COLON BARBAR BAR ANDAND AND ]
##
@@ -1464,7 +1467,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME LT XOR_ASSIGN
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME NEQ XOR_ASSIGN
##
-## Ends in an error in state: 123.
+## Ends in an error in state: 210.
##
## equality_expression -> equality_expression equality_operator . relational_expression [ SEMICOLON RPAREN RBRACK RBRACE QUESTION NEQ HAT EQEQ COMMA COLON BARBAR BAR ANDAND AND ]
##
@@ -1473,7 +1476,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME NEQ XOR_ASSIGN
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME PLUS XOR_ASSIGN
##
-## Ends in an error in state: 102.
+## Ends in an error in state: 189.
##
## additive_expression -> additive_expression additive_operator . multiplicative_expression [ SEMICOLON RPAREN RIGHT RBRACK RBRACE QUESTION PLUS NEQ MINUS LT LEQ LEFT HAT GT GEQ EQEQ COMMA COLON BARBAR BAR ANDAND AND ]
##
@@ -1482,7 +1485,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME PLUS XOR_ASSIG
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME RIGHT XOR_ASSIGN
##
-## Ends in an error in state: 91.
+## Ends in an error in state: 178.
##
## shift_expression -> shift_expression shift_operator . additive_expression [ SEMICOLON RPAREN RIGHT RBRACK RBRACE QUESTION NEQ LT LEQ LEFT HAT GT GEQ EQEQ COMMA COLON BARBAR BAR ANDAND AND ]
##
@@ -1491,7 +1494,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME RIGHT XOR_ASSI
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME STAR XOR_ASSIGN
##
-## Ends in an error in state: 96.
+## Ends in an error in state: 183.
##
## multiplicative_expression -> multiplicative_expression multiplicative_operator . cast_expression [ STAR SLASH SEMICOLON RPAREN RIGHT RBRACK RBRACE QUESTION PLUS PERCENT NEQ MINUS LT LEQ LEFT HAT GT GEQ EQEQ COMMA COLON BARBAR BAR ANDAND AND ]
##
@@ -1508,7 +1511,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME XOR_ASSIGN XOR_ASSIGN
##
-## Ends in an error in state: 87.
+## Ends in an error in state: 174.
##
## assignment_expression -> unary_expression assignment_operator . assignment_expression [ SEMICOLON RPAREN RBRACK RBRACE COMMA COLON ]
##
@@ -1525,7 +1528,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME COMMA XOR_ASSIGN
##
-## Ends in an error in state: 145.
+## Ends in an error in state: 232.
##
## argument_expression_list -> argument_expression_list COMMA . assignment_expression [ RPAREN COMMA ]
##
@@ -1546,7 +1549,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME DOT XOR_ASSIGN
##
-## Ends in an error in state: 151.
+## Ends in an error in state: 238.
##
## postfix_expression -> postfix_expression DOT . general_identifier [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -1555,7 +1558,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME DOT XOR_ASSIGN
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME PTR XOR_ASSIGN
##
-## Ends in an error in state: 72.
+## Ends in an error in state: 159.
##
## postfix_expression -> postfix_expression PTR . general_identifier [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -1572,7 +1575,7 @@ At this point, the name of a struct or union member is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME LBRACK PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 148.
+## Ends in an error in state: 235.
##
## expression -> expression . COMMA assignment_expression [ RBRACK COMMA ]
## postfix_expression -> postfix_expression LBRACK expression . RBRACK [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -1584,21 +1587,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME LBRACK PRE_NAM
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
# We know for sure that an array subscript expression has begun, and
@@ -1617,7 +1620,7 @@ then at this point, a closing bracket ']' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME LBRACK XOR_ASSIGN
##
-## Ends in an error in state: 147.
+## Ends in an error in state: 234.
##
## postfix_expression -> postfix_expression LBRACK . expression RBRACK [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -1632,7 +1635,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 144.
+## Ends in an error in state: 231.
##
## argument_expression_list -> argument_expression_list . COMMA assignment_expression [ RPAREN COMMA ]
## option(argument_expression_list) -> argument_expression_list . [ RPAREN ]
@@ -1644,21 +1647,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME LPAREN PRE_NAM
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 143, spurious reduction of production argument_expression_list -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 230, spurious reduction of production argument_expression_list -> assignment_expression
##
Up to this point, a list of expressions has been recognized:
@@ -1670,7 +1673,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 74.
+## Ends in an error in state: 161.
##
## postfix_expression -> postfix_expression LPAREN . option(argument_expression_list) RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
##
@@ -1688,7 +1691,7 @@ followed with a closing parenthesis ')', is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME QUESTION PRE_NAME VAR_NAME COLON XOR_ASSIGN
##
-## Ends in an error in state: 135.
+## Ends in an error in state: 222.
##
## conditional_expression -> logical_or_expression QUESTION expression COLON . conditional_expression [ SEMICOLON RPAREN RBRACK RBRACE COMMA COLON ]
##
@@ -1697,7 +1700,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME QUESTION PRE_N
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME QUESTION XOR_ASSIGN
##
-## Ends in an error in state: 113.
+## Ends in an error in state: 200.
##
## conditional_expression -> logical_or_expression QUESTION . expression COLON conditional_expression [ SEMICOLON RPAREN RBRACK RBRACE COMMA COLON ]
##
@@ -1712,7 +1715,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME QUESTION PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 131.
+## Ends in an error in state: 218.
##
## conditional_expression -> logical_or_expression QUESTION expression . COLON conditional_expression [ SEMICOLON RPAREN RBRACK RBRACE COMMA COLON ]
## expression -> expression . COMMA assignment_expression [ COMMA COLON ]
@@ -1724,21 +1727,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ PRE_NAME VAR_NAME QUESTION PRE_N
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
# gcc and clang simply expect a colon.
@@ -1755,7 +1758,7 @@ then at this point, a colon ':' is expected.
translation_unit_file: PACKED LPAREN PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 392.
+## Ends in an error in state: 391.
##
## argument_expression_list -> argument_expression_list . COMMA assignment_expression [ RPAREN COMMA ]
## attribute_specifier -> PACKED LPAREN argument_expression_list . RPAREN [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER RBRACK PRE_NAME PLUS PACKED NORETURN MINUS LPAREN LONG LBRACK LBRACE INT INLINE INC FLOAT EXTERN EQ ENUM DOUBLE DEC CONSTANT CONST COMMA COLON CHAR BUILTIN_VA_ARG BUILTIN_OFFSETOF BANG AUTO ATTRIBUTE AND ALIGNOF ALIGNAS ]
@@ -1767,21 +1770,21 @@ translation_unit_file: PACKED LPAREN PRE_NAME VAR_NAME SEMICOLON
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 143, spurious reduction of production argument_expression_list -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 230, spurious reduction of production argument_expression_list -> assignment_expression
##
Ill-formed $2 attribute.
@@ -1872,7 +1875,7 @@ At this point, one of the following is expected:
translation_unit_file: TYPEDEF PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 395.
+## Ends in an error in state: 394.
##
## declaration_specifiers_typedef -> TYPEDEF list(declaration_specifier_no_type) typedef_name list(declaration_specifier_no_type) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_type) -> list(declaration_specifier_no_type) . storage_class_specifier_no_typedef [ VOLATILE STATIC STAR SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN INLINE EXTERN CONST AUTO ATTRIBUTE ALIGNAS ]
@@ -1885,7 +1888,7 @@ translation_unit_file: TYPEDEF PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
translation_unit_file: PRE_NAME TYPEDEF_NAME TYPEDEF XOR_ASSIGN
##
-## Ends in an error in state: 404.
+## Ends in an error in state: 403.
##
## declaration_specifiers_typedef -> typedef_name list(declaration_specifier_no_type) TYPEDEF list(declaration_specifier_no_type) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_type) -> list(declaration_specifier_no_type) . storage_class_specifier_no_typedef [ VOLATILE STATIC STAR SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN INLINE EXTERN CONST AUTO ATTRIBUTE ALIGNAS ]
@@ -1898,7 +1901,7 @@ translation_unit_file: PRE_NAME TYPEDEF_NAME TYPEDEF XOR_ASSIGN
##
translation_unit_file: VOLATILE TYPEDEF PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 414.
+## Ends in an error in state: 413.
##
## declaration_specifiers_typedef -> rlist(declaration_specifier_no_type) TYPEDEF list(declaration_specifier_no_type) typedef_name list(declaration_specifier_no_type) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_type) -> list(declaration_specifier_no_type) . storage_class_specifier_no_typedef [ VOLATILE STATIC STAR SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN INLINE EXTERN CONST AUTO ATTRIBUTE ALIGNAS ]
@@ -1911,7 +1914,7 @@ translation_unit_file: VOLATILE TYPEDEF PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
translation_unit_file: VOLATILE PRE_NAME TYPEDEF_NAME TYPEDEF XOR_ASSIGN
##
-## Ends in an error in state: 420.
+## Ends in an error in state: 419.
##
## declaration_specifiers_typedef -> rlist(declaration_specifier_no_type) typedef_name list(declaration_specifier_no_type) TYPEDEF list(declaration_specifier_no_type) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_type) -> list(declaration_specifier_no_type) . storage_class_specifier_no_typedef [ VOLATILE STATIC STAR SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN INLINE EXTERN CONST AUTO ATTRIBUTE ALIGNAS ]
@@ -1924,7 +1927,7 @@ translation_unit_file: VOLATILE PRE_NAME TYPEDEF_NAME TYPEDEF XOR_ASSIGN
##
translation_unit_file: TYPEDEF INT XOR_ASSIGN
##
-## Ends in an error in state: 397.
+## Ends in an error in state: 396.
##
## declaration_specifiers_typedef -> TYPEDEF list(declaration_specifier_no_type) type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_typedef_name) -> list(declaration_specifier_no_typedef_name) . declaration_specifier_no_typedef_name [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC STAR SIGNED SHORT SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG INT INLINE FLOAT EXTERN ENUM DOUBLE CONST CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -1934,7 +1937,7 @@ translation_unit_file: TYPEDEF INT XOR_ASSIGN
##
translation_unit_file: INT TYPEDEF XOR_ASSIGN
##
-## Ends in an error in state: 408.
+## Ends in an error in state: 407.
##
## declaration_specifiers_typedef -> type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) TYPEDEF list(declaration_specifier_no_typedef_name) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_typedef_name) -> list(declaration_specifier_no_typedef_name) . declaration_specifier_no_typedef_name [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC STAR SIGNED SHORT SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG INT INLINE FLOAT EXTERN ENUM DOUBLE CONST CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -1944,7 +1947,7 @@ translation_unit_file: INT TYPEDEF XOR_ASSIGN
##
translation_unit_file: VOLATILE TYPEDEF INT XOR_ASSIGN
##
-## Ends in an error in state: 416.
+## Ends in an error in state: 415.
##
## declaration_specifiers_typedef -> rlist(declaration_specifier_no_type) TYPEDEF list(declaration_specifier_no_type) type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_typedef_name) -> list(declaration_specifier_no_typedef_name) . declaration_specifier_no_typedef_name [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC STAR SIGNED SHORT SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG INT INLINE FLOAT EXTERN ENUM DOUBLE CONST CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -1954,7 +1957,7 @@ translation_unit_file: VOLATILE TYPEDEF INT XOR_ASSIGN
##
translation_unit_file: VOLATILE INT TYPEDEF XOR_ASSIGN
##
-## Ends in an error in state: 424.
+## Ends in an error in state: 423.
##
## declaration_specifiers_typedef -> rlist(declaration_specifier_no_type) type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) TYPEDEF list(declaration_specifier_no_typedef_name) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_typedef_name) -> list(declaration_specifier_no_typedef_name) . declaration_specifier_no_typedef_name [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC STAR SIGNED SHORT SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG INT INLINE FLOAT EXTERN ENUM DOUBLE CONST CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -2007,7 +2010,7 @@ translation_unit_file: TYPEDEF XOR_ASSIGN
##
translation_unit_file: VOLATILE TYPEDEF XOR_ASSIGN
##
-## Ends in an error in state: 412.
+## Ends in an error in state: 411.
##
## declaration_specifiers_typedef -> rlist(declaration_specifier_no_type) TYPEDEF list(declaration_specifier_no_type) . typedef_name list(declaration_specifier_no_type) [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers_typedef -> rlist(declaration_specifier_no_type) TYPEDEF list(declaration_specifier_no_type) . type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2041,7 +2044,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN VOLATILE XOR_ASSIGN
##
-## Ends in an error in state: 222.
+## Ends in an error in state: 133.
##
## declaration_specifiers(parameter_declaration) -> rlist(declaration_specifier_no_type) . typedef_name list(declaration_specifier_no_type) [ STAR RPAREN PRE_NAME LPAREN LBRACK COMMA ]
## declaration_specifiers(parameter_declaration) -> rlist(declaration_specifier_no_type) . type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) [ STAR RPAREN PRE_NAME LPAREN LBRACK COMMA ]
@@ -2053,7 +2056,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN VOLATILE XOR_ASSIGN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 214, spurious reduction of production rlist(declaration_specifier_no_type) -> type_qualifier_noattr
+## In state 125, spurious reduction of production rlist(declaration_specifier_no_type) -> type_qualifier_noattr
##
# Analogous to the above, except we are in the context of a parameter declaration,
@@ -2077,7 +2080,7 @@ At this point, one of the following is expected:
translation_unit_file: PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 402.
+## Ends in an error in state: 401.
##
## declaration_specifiers(declaration(external_declaration)) -> typedef_name list(declaration_specifier_no_type) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers_typedef -> typedef_name list(declaration_specifier_no_type) . TYPEDEF list(declaration_specifier_no_type) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2091,7 +2094,7 @@ translation_unit_file: PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
translation_unit_file: VOLATILE PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 418.
+## Ends in an error in state: 417.
##
## declaration_specifiers(declaration(external_declaration)) -> rlist(declaration_specifier_no_type) typedef_name list(declaration_specifier_no_type) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers_typedef -> rlist(declaration_specifier_no_type) typedef_name list(declaration_specifier_no_type) . TYPEDEF list(declaration_specifier_no_type) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2105,7 +2108,7 @@ translation_unit_file: VOLATILE PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
translation_unit_file: INT XOR_ASSIGN
##
-## Ends in an error in state: 406.
+## Ends in an error in state: 405.
##
## declaration_specifiers(declaration(external_declaration)) -> type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers_typedef -> type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . TYPEDEF list(declaration_specifier_no_typedef_name) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2116,7 +2119,7 @@ translation_unit_file: INT XOR_ASSIGN
##
translation_unit_file: VOLATILE INT XOR_ASSIGN
##
-## Ends in an error in state: 422.
+## Ends in an error in state: 421.
##
## declaration_specifiers(declaration(external_declaration)) -> rlist(declaration_specifier_no_type) type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers_typedef -> rlist(declaration_specifier_no_type) type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . TYPEDEF list(declaration_specifier_no_typedef_name) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2177,7 +2180,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 201.
+## Ends in an error in state: 112.
##
## declaration_specifiers(parameter_declaration) -> typedef_name list(declaration_specifier_no_type) . [ STAR RPAREN PRE_NAME LPAREN LBRACK COMMA ]
## list(declaration_specifier_no_type) -> list(declaration_specifier_no_type) . storage_class_specifier_no_typedef [ VOLATILE STATIC STAR RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LBRACK INLINE EXTERN CONST COMMA AUTO ATTRIBUTE ALIGNAS ]
@@ -2190,7 +2193,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME TYPEDEF_NAME XOR_AS
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN VOLATILE PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 224.
+## Ends in an error in state: 135.
##
## declaration_specifiers(parameter_declaration) -> rlist(declaration_specifier_no_type) typedef_name list(declaration_specifier_no_type) . [ STAR RPAREN PRE_NAME LPAREN LBRACK COMMA ]
## list(declaration_specifier_no_type) -> list(declaration_specifier_no_type) . storage_class_specifier_no_typedef [ VOLATILE STATIC STAR RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LBRACK INLINE EXTERN CONST COMMA AUTO ATTRIBUTE ALIGNAS ]
@@ -2203,7 +2206,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN VOLATILE PRE_NAME TYPEDEF_NA
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT XOR_ASSIGN
##
-## Ends in an error in state: 207.
+## Ends in an error in state: 118.
##
## declaration_specifiers(parameter_declaration) -> type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . [ STAR RPAREN PRE_NAME LPAREN LBRACK COMMA ]
## list(declaration_specifier_no_typedef_name) -> list(declaration_specifier_no_typedef_name) . declaration_specifier_no_typedef_name [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC STAR SIGNED SHORT RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK INT INLINE FLOAT EXTERN ENUM DOUBLE CONST COMMA CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -2213,7 +2216,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT XOR_ASSIGN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN VOLATILE INT XOR_ASSIGN
##
-## Ends in an error in state: 226.
+## Ends in an error in state: 137.
##
## declaration_specifiers(parameter_declaration) -> rlist(declaration_specifier_no_type) type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . [ STAR RPAREN PRE_NAME LPAREN LBRACK COMMA ]
## list(declaration_specifier_no_typedef_name) -> list(declaration_specifier_no_typedef_name) . declaration_specifier_no_typedef_name [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC STAR SIGNED SHORT RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK INT INLINE FLOAT EXTERN ENUM DOUBLE CONST COMMA CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -2262,7 +2265,7 @@ At this point, one of the following is expected:
translation_unit_file: VOLATILE XOR_ASSIGN
##
-## Ends in an error in state: 410.
+## Ends in an error in state: 409.
##
## declaration_specifiers(declaration(external_declaration)) -> rlist(declaration_specifier_no_type) . typedef_name list(declaration_specifier_no_type) [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers(declaration(external_declaration)) -> rlist(declaration_specifier_no_type) . type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2278,7 +2281,7 @@ translation_unit_file: VOLATILE XOR_ASSIGN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 214, spurious reduction of production rlist(declaration_specifier_no_type) -> type_qualifier_noattr
+## In state 125, spurious reduction of production rlist(declaration_specifier_no_type) -> type_qualifier_noattr
##
# We have seen some specifiers or qualifiers. We have probably seen at least
@@ -2307,7 +2310,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE VOLATILE XOR_ASSIGN
##
-## Ends in an error in state: 519.
+## Ends in an error in state: 518.
##
## declaration_specifiers(declaration(block_item)) -> rlist(declaration_specifier_no_type) . typedef_name list(declaration_specifier_no_type) [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers(declaration(block_item)) -> rlist(declaration_specifier_no_type) . type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2323,7 +2326,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 214, spurious reduction of production rlist(declaration_specifier_no_type) -> type_qualifier_noattr
+## In state 125, spurious reduction of production rlist(declaration_specifier_no_type) -> type_qualifier_noattr
##
# Identical to the previous one, except we are not at the top level,
# so we know this cannot be the beginning of a function definition.
@@ -2338,7 +2341,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE PRE_NAME TYPEDEF_NAME VOLATILE XOR_ASSIGN
##
-## Ends in an error in state: 516.
+## Ends in an error in state: 515.
##
## declaration_specifiers(declaration(block_item)) -> typedef_name list(declaration_specifier_no_type) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers_typedef -> typedef_name list(declaration_specifier_no_type) . TYPEDEF list(declaration_specifier_no_type) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2352,7 +2355,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE VOLATILE PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 521.
+## Ends in an error in state: 520.
##
## declaration_specifiers(declaration(block_item)) -> rlist(declaration_specifier_no_type) typedef_name list(declaration_specifier_no_type) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers_typedef -> rlist(declaration_specifier_no_type) typedef_name list(declaration_specifier_no_type) . TYPEDEF list(declaration_specifier_no_type) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2366,7 +2369,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE INT XOR_ASSIGN
##
-## Ends in an error in state: 518.
+## Ends in an error in state: 517.
##
## declaration_specifiers(declaration(block_item)) -> type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers_typedef -> type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . TYPEDEF list(declaration_specifier_no_typedef_name) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2377,7 +2380,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE VOLATILE INT XOR_ASSIGN
##
-## Ends in an error in state: 523.
+## Ends in an error in state: 522.
##
## declaration_specifiers(declaration(block_item)) -> rlist(declaration_specifier_no_type) type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers_typedef -> rlist(declaration_specifier_no_type) type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . TYPEDEF list(declaration_specifier_no_typedef_name) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -2417,7 +2420,7 @@ At this point, one of the following is expected:
translation_unit_file: UNION LBRACE PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 181.
+## Ends in an error in state: 92.
##
## struct_declaration -> specifier_qualifier_list(struct_declaration) . option(struct_declarator_list) SEMICOLON [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT SIGNED SHORT RESTRICT RBRACE PRE_NAME PACKED LONG INT FLOAT ENUM DOUBLE CONST CHAR ATTRIBUTE ALIGNAS ]
##
@@ -2428,7 +2431,7 @@ translation_unit_file: UNION LBRACE PRE_NAME TYPEDEF_NAME XOR_ASSIGN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 167, spurious reduction of production specifier_qualifier_list(struct_declaration) -> typedef_name option(type_qualifier_list)
+## In state 78, spurious reduction of production specifier_qualifier_list(struct_declaration) -> typedef_name option(type_qualifier_list)
##
# We have (spuriously) recognized a specifier_qualifier_list,
@@ -2474,19 +2477,19 @@ translation_unit_file: UNION LBRACE LONG COLON CONSTANT RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 67, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 154, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
## In state 292, spurious reduction of production struct_declarator -> option(declarator) COLON conditional_expression
## In state 294, spurious reduction of production struct_declarator_list -> struct_declarator
##
@@ -2573,7 +2576,7 @@ then at this point, one of the following is expected:
translation_unit_file: UNION LBRACE VOLATILE ADD_ASSIGN
##
-## Ends in an error in state: 175.
+## Ends in an error in state: 86.
##
## option(type_qualifier_list) -> type_qualifier_list . [ VOLATILE RESTRICT PACKED CONST ATTRIBUTE ALIGNAS ]
## specifier_qualifier_list(struct_declaration) -> type_qualifier_list . typedef_name option(type_qualifier_list) [ STAR SEMICOLON PRE_NAME LPAREN COLON ]
@@ -2596,7 +2599,7 @@ At this point, one of the following is expected:
translation_unit_file: UNION LBRACE XOR_ASSIGN
##
-## Ends in an error in state: 164.
+## Ends in an error in state: 75.
##
## struct_declaration_list -> struct_declaration_list . struct_declaration [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT SIGNED SHORT RESTRICT RBRACE PRE_NAME PACKED LONG INT FLOAT ENUM DOUBLE CONST CHAR ATTRIBUTE ALIGNAS ]
## struct_or_union_specifier -> struct_or_union attribute_specifier_list option(other_identifier) LBRACE struct_declaration_list . RBRACE [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF STRUCT STATIC STAR SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK INT INLINE FLOAT EXTERN ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -2616,7 +2619,7 @@ At this point, one of the following is expected:
translation_unit_file: UNION XOR_ASSIGN
##
-## Ends in an error in state: 161.
+## Ends in an error in state: 72.
##
## struct_or_union_specifier -> struct_or_union attribute_specifier_list . option(other_identifier) LBRACE struct_declaration_list RBRACE [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF STRUCT STATIC STAR SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK INT INLINE FLOAT EXTERN ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
## struct_or_union_specifier -> struct_or_union attribute_specifier_list . general_identifier [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF STRUCT STATIC STAR SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK INT INLINE FLOAT EXTERN ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -2628,7 +2631,7 @@ translation_unit_file: UNION XOR_ASSIGN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 160, spurious reduction of production attribute_specifier_list ->
+## In state 71, spurious reduction of production attribute_specifier_list ->
##
# gcc expects '{'.
@@ -2661,7 +2664,7 @@ translation_unit_file: INT LPAREN PRE_NAME VAR_NAME SEMICOLON
## In state 261, spurious reduction of production declarator -> declarator_noattrend attribute_specifier_list
##
-Up to this point, a declarator have been recognized:
+Up to this point, a declarator has been recognized:
$0
If this declarator is complete,
then at this point, a closing parenthesis ')' is expected.
@@ -2670,7 +2673,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 187.
+## Ends in an error in state: 98.
##
## direct_declarator -> LPAREN save_context . declarator RPAREN [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK LBRACE INT INLINE FLOAT EXTERN EQ ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
##
@@ -2706,7 +2709,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 193.
+## Ends in an error in state: 104.
##
## context_parameter_type_list -> save_context . parameter_type_list save_context [ RPAREN ]
## direct_declarator -> direct_declarator LPAREN save_context . option(identifier_list) RPAREN [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK LBRACE INT INLINE FLOAT EXTERN EQ ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -2730,7 +2733,7 @@ followed with a closing parenthesis ')', is expected.
translation_unit_file: INT STAR RPAREN
##
-## Ends in an error in state: 190.
+## Ends in an error in state: 101.
##
## declarator_noattrend -> list(pointer1) STAR option(type_qualifier_list) . direct_declarator [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LONG LBRACE INT INLINE FLOAT EXTERN EQ ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
## list(pointer1) -> list(pointer1) STAR option(type_qualifier_list) . [ STAR ]
@@ -2763,7 +2766,7 @@ At this point, one of the following is expected:
translation_unit_file: TYPEDEF INT PRE_NAME VAR_NAME XOR_ASSIGN
##
-## Ends in an error in state: 535.
+## Ends in an error in state: 534.
##
## option(typedef_declarator_list) -> typedef_declarator_list . [ SEMICOLON ]
## typedef_declarator_list -> typedef_declarator_list . COMMA typedef_declarator [ SEMICOLON COMMA ]
@@ -2778,9 +2781,9 @@ translation_unit_file: TYPEDEF INT PRE_NAME VAR_NAME XOR_ASSIGN
## In state 255, spurious reduction of production declarator_noattrend -> direct_declarator
## In state 260, spurious reduction of production attribute_specifier_list ->
## In state 261, spurious reduction of production declarator -> declarator_noattrend attribute_specifier_list
-## In state 539, spurious reduction of production declare_typename(declarator) -> declarator
-## In state 538, spurious reduction of production typedef_declarator -> declare_typename(declarator)
-## In state 540, spurious reduction of production typedef_declarator_list -> typedef_declarator
+## In state 538, spurious reduction of production declare_typename(declarator) -> declarator
+## In state 537, spurious reduction of production typedef_declarator -> declare_typename(declarator)
+## In state 539, spurious reduction of production typedef_declarator_list -> typedef_declarator
##
# Because attribute_specifier_list, declarator and declarator_noattrend have been marked
@@ -2806,7 +2809,7 @@ then at this point, a semicolon ';' is expected.
translation_unit_file: TYPEDEF INT PRE_NAME VAR_NAME COMMA XOR_ASSIGN
##
-## Ends in an error in state: 536.
+## Ends in an error in state: 535.
##
## typedef_declarator_list -> typedef_declarator_list COMMA . typedef_declarator [ SEMICOLON COMMA ]
##
@@ -2835,7 +2838,7 @@ followed with a closing parenthesis ')', is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM CONST XOR_ASSIGN
##
-## Ends in an error in state: 451.
+## Ends in an error in state: 450.
##
## asm_attributes -> CONST . asm_attributes [ LPAREN ]
##
@@ -2844,7 +2847,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM VOLATILE XOR_ASSIGN
##
-## Ends in an error in state: 450.
+## Ends in an error in state: 449.
##
## asm_attributes -> VOLATILE . asm_attributes [ LPAREN ]
##
@@ -2853,7 +2856,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM XOR_ASSIGN
##
-## Ends in an error in state: 449.
+## Ends in an error in state: 448.
##
## asm_statement -> ASM . asm_attributes LPAREN string_literals_list asm_arguments RPAREN SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -2870,7 +2873,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON COLON COLON STRING_LITERAL COMMA XOR_ASSIGN
##
-## Ends in an error in state: 475.
+## Ends in an error in state: 474.
##
## asm_flags -> asm_flags COMMA . string_literals_list [ RPAREN COMMA ]
##
@@ -2882,7 +2885,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
# first(asm_flags) = STRING_LITERAL
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON COLON COLON XOR_ASSIGN
##
-## Ends in an error in state: 472.
+## Ends in an error in state: 471.
##
## asm_arguments -> COLON asm_operands COLON asm_operands COLON . asm_flags [ RPAREN ]
##
@@ -2902,7 +2905,7 @@ Examples of clobbered resources:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON COLON COLON STRING_LITERAL XOR_ASSIGN
##
-## Ends in an error in state: 474.
+## Ends in an error in state: 473.
##
## asm_arguments -> COLON asm_operands COLON asm_operands COLON asm_flags . [ RPAREN ]
## asm_flags -> asm_flags . COMMA string_literals_list [ RPAREN COMMA ]
@@ -2914,7 +2917,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 473, spurious reduction of production asm_flags -> string_literals_list
+## In state 472, spurious reduction of production asm_flags -> string_literals_list
##
# Let's ignore the possibility of concatenating string literals.
@@ -2931,7 +2934,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON STRING_LITERAL LPAREN CONSTANT RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 469.
+## Ends in an error in state: 468.
##
## asm_arguments -> COLON asm_operands . [ RPAREN ]
## asm_arguments -> COLON asm_operands . COLON asm_operands [ RPAREN ]
@@ -2944,7 +2947,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 461, spurious reduction of production asm_operands -> asm_operands_ne
+## In state 460, spurious reduction of production asm_operands -> asm_operands_ne
##
# We have seen one COLON, hence the outputs. (The list of outputs may be empty.)
@@ -2961,7 +2964,7 @@ then at this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON COLON XOR_ASSIGN
##
-## Ends in an error in state: 471.
+## Ends in an error in state: 470.
##
## asm_arguments -> COLON asm_operands COLON asm_operands . [ RPAREN ]
## asm_arguments -> COLON asm_operands COLON asm_operands . COLON asm_flags [ RPAREN ]
@@ -2973,7 +2976,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 470, spurious reduction of production asm_operands ->
+## In state 469, spurious reduction of production asm_operands ->
##
# We have seen two COLONs, hence the outputs and inputs. (The list of inputs may be empty.)
@@ -2993,7 +2996,7 @@ then at this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON LBRACK PRE_NAME VAR_NAME RBRACK XOR_ASSIGN
##
-## Ends in an error in state: 464.
+## Ends in an error in state: 463.
##
## asm_operand -> asm_op_name . string_literals_list LPAREN expression RPAREN [ RPAREN COMMA COLON ]
##
@@ -3012,7 +3015,7 @@ At this point, a string literal, representing a constraint, is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON LBRACK PRE_NAME VAR_NAME XOR_ASSIGN
##
-## Ends in an error in state: 459.
+## Ends in an error in state: 458.
##
## asm_op_name -> LBRACK general_identifier . RBRACK [ STRING_LITERAL ]
##
@@ -3027,7 +3030,7 @@ At this point, a closing bracket ']' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON LBRACK XOR_ASSIGN
##
-## Ends in an error in state: 458.
+## Ends in an error in state: 457.
##
## asm_op_name -> LBRACK . general_identifier RBRACK [ STRING_LITERAL ]
##
@@ -3042,7 +3045,7 @@ At this point, an identifier is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON STRING_LITERAL LPAREN CONSTANT RPAREN COMMA XOR_ASSIGN
##
-## Ends in an error in state: 462.
+## Ends in an error in state: 461.
##
## asm_operands_ne -> asm_operands_ne COMMA . asm_operand [ RPAREN COMMA COLON ]
##
@@ -3059,7 +3062,7 @@ At this point, an assembly operand is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON STRING_LITERAL LPAREN PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 467.
+## Ends in an error in state: 466.
##
## asm_operand -> asm_op_name string_literals_list LPAREN expression . RPAREN [ RPAREN COMMA COLON ]
## expression -> expression . COMMA assignment_expression [ RPAREN COMMA ]
@@ -3071,21 +3074,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
Ill-formed assembly operand.
@@ -3098,7 +3101,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON STRING_LITERAL LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 466.
+## Ends in an error in state: 465.
##
## asm_operand -> asm_op_name string_literals_list LPAREN . expression RPAREN [ RPAREN COMMA COLON ]
##
@@ -3113,7 +3116,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL COLON STRING_LITERAL XOR_ASSIGN
##
-## Ends in an error in state: 465.
+## Ends in an error in state: 464.
##
## asm_operand -> asm_op_name string_literals_list . LPAREN expression RPAREN [ RPAREN COMMA COLON ]
## string_literals_list -> string_literals_list . STRING_LITERAL [ STRING_LITERAL LPAREN ]
@@ -3133,7 +3136,7 @@ followed with an expression and a closing parenthesis ')', is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL XOR_ASSIGN
##
-## Ends in an error in state: 456.
+## Ends in an error in state: 455.
##
## asm_statement -> ASM asm_attributes LPAREN string_literals_list . asm_arguments RPAREN SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
## string_literals_list -> string_literals_list . STRING_LITERAL [ STRING_LITERAL RPAREN COLON ]
@@ -3155,7 +3158,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 455.
+## Ends in an error in state: 454.
##
## asm_statement -> ASM asm_attributes LPAREN . string_literals_list asm_arguments RPAREN SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3170,7 +3173,7 @@ At this point, a string literal, representing an instruction, is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE BREAK XOR_ASSIGN
##
-## Ends in an error in state: 447.
+## Ends in an error in state: 446.
##
## jump_statement -> BREAK . SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3179,7 +3182,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE CONTINUE XOR_ASSIGN
##
-## Ends in an error in state: 442.
+## Ends in an error in state: 441.
##
## jump_statement -> CONTINUE . SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3188,7 +3191,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE DO SEMICOLON WHILE LPAREN PRE_NAME VAR_NAME RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 566.
+## Ends in an error in state: 565.
##
## iteration_statement -> save_context do_statement1 WHILE LPAREN expression RPAREN . SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3197,7 +3200,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE GOTO PRE_NAME VAR_NAME XOR_ASSIGN
##
-## Ends in an error in state: 438.
+## Ends in an error in state: 437.
##
## jump_statement -> GOTO general_identifier . SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3206,7 +3209,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE ASM LPAREN STRING_LITERAL RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 479.
+## Ends in an error in state: 478.
##
## asm_statement -> ASM asm_attributes LPAREN string_literals_list asm_arguments RPAREN . SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3221,7 +3224,7 @@ At this point, a semicolon ';' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE CASE CONSTANT COLON XOR_ASSIGN
##
-## Ends in an error in state: 446.
+## Ends in an error in state: 445.
##
## labeled_statement -> CASE conditional_expression COLON . statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3230,7 +3233,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE DEFAULT COLON XOR_ASSIGN
##
-## Ends in an error in state: 441.
+## Ends in an error in state: 440.
##
## labeled_statement -> DEFAULT COLON . statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3239,7 +3242,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE PRE_NAME VAR_NAME COLON XOR_ASSIGN
##
-## Ends in an error in state: 495.
+## Ends in an error in state: 494.
##
## labeled_statement -> general_identifier COLON . statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3256,7 +3259,7 @@ At this point, a statement is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE CASE CONSTANT SEMICOLON
##
-## Ends in an error in state: 445.
+## Ends in an error in state: 444.
##
## labeled_statement -> CASE conditional_expression . COLON statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3267,19 +3270,19 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 67, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 154, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
##
Ill-formed labeled statement.
@@ -3292,7 +3295,7 @@ then at this point, a colon ':' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE CASE XOR_ASSIGN
##
-## Ends in an error in state: 444.
+## Ends in an error in state: 443.
##
## labeled_statement -> CASE . conditional_expression COLON statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3307,7 +3310,7 @@ At this point, a constant expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE DEFAULT XOR_ASSIGN
##
-## Ends in an error in state: 440.
+## Ends in an error in state: 439.
##
## labeled_statement -> DEFAULT . COLON statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3316,7 +3319,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE DO PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 494.
+## Ends in an error in state: 493.
##
## labeled_statement -> general_identifier . COLON statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3333,7 +3336,7 @@ At this point, a colon ':' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE DO SEMICOLON WHILE LPAREN PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 565.
+## Ends in an error in state: 564.
##
## expression -> expression . COMMA assignment_expression [ RPAREN COMMA ]
## iteration_statement -> save_context do_statement1 WHILE LPAREN expression . RPAREN SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
@@ -3345,21 +3348,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
Ill-formed 'do' ... 'while' statement.
@@ -3372,7 +3375,7 @@ then at this point, a closing parenthesis ')' and a semicolon ';' are expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE DO SEMICOLON WHILE LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 564.
+## Ends in an error in state: 563.
##
## iteration_statement -> save_context do_statement1 WHILE LPAREN . expression RPAREN SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3387,7 +3390,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE DO SEMICOLON WHILE XOR_ASSIGN
##
-## Ends in an error in state: 563.
+## Ends in an error in state: 562.
##
## iteration_statement -> save_context do_statement1 WHILE . LPAREN expression RPAREN SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3402,7 +3405,7 @@ At this point, an opening parenthesis '(' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE DO SEMICOLON XOR_ASSIGN
##
-## Ends in an error in state: 562.
+## Ends in an error in state: 561.
##
## iteration_statement -> save_context do_statement1 . WHILE LPAREN expression RPAREN SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3423,7 +3426,7 @@ At this point, a 'while' keyword is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE DO XOR_ASSIGN
##
-## Ends in an error in state: 558.
+## Ends in an error in state: 557.
##
## do_statement1 -> save_context DO . statement [ WHILE ]
##
@@ -3440,7 +3443,7 @@ At this point, a statement (the loop body) is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE FOR LPAREN SEMICOLON SEMICOLON RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 528.
+## Ends in an error in state: 527.
##
## iteration_statement -> save_context FOR LPAREN for_statement_header optional(expression,SEMICOLON) optional(expression,RPAREN) . statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3455,7 +3458,7 @@ At this point, a statement (the loop body) is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE FOR LPAREN SEMICOLON SEMICOLON PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 530.
+## Ends in an error in state: 529.
##
## expression -> expression . COMMA assignment_expression [ RPAREN COMMA ]
## optional(expression,RPAREN) -> expression . RPAREN [ WHILE TILDE SWITCH STRING_LITERAL STAR SIZEOF SEMICOLON RETURN PRE_NAME PLUS MINUS LPAREN LBRACE INC IF GOTO FOR DO DEFAULT DEC CONTINUE CONSTANT CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG ASM AND ALIGNOF ]
@@ -3467,21 +3470,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
# The use of optional(expression,RPAREN) tells us that we are in a FOR statement.
@@ -3497,7 +3500,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE FOR LPAREN SEMICOLON SEMICOLON XOR_ASSIGN
##
-## Ends in an error in state: 526.
+## Ends in an error in state: 525.
##
## iteration_statement -> save_context FOR LPAREN for_statement_header optional(expression,SEMICOLON) . optional(expression,RPAREN) statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3517,7 +3520,7 @@ followed with a closing parenthesis ')', is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE FOR LPAREN SEMICOLON XOR_ASSIGN
##
-## Ends in an error in state: 525.
+## Ends in an error in state: 524.
##
## iteration_statement -> save_context FOR LPAREN for_statement_header . optional(expression,SEMICOLON) optional(expression,RPAREN) statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3536,7 +3539,7 @@ followed with a semicolon ';', is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE FOR LPAREN PRE_NAME VAR_NAME RPAREN
##
-## Ends in an error in state: 532.
+## Ends in an error in state: 531.
##
## expression -> expression . COMMA assignment_expression [ SEMICOLON COMMA ]
## optional(expression,SEMICOLON) -> expression . SEMICOLON [ TILDE STRING_LITERAL STAR SIZEOF SEMICOLON RPAREN PRE_NAME PLUS MINUS LPAREN INC DEC CONSTANT BUILTIN_VA_ARG BUILTIN_OFFSETOF BANG AND ALIGNOF ]
@@ -3548,21 +3551,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
# At the time of writing, optional(expression,SEMICOLON) is used only in FOR
@@ -3578,7 +3581,7 @@ then at this point, a semicolon ';' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE FOR LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 513.
+## Ends in an error in state: 512.
##
## iteration_statement -> save_context FOR LPAREN . for_statement_header optional(expression,SEMICOLON) optional(expression,RPAREN) statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3599,7 +3602,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE FOR XOR_ASSIGN
##
-## Ends in an error in state: 512.
+## Ends in an error in state: 511.
##
## iteration_statement -> save_context FOR . LPAREN for_statement_header optional(expression,SEMICOLON) optional(expression,RPAREN) statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3614,7 +3617,7 @@ At this point, an opening parenthesis '(' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE GOTO XOR_ASSIGN
##
-## Ends in an error in state: 437.
+## Ends in an error in state: 436.
##
## jump_statement -> GOTO . general_identifier SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3629,7 +3632,7 @@ At this point, an identifier (a 'goto' label) is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE DO IF LPAREN CONSTANT RPAREN SEMICOLON ELSE XOR_ASSIGN
##
-## Ends in an error in state: 560.
+## Ends in an error in state: 559.
##
## selection_statement -> save_context ifelse_statement1 . statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3644,7 +3647,7 @@ At this point, a statement is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE IF LPAREN PRE_NAME VAR_NAME RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 509.
+## Ends in an error in state: 508.
##
## ifelse_statement1 -> IF LPAREN expression RPAREN save_context . statement ELSE [ WHILE TILDE SWITCH STRING_LITERAL STAR SIZEOF SEMICOLON RETURN PRE_NAME PLUS MINUS LPAREN LBRACE INC IF GOTO FOR DO DEFAULT DEC CONTINUE CONSTANT CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG ASM AND ALIGNOF ]
## selection_statement -> save_context IF LPAREN expression RPAREN save_context . statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
@@ -3660,7 +3663,7 @@ At this point, a statement is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE IF LPAREN PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 507.
+## Ends in an error in state: 506.
##
## expression -> expression . COMMA assignment_expression [ RPAREN COMMA ]
## ifelse_statement1 -> IF LPAREN expression . RPAREN save_context statement ELSE [ WHILE TILDE SWITCH STRING_LITERAL STAR SIZEOF SEMICOLON RETURN PRE_NAME PLUS MINUS LPAREN LBRACE INC IF GOTO FOR DO DEFAULT DEC CONTINUE CONSTANT CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG ASM AND ALIGNOF ]
@@ -3673,21 +3676,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
Ill-formed 'if' statement.
@@ -3700,7 +3703,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE IF LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 506.
+## Ends in an error in state: 505.
##
## ifelse_statement1 -> IF LPAREN . expression RPAREN save_context statement ELSE [ WHILE TILDE SWITCH STRING_LITERAL STAR SIZEOF SEMICOLON RETURN PRE_NAME PLUS MINUS LPAREN LBRACE INC IF GOTO FOR DO DEFAULT DEC CONTINUE CONSTANT CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG ASM AND ALIGNOF ]
## selection_statement -> save_context IF LPAREN . expression RPAREN save_context statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
@@ -3716,7 +3719,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE IF XOR_ASSIGN
##
-## Ends in an error in state: 505.
+## Ends in an error in state: 504.
##
## ifelse_statement1 -> IF . LPAREN expression RPAREN save_context statement ELSE [ WHILE TILDE SWITCH STRING_LITERAL STAR SIZEOF SEMICOLON RETURN PRE_NAME PLUS MINUS LPAREN LBRACE INC IF GOTO FOR DO DEFAULT DEC CONTINUE CONSTANT CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG ASM AND ALIGNOF ]
## selection_statement -> save_context IF . LPAREN expression RPAREN save_context statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
@@ -3732,7 +3735,7 @@ At this point, an opening parenthesis '(' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE SWITCH LPAREN PRE_NAME VAR_NAME RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 503.
+## Ends in an error in state: 502.
##
## selection_statement -> save_context SWITCH LPAREN expression RPAREN . statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3756,7 +3759,7 @@ enclosed within braces '{' and '}'.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE SWITCH LPAREN PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 502.
+## Ends in an error in state: 501.
##
## expression -> expression . COMMA assignment_expression [ RPAREN COMMA ]
## selection_statement -> save_context SWITCH LPAREN expression . RPAREN statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
@@ -3768,21 +3771,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
Ill-formed 'switch' statement.
@@ -3795,7 +3798,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE SWITCH LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 501.
+## Ends in an error in state: 500.
##
## selection_statement -> save_context SWITCH LPAREN . expression RPAREN statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3810,7 +3813,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE SWITCH XOR_ASSIGN
##
-## Ends in an error in state: 500.
+## Ends in an error in state: 499.
##
## selection_statement -> save_context SWITCH . LPAREN expression RPAREN statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3825,7 +3828,7 @@ At this point, an opening parenthesis '(' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE WHILE LPAREN PRE_NAME VAR_NAME RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 487.
+## Ends in an error in state: 486.
##
## iteration_statement -> save_context WHILE LPAREN expression RPAREN . statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3840,7 +3843,7 @@ At this point, a statement (the loop body) is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE WHILE LPAREN PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 486.
+## Ends in an error in state: 485.
##
## expression -> expression . COMMA assignment_expression [ RPAREN COMMA ]
## iteration_statement -> save_context WHILE LPAREN expression . RPAREN statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
@@ -3852,21 +3855,21 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
Ill-formed 'while' statement.
@@ -3879,7 +3882,7 @@ then at this point, a closing parenthesis ')' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE WHILE LPAREN XOR_ASSIGN
##
-## Ends in an error in state: 485.
+## Ends in an error in state: 484.
##
## iteration_statement -> save_context WHILE LPAREN . expression RPAREN statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3894,7 +3897,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE WHILE XOR_ASSIGN
##
-## Ends in an error in state: 484.
+## Ends in an error in state: 483.
##
## iteration_statement -> save_context WHILE . LPAREN expression RPAREN statement [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3909,7 +3912,7 @@ At this point, an opening parenthesis '(' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE XOR_ASSIGN
##
-## Ends in an error in state: 428.
+## Ends in an error in state: 427.
##
## block_item_list -> option(block_item_list) . block_item [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
## compound_statement -> save_context LBRACE option(block_item_list) . RBRACE [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN EOF ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
@@ -3937,7 +3940,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE RETURN XOR_ASSIGN
##
-## Ends in an error in state: 429.
+## Ends in an error in state: 428.
##
## jump_statement -> RETURN . option(expression) SEMICOLON [ WHILE VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL TYPEDEF TILDE SWITCH STRUCT STRING_LITERAL STATIC STAR SIZEOF SIGNED SHORT SEMICOLON RETURN RESTRICT REGISTER RBRACE PRE_NAME PRAGMA PLUS PACKED NORETURN MINUS LPAREN LONG LBRACE INT INLINE INC IF GOTO FOR FLOAT EXTERN ENUM ELSE DOUBLE DO DEFAULT DEC CONTINUE CONSTANT CONST CHAR CASE BUILTIN_VA_ARG BUILTIN_OFFSETOF BREAK BANG AUTO ATTRIBUTE ASM AND ALIGNOF ALIGNAS ]
##
@@ -3956,7 +3959,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE STRING_LITERAL RPAREN
##
-## Ends in an error in state: 432.
+## Ends in an error in state: 431.
##
## expression -> expression . COMMA assignment_expression [ SEMICOLON COMMA ]
## option(expression) -> expression . [ SEMICOLON ]
@@ -3968,23 +3971,23 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 68, spurious reduction of production primary_expression -> string_literals_list
-## In state 70, spurious reduction of production postfix_expression -> primary_expression
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 137, spurious reduction of production expression -> assignment_expression
+## In state 155, spurious reduction of production primary_expression -> string_literals_list
+## In state 157, spurious reduction of production postfix_expression -> primary_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 224, spurious reduction of production expression -> assignment_expression
##
Up to this point, an expression has been recognized:
@@ -3996,7 +3999,7 @@ then at this point, a semicolon ';' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 569.
+## Ends in an error in state: 568.
##
## declaration_specifiers(declaration(block_item)) -> typedef_name . list(declaration_specifier_no_type) [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers_typedef -> typedef_name . list(declaration_specifier_no_type) TYPEDEF list(declaration_specifier_no_type) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -4031,7 +4034,7 @@ at this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME RPAREN LBRACE PRE_NAME VAR_NAME COMMA XOR_ASSIGN
##
-## Ends in an error in state: 132.
+## Ends in an error in state: 219.
##
## expression -> expression COMMA . assignment_expression [ SEMICOLON RPAREN RBRACK COMMA COLON ]
##
@@ -4046,7 +4049,7 @@ At this point, an expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME COMMA PRE_NAME VAR_NAME RPAREN
##
-## Ends in an error in state: 546.
+## Ends in an error in state: 545.
##
## init_declarator_list -> init_declarator_list . COMMA init_declarator [ SEMICOLON COMMA ]
## option(init_declarator_list) -> init_declarator_list . [ SEMICOLON ]
@@ -4059,11 +4062,11 @@ translation_unit_file: INT PRE_NAME VAR_NAME COMMA PRE_NAME VAR_NAME RPAREN
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
## In state 255, spurious reduction of production declarator_noattrend -> direct_declarator
-## In state 554, spurious reduction of production declare_varname(declarator_noattrend) -> declarator_noattrend
-## In state 549, spurious reduction of production save_context ->
-## In state 550, spurious reduction of production attribute_specifier_list ->
-## In state 551, spurious reduction of production init_declarator -> declare_varname(declarator_noattrend) save_context attribute_specifier_list
-## In state 548, spurious reduction of production init_declarator_list -> init_declarator_list COMMA init_declarator
+## In state 553, spurious reduction of production declare_varname(declarator_noattrend) -> declarator_noattrend
+## In state 548, spurious reduction of production save_context ->
+## In state 549, spurious reduction of production attribute_specifier_list ->
+## In state 550, spurious reduction of production init_declarator -> declare_varname(declarator_noattrend) save_context attribute_specifier_list
+## In state 547, spurious reduction of production init_declarator_list -> init_declarator_list COMMA init_declarator
##
Up to this point, a list of declarators has been recognized:
@@ -4075,7 +4078,7 @@ then at this point, a semicolon ';' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME COMMA XOR_ASSIGN
##
-## Ends in an error in state: 547.
+## Ends in an error in state: 546.
##
## init_declarator_list -> init_declarator_list COMMA . init_declarator [ SEMICOLON COMMA ]
##
@@ -4090,7 +4093,7 @@ At this point, an init declarator is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE DOT PRE_NAME VAR_NAME EQ ALIGNAS
##
-## Ends in an error in state: 314.
+## Ends in an error in state: 366.
##
## initializer_list -> option(designation) . c_initializer [ RBRACE COMMA ]
##
@@ -4099,7 +4102,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE DOT PRE_NAME VAR_NAME EQ
##
translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE PRE_NAME VAR_NAME COMMA DOT PRE_NAME VAR_NAME EQ ALIGNAS
##
-## Ends in an error in state: 318.
+## Ends in an error in state: 370.
##
## initializer_list -> initializer_list COMMA option(designation) . c_initializer [ RBRACE COMMA ]
##
@@ -4114,7 +4117,7 @@ At this point, an initializer is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE DOT PRE_NAME VAR_NAME XOR_ASSIGN
##
-## Ends in an error in state: 321.
+## Ends in an error in state: 373.
##
## designation -> designator_list . EQ [ TILDE STRING_LITERAL STAR SIZEOF PRE_NAME PLUS MINUS LPAREN LBRACE INC DEC CONSTANT BUILTIN_VA_ARG BUILTIN_OFFSETOF BANG AND ALIGNOF ]
## option(designator_list) -> designator_list . [ LBRACK DOT ]
@@ -4136,7 +4139,7 @@ then at this point, an equals sign '=' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE DOT XOR_ASSIGN
##
-## Ends in an error in state: 311.
+## Ends in an error in state: 326.
##
## designator -> DOT . general_identifier [ RPAREN LBRACK EQ DOT ]
##
@@ -4153,7 +4156,7 @@ At this point, the name of a struct or union member is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE LBRACK PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 309.
+## Ends in an error in state: 324.
##
## designator -> LBRACK conditional_expression . RBRACK [ RPAREN LBRACK EQ DOT ]
##
@@ -4164,19 +4167,19 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE LBRACK PRE_NAME VAR_NAME
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 67, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 154, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
##
Ill-formed designator.
@@ -4189,7 +4192,7 @@ then at this point, a closing bracket ']' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE LBRACK XOR_ASSIGN
##
-## Ends in an error in state: 308.
+## Ends in an error in state: 323.
##
## designator -> LBRACK . conditional_expression RBRACK [ RPAREN LBRACK EQ DOT ]
##
@@ -4204,7 +4207,7 @@ At this point, a constant expression is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE PRE_NAME VAR_NAME COMMA XOR_ASSIGN
##
-## Ends in an error in state: 317.
+## Ends in an error in state: 369.
##
## initializer_list -> initializer_list COMMA . option(designation) c_initializer [ RBRACE COMMA ]
## option(COMMA) -> COMMA . [ RBRACE ]
@@ -4225,7 +4228,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE CONSTANT SEMICOLON
##
-## Ends in an error in state: 316.
+## Ends in an error in state: 368.
##
## c_initializer -> LBRACE initializer_list . option(COMMA) RBRACE [ SEMICOLON RBRACE COMMA ]
## initializer_list -> initializer_list . COMMA option(designation) c_initializer [ RBRACE COMMA ]
@@ -4237,22 +4240,22 @@ translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE CONSTANT SEMICOLON
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
-## In state 320, spurious reduction of production c_initializer -> assignment_expression
-## In state 326, spurious reduction of production initializer_list -> option(designation) c_initializer
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
+## In state 372, spurious reduction of production c_initializer -> assignment_expression
+## In state 378, spurious reduction of production initializer_list -> option(designation) c_initializer
##
# Omitting the fact that the closing brace can be preceded with a comma.
@@ -4267,7 +4270,7 @@ then at this point, a closing brace '}' is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ LBRACE XOR_ASSIGN
##
-## Ends in an error in state: 315.
+## Ends in an error in state: 367.
##
## c_initializer -> LBRACE . initializer_list option(COMMA) RBRACE [ SEMICOLON RBRACE COMMA ]
##
@@ -4288,7 +4291,7 @@ followed with an initializer, is expected.
translation_unit_file: INT PRE_NAME VAR_NAME EQ XOR_ASSIGN
##
-## Ends in an error in state: 552.
+## Ends in an error in state: 551.
##
## init_declarator -> declare_varname(declarator_noattrend) save_context attribute_specifier_list EQ . c_initializer [ SEMICOLON COMMA ]
##
@@ -4316,20 +4319,20 @@ translation_unit_file: INT PRE_NAME VAR_NAME LBRACK CONSTANT SEMICOLON
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 71, spurious reduction of production unary_expression -> postfix_expression
-## In state 75, spurious reduction of production cast_expression -> unary_expression
-## In state 98, spurious reduction of production multiplicative_expression -> cast_expression
-## In state 92, spurious reduction of production additive_expression -> multiplicative_expression
-## In state 111, spurious reduction of production shift_expression -> additive_expression
-## In state 88, spurious reduction of production relational_expression -> shift_expression
-## In state 104, spurious reduction of production equality_expression -> relational_expression
-## In state 120, spurious reduction of production and_expression -> equality_expression
-## In state 128, spurious reduction of production exclusive_or_expression -> and_expression
-## In state 129, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
-## In state 130, spurious reduction of production logical_and_expression -> inclusive_or_expression
-## In state 114, spurious reduction of production logical_or_expression -> logical_and_expression
-## In state 112, spurious reduction of production conditional_expression -> logical_or_expression
-## In state 133, spurious reduction of production assignment_expression -> conditional_expression
+## In state 158, spurious reduction of production unary_expression -> postfix_expression
+## In state 162, spurious reduction of production cast_expression -> unary_expression
+## In state 185, spurious reduction of production multiplicative_expression -> cast_expression
+## In state 179, spurious reduction of production additive_expression -> multiplicative_expression
+## In state 198, spurious reduction of production shift_expression -> additive_expression
+## In state 175, spurious reduction of production relational_expression -> shift_expression
+## In state 191, spurious reduction of production equality_expression -> relational_expression
+## In state 207, spurious reduction of production and_expression -> equality_expression
+## In state 215, spurious reduction of production exclusive_or_expression -> and_expression
+## In state 216, spurious reduction of production inclusive_or_expression -> exclusive_or_expression
+## In state 217, spurious reduction of production logical_and_expression -> inclusive_or_expression
+## In state 201, spurious reduction of production logical_or_expression -> logical_and_expression
+## In state 199, spurious reduction of production conditional_expression -> logical_or_expression
+## In state 220, spurious reduction of production assignment_expression -> conditional_expression
##
# At the time of writing, optional(expression,RBRACK) is used only in direct
@@ -4380,7 +4383,7 @@ The following type name is used as a K&R parameter name:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME RPAREN INT XOR_ASSIGN
##
-## Ends in an error in state: 587.
+## Ends in an error in state: 586.
##
## declaration_specifiers(declaration(block_item)) -> type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_typedef_name) -> list(declaration_specifier_no_typedef_name) . declaration_specifier_no_typedef_name [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC STAR SIGNED SHORT SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG INT INLINE FLOAT EXTERN ENUM DOUBLE CONST CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -4390,7 +4393,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME RPAREN INT
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME RPAREN VOLATILE INT XOR_ASSIGN
##
-## Ends in an error in state: 592.
+## Ends in an error in state: 591.
##
## declaration_specifiers(declaration(block_item)) -> rlist(declaration_specifier_no_type) type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_typedef_name) -> list(declaration_specifier_no_typedef_name) . declaration_specifier_no_typedef_name [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC STAR SIGNED SHORT SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG INT INLINE FLOAT EXTERN ENUM DOUBLE CONST CHAR AUTO ATTRIBUTE ALIGNAS ]
@@ -4400,7 +4403,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME RPAREN VOL
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME RPAREN PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 585.
+## Ends in an error in state: 584.
##
## declaration_specifiers(declaration(block_item)) -> typedef_name list(declaration_specifier_no_type) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_type) -> list(declaration_specifier_no_type) . storage_class_specifier_no_typedef [ VOLATILE STATIC STAR SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN INLINE EXTERN CONST AUTO ATTRIBUTE ALIGNAS ]
@@ -4413,7 +4416,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME RPAREN PRE
##
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME RPAREN VOLATILE PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 590.
+## Ends in an error in state: 589.
##
## declaration_specifiers(declaration(block_item)) -> rlist(declaration_specifier_no_type) typedef_name list(declaration_specifier_no_type) . [ STAR SEMICOLON PRE_NAME LPAREN ]
## list(declaration_specifier_no_type) -> list(declaration_specifier_no_type) . storage_class_specifier_no_typedef [ VOLATILE STATIC STAR SEMICOLON RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN INLINE EXTERN CONST AUTO ATTRIBUTE ALIGNAS ]
@@ -4438,7 +4441,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME RPAREN VOLATILE XOR_ASSIGN
##
-## Ends in an error in state: 588.
+## Ends in an error in state: 587.
##
## declaration_specifiers(declaration(block_item)) -> rlist(declaration_specifier_no_type) . typedef_name list(declaration_specifier_no_type) [ STAR SEMICOLON PRE_NAME LPAREN ]
## declaration_specifiers(declaration(block_item)) -> rlist(declaration_specifier_no_type) . type_specifier_no_typedef_name list(declaration_specifier_no_typedef_name) [ STAR SEMICOLON PRE_NAME LPAREN ]
@@ -4450,7 +4453,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME RPAREN VOL
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 214, spurious reduction of production rlist(declaration_specifier_no_type) -> type_qualifier_noattr
+## In state 125, spurious reduction of production rlist(declaration_specifier_no_type) -> type_qualifier_noattr
##
Ill-formed K&R parameter declaration.
@@ -4463,7 +4466,7 @@ At this point, one of the following is expected:
translation_unit_file: VOID PRE_NAME TYPEDEF_NAME PACKED LPAREN CONSTANT RPAREN XOR_ASSIGN
##
-## Ends in an error in state: 601.
+## Ends in an error in state: 600.
##
## attribute_specifier_list -> attribute_specifier . attribute_specifier_list [ SEMICOLON LBRACE EQ COMMA ]
## rlist(declaration_specifier_no_type) -> attribute_specifier . [ VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT SIGNED SHORT PRE_NAME LONG INT FLOAT ENUM DOUBLE CHAR ]
@@ -4496,7 +4499,7 @@ If this is the parameter declaration of a K&R function definition,
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT COMMA XOR_ASSIGN
##
-## Ends in an error in state: 230.
+## Ends in an error in state: 141.
##
## parameter_list -> parameter_list COMMA . parameter_declaration [ RPAREN COMMA ]
## parameter_type_list -> parameter_list COMMA . ELLIPSIS [ RPAREN ]
@@ -4513,7 +4516,7 @@ At this point, one of the following is expected:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME SEMICOLON
##
-## Ends in an error in state: 229.
+## Ends in an error in state: 140.
##
## parameter_list -> parameter_list . COMMA parameter_declaration [ RPAREN COMMA ]
## parameter_type_list -> parameter_list . [ RPAREN ]
@@ -4531,7 +4534,7 @@ translation_unit_file: INT PRE_NAME VAR_NAME LPAREN INT PRE_NAME VAR_NAME SEMICO
## In state 261, spurious reduction of production declarator -> declarator_noattrend attribute_specifier_list
## In state 277, spurious reduction of production declare_varname(declarator) -> declarator
## In state 276, spurious reduction of production parameter_declaration -> declaration_specifiers(parameter_declaration) declare_varname(declarator)
-## In state 237, spurious reduction of production parameter_list -> parameter_declaration
+## In state 148, spurious reduction of production parameter_list -> parameter_declaration
##
# We omit the possibility of an ellipsis.
@@ -4567,7 +4570,7 @@ The following identifier is used as a type, but has not been defined as such:
translation_unit_file: INT PRE_NAME VAR_NAME LPAREN PRE_NAME VAR_NAME RPAREN INT SEMICOLON XOR_ASSIGN
##
-## Ends in an error in state: 597.
+## Ends in an error in state: 596.
##
## declaration_list -> declaration_list . kr_param_declaration [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC SIGNED SHORT RESTRICT REGISTER PRE_NAME PACKED NORETURN LONG LBRACE INT INLINE FLOAT EXTERN ENUM DOUBLE CONST CHAR AUTO ATTRIBUTE ALIGNAS ]
## function_definition1 -> declaration_specifiers(declaration(external_declaration)) declare_varname(declarator_noattrend) save_context declaration_list . [ LBRACE ]
@@ -4618,7 +4621,7 @@ At this point, a struct or union name is expected.
translation_unit_file: PACKED LPAREN BUILTIN_OFFSETOF LPAREN VOID XOR_ASSIGN
##
-## Ends in an error in state: 345.
+## Ends in an error in state: 318.
##
## postfix_expression -> BUILTIN_OFFSETOF LPAREN type_name . COMMA general_identifier RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
## postfix_expression -> BUILTIN_OFFSETOF LPAREN type_name . COMMA general_identifier designator_list RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -4630,9 +4633,9 @@ translation_unit_file: PACKED LPAREN BUILTIN_OFFSETOF LPAREN VOID XOR_ASSIGN
## This implies that, although the LR(1) items shown above provide an
## accurate view of the past (what has been recognized so far), they
## may provide an INCOMPLETE view of the future (what was expected next).
-## In state 156, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
-## In state 330, spurious reduction of production option(abstract_declarator(type_name)) ->
-## In state 336, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
+## In state 67, spurious reduction of production specifier_qualifier_list(type_name) -> type_specifier_no_typedef_name list(specifier_qualifier_no_typedef_name)
+## In state 306, spurious reduction of production option(abstract_declarator(type_name)) ->
+## In state 312, spurious reduction of production type_name -> specifier_qualifier_list(type_name) option(abstract_declarator(type_name))
##
Ill-formed __builtin_offsetof.
@@ -4642,7 +4645,7 @@ At this point, a colon ',' is expected
translation_unit_file: PACKED LPAREN BUILTIN_OFFSETOF LPAREN VOID COMMA XOR_ASSIGN
##
-## Ends in an error in state: 346.
+## Ends in an error in state: 319.
##
## postfix_expression -> BUILTIN_OFFSETOF LPAREN type_name COMMA . general_identifier RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
## postfix_expression -> BUILTIN_OFFSETOF LPAREN type_name COMMA . general_identifier designator_list RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -4658,7 +4661,7 @@ At this point, a member-designator is expected.
translation_unit_file: PACKED LPAREN BUILTIN_OFFSETOF LPAREN VOID COMMA PRE_NAME TYPEDEF_NAME XOR_ASSIGN
##
-## Ends in an error in state: 347.
+## Ends in an error in state: 320.
##
## postfix_expression -> BUILTIN_OFFSETOF LPAREN type_name COMMA general_identifier . RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
## postfix_expression -> BUILTIN_OFFSETOF LPAREN type_name COMMA general_identifier . designator_list RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -4674,7 +4677,7 @@ At this point, a member-designator is expected.
translation_unit_file: PACKED LPAREN BUILTIN_OFFSETOF LPAREN VOID COMMA PRE_NAME TYPEDEF_NAME LBRACK STRING_LITERAL RBRACK XOR_ASSIGN
##
-## Ends in an error in state: 349.
+## Ends in an error in state: 329.
##
## option(designator_list) -> designator_list . [ LBRACK DOT ]
## postfix_expression -> BUILTIN_OFFSETOF LPAREN type_name COMMA general_identifier designator_list . RPAREN [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RPAREN RIGHT_ASSIGN RIGHT RBRACK RBRACE QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA COLON BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -4701,7 +4704,7 @@ translation_unit_file: ALIGNAS LPAREN PRE_NAME XOR_ASSIGN
##
translation_unit_file: ALIGNAS LPAREN VOID LPAREN VOID LPAREN PRE_NAME XOR_ASSIGN
##
-## Ends in an error in state: 236.
+## Ends in an error in state: 147.
##
## declarator_identifier -> PRE_NAME . low_prec TYPEDEF_NAME [ RPAREN PACKED LPAREN LBRACK ATTRIBUTE ALIGNAS ]
## declarator_identifier -> PRE_NAME . VAR_NAME [ RPAREN PACKED LPAREN LBRACK ATTRIBUTE ALIGNAS ]
@@ -4722,7 +4725,7 @@ translation_unit_file: UNION PRE_NAME XOR_ASSIGN
##
translation_unit_file: VOID PRE_NAME TYPEDEF_NAME LBRACE PRE_NAME XOR_ASSIGN
##
-## Ends in an error in state: 434.
+## Ends in an error in state: 433.
##
## general_identifier -> PRE_NAME . VAR_NAME [ COLON ]
## primary_expression -> PRE_NAME . VAR_NAME [ XOR_ASSIGN SUB_ASSIGN STAR SLASH SEMICOLON RIGHT_ASSIGN RIGHT QUESTION PTR PLUS PERCENT OR_ASSIGN NEQ MUL_ASSIGN MOD_ASSIGN MINUS LT LPAREN LEQ LEFT_ASSIGN LEFT LBRACK INC HAT GT GEQ EQEQ EQ DOT DIV_ASSIGN DEC COMMA BARBAR BAR AND_ASSIGN ANDAND AND ADD_ASSIGN ]
@@ -4733,7 +4736,7 @@ translation_unit_file: VOID PRE_NAME TYPEDEF_NAME LBRACE PRE_NAME XOR_ASSIGN
##
translation_unit_file: VOID PRE_NAME TYPEDEF_NAME LPAREN PRE_NAME XOR_ASSIGN
##
-## Ends in an error in state: 194.
+## Ends in an error in state: 105.
##
## identifier_list -> PRE_NAME . VAR_NAME [ RPAREN COMMA ]
## typedef_name -> PRE_NAME . TYPEDEF_NAME [ VOLATILE STATIC STAR RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LBRACK INLINE EXTERN CONST COMMA AUTO ATTRIBUTE ALIGNAS ]
@@ -4743,7 +4746,7 @@ translation_unit_file: VOID PRE_NAME TYPEDEF_NAME LPAREN PRE_NAME XOR_ASSIGN
##
translation_unit_file: VOID PRE_NAME XOR_ASSIGN
##
-## Ends in an error in state: 182.
+## Ends in an error in state: 93.
##
## declarator_identifier -> PRE_NAME . low_prec TYPEDEF_NAME [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK LBRACE INT INLINE FLOAT EXTERN EQ ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
## declarator_identifier -> PRE_NAME . VAR_NAME [ VOLATILE VOID UNSIGNED UNION UNDERSCORE_BOOL STRUCT STATIC SIGNED SHORT SEMICOLON RPAREN RESTRICT REGISTER PRE_NAME PACKED NORETURN LPAREN LONG LBRACK LBRACE INT INLINE FLOAT EXTERN EQ ENUM DOUBLE CONST COMMA COLON CHAR AUTO ATTRIBUTE ALIGNAS ]
diff --git a/cparser/pre_parser.mly b/cparser/pre_parser.mly
index 04fbcb94..71eaf419 100644
--- a/cparser/pre_parser.mly
+++ b/cparser/pre_parser.mly
@@ -275,7 +275,6 @@ unary_expression:
| unary_operator cast_expression
| SIZEOF unary_expression
| SIZEOF LPAREN type_name RPAREN
-| ALIGNOF unary_expression
| ALIGNOF LPAREN type_name RPAREN
{}
diff --git a/debug/DwarfPrinter.ml b/debug/DwarfPrinter.ml
index 09694d0b..a45fff0c 100644
--- a/debug/DwarfPrinter.ml
+++ b/debug/DwarfPrinter.ml
@@ -241,7 +241,7 @@ module DwarfPrinter(Target: DWARF_TARGET):
let abbrev = !curr_abbrev in
incr curr_abbrev;abbrev
- (* Mapping from abbreviation string to abbrevaiton id *)
+ (* Mapping from abbreviation string to abbreviaton id *)
let abbrev_mapping: (string,int) Hashtbl.t = Hashtbl.create 7
(* Look up the id of the abbreviation and add it if it is missing *)
diff --git a/doc/ccomp.1 b/doc/ccomp.1
index 301b0b5f..374bd2e7 100644
--- a/doc/ccomp.1
+++ b/doc/ccomp.1
@@ -365,7 +365,7 @@ CompCert supports the following warning classes:
.sp
\fIc11\-extensions\fP:
Feature specific to C11.
-Enabled by default.
+Disabled by default.
.sp
\fIcompare\-distinct\-pointer\-types\fP:
Comparison of different pointer types.
@@ -379,10 +379,22 @@ Disabled by default.
Dangerous conversion of constants, e.g. literals that are too large for the given type.
Enabled by default.
.sp
+\fIextern\-after\-definition\fP:
+Extern declarations after non-extern definitions.
+Enabled by default.
+.sp
+\fIflexible\-array\-extensions\fP:
+Use of structs with flexible arrays nexted within structs or arrays.
+Disabled by default.
+.sp
\fIgnu\-empty\-struct\fP:
GNU extension for empty structs.
Enabled by default.
.sp
+\fIignored\-attributes\fP:
+Attribute declarations after definitions.
+Enabled by default.
+.sp
\fIimplicit\-function\-declaration\fP:
Deprecated implicit function declarations.
Enabled by default.
@@ -391,6 +403,10 @@ Enabled by default.
Type of parameter or return type is implicitly assumed to be int.
Enabled by default.
.sp
+\fIinline\-asm\-sdump\fP:
+Use of unsupported features in combination with dump of abstract syntax tree.
+Enabled by default.
+.sp
\fIint\-conversion\fP:
Conversion between pointer and integer.
Enabled by default.
@@ -407,14 +423,30 @@ Enabled by default.
Wrong return type for main.
Enabled by default.
.sp
+\fImissing\-declarations\fP:
+Declations which do not declare anything.
+Enabled by default.
+.sp
\fIpointer\-type\-mismatch\fP:
Use of incompatible pointer types in conditional expressions.
Enabled by default.
.sp
+\fIreduced\-alignment\fP:
+Alignment specifications lower than natural alignment.
+Disabled by default.
+.sp
\fIreturn\-type\fP:
Void-return statement in non-void function.
Enabled by default.
.sp
+\fIstatic\-in\-inline\fP:
+Use of static variables in non-static inline functions.
+Enabled by default.
+.sp
+\fItentative\-incomplete\-static\fP:
+Use of tentative static definitions with incomplete type.
+Disabled by default.
+.sp
\fIunknown\-attributes\fP:
Use of unsupported or unknown attributes.
Enabled by default.
@@ -423,6 +455,14 @@ Enabled by default.
Use of unsupported or unknown pragmas.
Disabled by default.
.sp
+\fIunused\-ais\-parameter\fP:
+Unused parameter for embedded program annotations.
+Disabled by default.
+.sp
+\fIunused\-variable\fP:
+Unused local variables.
+Enabled by default.
+.sp
\fIvarargs\fP:
Promotable vararg arguments.
Enabled by default.
@@ -434,10 +474,6 @@ Enabled by default.
\fIzero\-length\-array\fP:
GNU extension for zero length arrays.
Disabled by default.
-.sp
-\fIinline\-asm\-sdump\fP:
-Use of unsupported features in combination with dump of abstract syntax tree.
-Enabled by default.
.
.TP
.B \-Wno-<warning>
@@ -524,10 +560,6 @@ Save generated assembly in <file>.s.
Save all generated intermediate files in <file>.<ext>.
.
.TP
-.B \-doptions
-Save the compiler configuration in <file>.opt.json.
-.
-.TP
.B \-sdump
Save abstract syntax tree of generated assembly for post-linking validation tool in <file>.json.
.
diff --git a/doc/coq2html.css b/doc/coq2html.css
deleted file mode 100644
index c5627bfb..00000000
--- a/doc/coq2html.css
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Classes:
- h1.title the title of the page
- div.coq encloses all generated body
- div.doc contents of (** *) comments
- div.footer footer
- div.togglescript "Proof." line
- div.proofscript contents of proof script
- span.docright contents of (**r *) comments
- span.bracket contents of [ ] within comments
- span.comment contents of (* *) comments
- span.kwd Coq keyword
- span.tactic Coq tactic
- span.id any other identifier
-*/
-
-body {
- color: black;
- background: white;
-}
-
-h1.title {
- font-size: 2em;
- text-align: center
-}
-
-h1 {
- font-size: 1.5em;
-}
-h2 {
- font-size: 1.17em;
-}
-h3 {
- font-size: 1em;
-}
-
-h1, h2, h3 {
- font-family: sans-serif;
- margin-left: -5%;
-}
-
-div.coq {
- margin-left: 15%;
- margin-right: 5%;
- font-family: monospace;
-}
-
-div.doc {
- margin-left: -5%;
- margin-top: 0.2em;
- margin-bottom: 0.5em;
- font-family: serif;
-}
-
-div.toggleproof {
- font-size: 0.8em;
- text-decoration: underline;
-}
-
-div.toggleproof:hover {
- cursor: pointer;
-}
-
-div.proofscript {
- font-size: 0.8em;
-}
-
-div.footer {
- margin-top: 1em;
- margin-bottom: 1em;
- font-size: 0.8em;
- font-style: italic;
-}
-
-span.docright {
- position: absolute;
- left: 60%;
- width: 40%;
- font-family: serif;
-}
-
-span.bracket {
- font-family: monospace;
- color: #008000;
-}
-
-span.kwd {
- color: #cf1d1d;
-}
-
-span.comment {
- color: #008000;
-}
-
-a:visited {color : #416DFF; text-decoration : none; }
-a:link {color : #416DFF; text-decoration : none; }
-a:hover {text-decoration : none; }
-a:active {text-decoration : none; }
diff --git a/doc/coq2html.js b/doc/coq2html.js
deleted file mode 100644
index a840b004..00000000
--- a/doc/coq2html.js
+++ /dev/null
@@ -1,24 +0,0 @@
-function toggleDisplay(id)
-{
- var elt = document.getElementById(id);
- if (elt.style.display == 'none') {
- elt.style.display = 'block';
- } else {
- elt.style.display = 'none';
- }
-}
-
-function hideAll(cls)
-{
- var testClass = new RegExp("(^|s)" + cls + "(s|$)");
- var tag = tag || "*";
- var elements = document.getElementsByTagName("div");
- var current;
- var length = elements.length;
- for(var i=0; i<length; i++){
- current = elements[i];
- if(testClass.test(current.className)) {
- current.style.display = 'none';
- }
- }
-}
diff --git a/doc/coq2html.mll b/doc/coq2html.mll
deleted file mode 100644
index a5b284e2..00000000
--- a/doc/coq2html.mll
+++ /dev/null
@@ -1,454 +0,0 @@
-(* *********************************************************************)
-(* *)
-(* The Compcert verified compiler *)
-(* *)
-(* Xavier Leroy, INRIA Paris-Rocquencourt *)
-(* *)
-(* Copyright Institut National de Recherche en Informatique et en *)
-(* Automatique. All rights reserved. This file is distributed *)
-(* under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation, either version 2 of the License, or *)
-(* (at your option) any later version. This file is also distributed *)
-(* under the terms of the INRIA Non-Commercial License Agreement. *)
-(* *)
-(* *********************************************************************)
-
-{
-open Printf
-
-(** Cross-referencing *)
-
-let current_module = ref ""
-
-type xref =
- | Def of string * string (* path, type *)
- | Ref of string * string * string (* unit, path, type *)
-
-let xref_table : (string * int, xref) Hashtbl.t = Hashtbl.create 273
-let xref_modules : (string, unit) Hashtbl.t = Hashtbl.create 29
-
-let path sp id =
- match sp, id with
- | "<>", "<>" -> ""
- | "<>", _ -> id
- | _ , "<>" -> sp
- | _ , _ -> sp ^ "." ^ id
-
-let add_module m =
- (*eprintf "add_module %s\n" m;*)
- Hashtbl.add xref_modules m ()
-
-let add_reference curmod pos dp sp id ty =
- (*eprintf "add_reference %s %d %s %s %s %s\n" curmod pos dp sp id ty;*)
- if not (Hashtbl.mem xref_table (curmod, pos))
- then Hashtbl.add xref_table (curmod, pos) (Ref(dp, path sp id, ty))
-
-let add_definition curmod pos sp id ty =
- if not (Hashtbl.mem xref_table (curmod, pos))
- then Hashtbl.add xref_table (curmod, pos) (Def(path sp id, ty))
-
-type link = Link of string | Anchor of string | Nolink
-
-let coqlib_url = "http://coq.inria.fr/library/"
-
-let re_coqlib = Str.regexp "Coq\\."
-let re_sane_path = Str.regexp "[A-Za-z0-9_.]+$"
-let re_shortname = Str.regexp "^.*\\."
-
-let shortname m = Str.replace_first re_shortname "" m
-
-let crossref m pos =
- (*eprintf "crossref %s %d\n" m pos;*)
- try match Hashtbl.find xref_table (m, pos) with
- | Def(p, _) ->
- Anchor p
- | Ref(m', p, _) ->
- let url =
- if Hashtbl.mem xref_modules m' then
- shortname m' ^ ".html"
- else if Str.string_match re_coqlib m' 0 then
- coqlib_url ^ m' ^ ".html"
- else
- raise Not_found in
- if p = "" then
- Link url
- else if Str.string_match re_sane_path p 0 then
- Link(url ^ "#" ^ p)
- else
- Nolink
- with Not_found ->
- Nolink
-
-(** Keywords, etc *)
-
-module StringSet = Set.Make(String)
-
-let mkset l = List.fold_right StringSet.add l StringSet.empty
-
-let coq_keywords = mkset [
- "forall"; "match"; "as"; "in"; "return"; "with"; "end"; "let";
- "dest"; "fun"; "if"; "then"; "else"; "Prop"; "Set"; "Type"; ":=";
- "where"; "struct"; "wf"; "measure";
- "AddPath"; "Axiom"; "Abort"; "Boxed"; "Chapter"; "Check";
- "Coercion"; "CoFixpoint"; "CoInductive"; "Corollary"; "Defined";
- "Definition"; "End"; "Eval"; "Example"; "Export"; "Fact"; "Fix";
- "Fixpoint"; "Global"; "Grammar"; "Goal"; "Hint"; "Hypothesis";
- "Hypotheses"; "Resolve"; "Unfold"; "Immediate"; "Extern";
- "Implicit"; "Import"; "Inductive"; "Infix"; "Lemma"; "Let"; "Load";
- "Local"; "Ltac"; "Module"; "Module Type"; "Declare Module";
- "Include"; "Mutual"; "Parameter"; "Parameters"; "Print"; "Proof";
- "Qed"; "Record"; "Recursive"; "Remark"; "Require";
- "Save"; "Scheme"; "Induction"; "for"; "Sort"; "Section"; "Show";
- "Structure"; "Syntactic"; "Syntax"; "Tactic"; "Theorem"; "Set";
- "Types"; "Undo"; "Unset"; "Variable"; "Variables"; "Context";
- "Notation"; "Reserved"; "Tactic"; "Delimit"; "Bind"; "Open";
- "Scope"; "Boxed"; "Unboxed"; "Inline"; "Implicit Arguments"; "Add";
- "Strict"; "Typeclasses"; "Instance"; "Global Instance"; "Class";
- "Instantiation"; "subgoal"; "Program"; "Example"; "Obligation";
- "Obligations"; "Solve"; "using"; "Next"; "Instance"; "Equations";
- "Equations_nocomp"
-]
-
-let coq_tactics = mkset [
- "intro"; "intros"; "apply"; "rewrite"; "refine"; "case"; "clear";
- "injection"; "elimtype"; "progress"; "setoid_rewrite"; "destruct";
- "destruction"; "destruct_call"; "dependent"; "elim";
- "extensionality"; "f_equal"; "generalize"; "generalize_eqs";
- "generalize_eqs_vars"; "induction"; "rename"; "move"; "omega";
- "set"; "assert"; "do"; "repeat"; "cut"; "assumption"; "exact";
- "split"; "subst"; "try"; "discriminate"; "simpl"; "unfold"; "red";
- "compute"; "at"; "in"; "by"; "reflexivity"; "symmetry";
- "transitivity"; "replace"; "setoid_replace"; "inversion";
- "inversion_clear"; "pattern"; "intuition"; "congruence"; "fail";
- "fresh"; "trivial"; "exact"; "tauto"; "firstorder"; "ring";
- "clapply"; "program_simpl"; "program_simplify"; "eapply"; "auto";
- "eauto"
-]
-
-(** HTML generation *)
-
-let oc = ref stdout
-
-let character = function
- | '<' -> output_string !oc "&lt;"
- | '>' -> output_string !oc "&gt;"
- | '&' -> output_string !oc "&amp;"
- | c -> output_char !oc c
-
-let section_level = function
- | "*" -> 1
- | "**" -> 2
- | _ -> 3
-
-let start_section sect =
- fprintf !oc "<h%d>" (section_level sect)
-let end_section sect =
- fprintf !oc "</h%d>\n" (section_level sect)
-
-let start_doc_right () =
- fprintf !oc "<span class=\"docright\">(* "
-let end_doc_right () =
- fprintf !oc " *)</span>"
-
-let enum_depth = ref 0
-
-let set_enum_depth d =
- if !enum_depth < d then begin
- fprintf !oc "<ul>\n";
- fprintf !oc "<li>\n";
- incr enum_depth;
- end
- else if !enum_depth > d then begin
- fprintf !oc "</li>\n";
- fprintf !oc "</ul>\n";
- decr enum_depth;
- end
- else if !enum_depth > 0 then begin
- fprintf !oc "</li>\n";
- fprintf !oc "<li>\n"
- end
-
-let start_doc () =
- fprintf !oc "<div class=\"doc\">"
-let end_doc () =
- set_enum_depth 0;
- fprintf !oc "</div>\n"
-
-let ident pos id =
- if StringSet.mem id coq_keywords then
- fprintf !oc "<span class=\"kwd\">%s</span>" id
- else if StringSet.mem id coq_tactics then
- fprintf !oc "<span class=\"tactic\">%s</span>" id
- else match crossref !current_module pos with
- | Nolink ->
- fprintf !oc "<span class=\"id\">%s</span>" id
- | Link p ->
- fprintf !oc "<span class=\"id\"><a href=\"%s\">%s</a></span>" p id
- | Anchor p ->
- fprintf !oc "<span class=\"id\"><a name=\"%s\">%s</a></span>" p id
-
-let space s =
- for _ = 1 to String.length s do fprintf !oc "&nbsp;" done
-
-let newline () =
- fprintf !oc "<br/>\n"
-
-let dashes = function
- | "-" -> set_enum_depth 1
- | "--" -> set_enum_depth 2
- | "---" -> set_enum_depth 3
- | "----" -> set_enum_depth 4
- | _ -> fprintf !oc "<hr/>\n"
-
-let start_verbatim () =
- fprintf !oc "<pre>\n"
-
-let end_verbatim () =
- fprintf !oc "</pre>\n"
-
-let start_comment () =
- fprintf !oc "<span class=\"comment\">(*"
-
-let end_comment () =
- fprintf !oc "*)</span>"
-
-let start_bracket () =
- fprintf !oc "<span class=\"bracket\">"
-
-let end_bracket () =
- fprintf !oc "</span>"
-
-let in_proof = ref false
-let proof_counter = ref 0
-
-let start_proof kwd =
- in_proof := true;
- incr proof_counter;
- fprintf !oc
- "<div class=\"toggleproof\" onclick=\"toggleDisplay('proof%d')\">%s</div>\n"
- !proof_counter kwd;
- fprintf !oc "<div class=\"proofscript\" id=\"proof%d\">\n" !proof_counter
-
-let end_proof kwd =
- fprintf !oc "%s</div>\n" kwd;
- in_proof := false
-
-let start_html_page modname =
- fprintf !oc "\
-<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
-<html xmlns=\"http://www.w3.org/1999/xhtml\">
-
-<head>
-<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
-<title>Module %s</title>
-<meta name=\"description\" content=\"Documentation of Coq module %s\" />
-<link href=\"coq2html.css\" rel=\"stylesheet\" type=\"text/css\" />
-<script type=\"text/javascript\" src=\"coq2html.js\"> </script>
-</head>
-
-<body onload=\"hideAll('proofscript')\">
-<h1 class=\"title\">Module %s</h1>
-<div class=\"coq\">
-" modname modname modname
-
-let end_html_page () =
- fprintf !oc "\
-</div>
-<div class=\"footer\"><hr/>Generated by coq2html</div>
-</body>
-</html>
-"
-
-}
-
-let space = [' ' '\t']
-let ident = ['A'-'Z' 'a'-'z' '_'] ['A'-'Z' 'a'-'z' '0'-'9' '_']*
-let path = ident ("." ident)*
-let start_proof = ("Proof" space* ".") | ("Proof" space+ "with") | ("Next" space+ "Obligation.")
-let end_proof = "Qed." | "Defined." | "Save." | "Admitted." | "Abort."
-
-let xref = ['A'-'Z' 'a'-'z' '0'-'9' '_' '.']+ | "<>"
-let integer = ['0'-'9']+
-
-rule coq_bol = parse
- | space* (start_proof as sp)
- { start_proof sp;
- skip_newline lexbuf }
- | space* "(** " ("*"+ as sect)
- { start_section sect;
- doc lexbuf;
- end_section sect;
- skip_newline lexbuf }
- | space* "(** "
- { start_doc();
- doc lexbuf;
- end_doc();
- skip_newline lexbuf }
- | space* "(*"
- { comment lexbuf;
- skip_newline lexbuf }
- | eof
- { () }
- | space* as s
- { space s;
- coq lexbuf }
-
-and skip_newline = parse
- | space* "\n"
- { coq_bol lexbuf }
- | ""
- { coq lexbuf }
-
-and coq = parse
- | end_proof as ep
- { end_proof ep;
- skip_newline lexbuf }
- | "(**r "
- { start_doc_right();
- doc lexbuf;
- end_doc_right();
- coq lexbuf }
- | "(*"
- { if !in_proof then start_comment();
- comment lexbuf;
- coq lexbuf }
- | path as id
- { ident (Lexing.lexeme_start lexbuf) id; coq lexbuf }
- | "\n"
- { newline(); coq_bol lexbuf }
- | eof
- { () }
- | _ as c
- { character c; coq lexbuf }
-
-and bracket = parse
- | ']'
- { () }
- | '['
- { character '['; bracket lexbuf; character ']'; bracket lexbuf }
- | path as id
- { ident (Lexing.lexeme_start lexbuf) id; bracket lexbuf }
- | eof
- { () }
- | _ as c
- { character c; bracket lexbuf }
-
-and comment = parse
- | "*)"
- { if !in_proof then end_comment() }
- | "(*"
- { if !in_proof then start_comment();
- comment lexbuf; comment lexbuf }
- | eof
- { () }
- | "\n"
- { if !in_proof then newline();
- comment lexbuf }
- | space* as s
- { if !in_proof then space s;
- comment lexbuf }
- | eof
- { () }
- | _ as c
- { if !in_proof then character c;
- comment lexbuf }
-
-and doc_bol = parse
- | "<<" space* "\n"
- { start_verbatim();
- verbatim lexbuf;
- end_verbatim();
- doc_bol lexbuf }
- | "-"+ as d
- { dashes d; doc lexbuf }
- | "\n"
- { set_enum_depth 0; doc_bol lexbuf }
- | ""
- { doc lexbuf }
-
-and doc = parse
- | "*)"
- { () }
- | "\n"
- { character '\n'; doc_bol lexbuf }
- | "["
- { start_bracket(); bracket lexbuf; end_bracket(); doc lexbuf }
- | "$" [^ '\n' '$']* "$"
- { doc lexbuf }
- | "#" ([^ '\n' '#']* as html) "#"
- { output_string !oc html; doc lexbuf }
- | eof
- { () }
- | _ as c
- { character c; doc lexbuf }
-
-and verbatim = parse
- | "\n>>" space* "\n"
- { () }
- | eof
- { () }
- | _ as c
- { character c; verbatim lexbuf }
-
-and globfile = parse
- | eof
- { () }
- | "F" (path as m) space* "\n"
- { current_module := m; add_module m;
- globfile lexbuf }
- | "R" (integer as pos) ":" (integer)
- space+ (xref as dp)
- space+ (xref as sp)
- space+ (xref as id)
- space+ (ident as ty)
- space* "\n"
- { add_reference !current_module (int_of_string pos) dp sp id ty;
- globfile lexbuf }
- | (ident as ty)
- space+ (integer as pos) ":" (integer)
- space+ (xref as sp)
- space+ (xref as id)
- space* "\n"
- { add_definition !current_module (int_of_string pos) sp id ty;
- globfile lexbuf }
- | [^ '\n']* "\n"
- { globfile lexbuf }
-
-{
-
-let output_name = ref "-"
-
-let process_file f =
- if Filename.check_suffix f ".v" then begin
- let pref_f = Filename.chop_suffix f ".v" in
- let base_f = Filename.basename pref_f in
- current_module :=
- "compcert." ^ Str.global_replace (Str.regexp "/") "." pref_f;
- let ic = open_in f in
- if !output_name = "-" then
- oc := stdout
- else
- oc := open_out (Str.global_replace (Str.regexp "%") base_f !output_name);
- start_html_page base_f;
- coq_bol (Lexing.from_channel ic);
- end_html_page();
- if !output_name <> "-" then (close_out !oc; oc := stdout);
- close_in ic
- end else
- if Filename.check_suffix f ".glob" then begin
- current_module := "";
- let ic = open_in f in
- globfile (Lexing.from_channel ic);
- close_in ic
- end else begin
- eprintf "Don't know what to do with file %s\n" f;
- exit 2
- end
-
-let _ =
- Arg.parse [
- "-o", Arg.String (fun s -> output_name := s),
- " <output> Set output file ('%' replaced by module name)"
- ] process_file
- "Usage: coq2html [options] <file.glob> file.v\nOptions are:"
-}
diff --git a/doc/coqdoc.css b/doc/coqdoc.css
deleted file mode 100644
index f2ae96da..00000000
--- a/doc/coqdoc.css
+++ /dev/null
@@ -1,62 +0,0 @@
-body {
- color: black;
- background: white;
- margin-left: 15%;
- margin-right: 5%;
-}
-
-#main a.idref:visited {color : #416DFF; text-decoration : none; }
-#main a.idref:link {color : #416DFF; text-decoration : none; }
-#main a.idref:hover {text-decoration : none; }
-#main a.idref:active {text-decoration : none; }
-
-#main a.modref:visited {color : #416DFF; text-decoration : none; }
-#main a.modref:link {color : #416DFF; text-decoration : none; }
-#main a.modref:hover {text-decoration : none; }
-#main a.modref:active {text-decoration : none; }
-
-#main .keyword { color : #cf1d1d }
-
-#main .doc {
- margin-left: -5%;
-}
-
-#main span.docright {
- position: absolute;
- left: 60%;
- width: 40%
-}
-
-h1.libtitle {
- font-size: 2em;
- margin-left: -15%;
- margin-right: -5%;
- text-align: center
-}
-
-h1 {
- font-size: 1.5em;
-}
-h2 {
- font-size: 1.17em;
-}
-
-h1, h2 {
- font-family: sans-serif;
-}
-
-.doc code {
- color: #008000;
-}
-
-/* Pied de page */
-
-hr { margin-left: -15%; margin-right:-5%; }
-
-#footer { font-size: 0.83em;
- font-family: sans-serif; }
-
-#footer a:visited { color: blue; }
-#footer a:link { text-decoration: none;
- color: #888888; }
-
diff --git a/doc/index.html b/doc/index.html
index 34583bd3..72875e1a 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -24,7 +24,7 @@ a:active {color : Red; text-decoration : underline; }
<H1 align="center">The CompCert verified compiler</H1>
<H2 align="center">Commented Coq development</H2>
-<H3 align="center">Version 3.2, 2018-01-15</H3>
+<H3 align="center">Version 3.4, 2018-09-17</H3>
<H2>Introduction</H2>
@@ -69,73 +69,73 @@ following <A HREF="LICENSE">license</A>.
<H3>General-purpose libraries, data structures and algorithms</H3>
<UL>
-<LI> <A HREF="html/Coqlib.html">Coqlib</A>: addendum to the Coq standard library.
-<LI> <A HREF="html/Maps.html">Maps</A>: finite maps.
-<LI> <A HREF="html/Integers.html">Integers</A>: machine integers.
-<LI> <A HREF="html/Floats.html">Floats</A>: machine floating-point numbers.
-<LI> <A HREF="html/Iteration.html">Iteration</A>: various forms of "while" loops.
-<LI> <A HREF="html/Ordered.html">Ordered</A>: construction of
+<LI> <A HREF="html/compcert.lib.Coqlib.html">Coqlib</A>: addendum to the Coq standard library.
+<LI> <A HREF="html/compcert.lib.Maps.html">Maps</A>: finite maps.
+<LI> <A HREF="html/compcert.lib.Integers.html">Integers</A>: machine integers.
+<LI> <A HREF="html/compcert.lib.Floats.html">Floats</A>: machine floating-point numbers.
+<LI> <A HREF="html/compcert.lib.Iteration.html">Iteration</A>: various forms of "while" loops.
+<LI> <A HREF="html/compcert.lib.Ordered.html">Ordered</A>: construction of
ordered types.
-<LI> <A HREF="html/Lattice.html">Lattice</A>: construction of
+<LI> <A HREF="html/compcert.lib.Lattice.html">Lattice</A>: construction of
semi-lattices.
-<LI> <A HREF="html/Kildall.html">Kildall</A>: resolution of dataflow
+<LI> <A HREF="html/compcert.backend.Kildall.html">Kildall</A>: resolution of dataflow
inequations by fixpoint iteration.
-<LI> <A HREF="html/UnionFind.html">UnionFind</A>: a persistent union-find data structure.
-<LI> <A HREF="html/Postorder.html">Postorder</A>: postorder numbering of a directed graph.
+<LI> <A HREF="html/compcert.lib.UnionFind.html">UnionFind</A>: a persistent union-find data structure.
+<LI> <A HREF="html/compcert.lib.Postorder.html">Postorder</A>: postorder numbering of a directed graph.
</UL>
<H3>Definitions and theorems used in many parts of the development</H3>
<UL>
-<LI> <A HREF="html/Errors.html">Errors</A>: the Error monad.
-<LI> <A HREF="html/AST.html">AST</A>: identifiers, whole programs and other
+<LI> <A HREF="html/compcert.common.Errors.html">Errors</A>: the Error monad.
+<LI> <A HREF="html/compcert.common.AST.html">AST</A>: identifiers, whole programs and other
common elements of abstract syntaxes.
-<LI> <A HREF="html/Linking.html">Linking</A>: generic framework to define syntactic linking over the CompCert languages.
-<LI> <A HREF="html/Values.html">Values</A>: run-time values.
-<LI> <A HREF="html/Events.html">Events</A>: observable events and traces.
-<LI> <A HREF="html/Memory.html">Memory</A>: memory model. <BR>
-See also: <A HREF="html/Memdata.html">Memdata</A> (in-memory representation of data).
-<LI> <A HREF="html/Globalenvs.html">Globalenvs</A>: global execution environments.
-<LI> <A HREF="html/Smallstep.html">Smallstep</A>: tools for small-step semantics.
-<LI> <A HREF="html/Behaviors.html">Behaviors</A>: from small-step semantics to observable behaviors of programs.
-<LI> <A HREF="html/Determinism.html">Determinism</A>: determinism properties of small-step semantics.
-<LI> <A HREF="html/Op.html"><I>Op</I></A>: operators, addressing modes and their
+<LI> <A HREF="html/compcert.common.Linking.html">Linking</A>: generic framework to define syntactic linking over the CompCert languages.
+<LI> <A HREF="html/compcert.common.Values.html">Values</A>: run-time values.
+<LI> <A HREF="html/compcert.common.Events.html">Events</A>: observable events and traces.
+<LI> <A HREF="html/compcert.common.Memory.html">Memory</A>: memory model. <BR>
+See also: <A HREF="html/compcert.common.Memdata.html">Memdata</A> (in-memory representation of data).
+<LI> <A HREF="html/compcert.common.Globalenvs.html">Globalenvs</A>: global execution environments.
+<LI> <A HREF="html/compcert.common.Smallstep.html">Smallstep</A>: tools for small-step semantics.
+<LI> <A HREF="html/compcert.common.Behaviors.html">Behaviors</A>: from small-step semantics to observable behaviors of programs.
+<LI> <A HREF="html/compcert.common.Determinism.html">Determinism</A>: determinism properties of small-step semantics.
+<LI> <A HREF="html/compcert.powerpc.Op.html"><I>Op</I></A>: operators, addressing modes and their
semantics.
-<LI> <A HREF="html/Unityping.html">Unityping</A>: a solver for atomic unification constraints.
+<LI> <A HREF="html/compcert.common.Unityping.html">Unityping</A>: a solver for atomic unification constraints.
</UL>
<H3>Source, intermediate and target languages: syntax and semantics</H3>
<UL>
<LI> The CompCert C source language:
-<A HREF="html/Csyntax.html">syntax</A> and
-<A HREF="html/Csem.html">semantics</A> and
-<A HREF="html/Cstrategy.html">determinized semantics</A> and
-<A HREF="html/Ctyping.html">type system</A>.<BR>
-See also: <A HREF="html/Ctypes.html">type expressions</A> and
-<A HREF="html/Cop.html">operators (syntax and semantics)</A>.<BR>
-See also: <A HREF="html/Cexec.html">reference interpreter</A>.
-<LI> <A HREF="html/Clight.html">Clight</A>: a simpler version of CompCert C where expressions contain no side-effects.
-<LI> <A HREF="html/Csharpminor.html">Csharpminor</A>: low-level
+<A HREF="html/compcert.cfrontend.Csyntax.html">syntax</A> and
+<A HREF="html/compcert.cfrontend.Csem.html">semantics</A> and
+<A HREF="html/compcert.cfrontend.Cstrategy.html">determinized semantics</A> and
+<A HREF="html/compcert.cfrontend.Ctyping.html">type system</A>.<BR>
+See also: <A HREF="html/compcert.cfrontend.Ctypes.html">type expressions</A> and
+<A HREF="html/compcert.cfrontend.Cop.html">operators (syntax and semantics)</A>.<BR>
+See also: <A HREF="html/compcert.cfrontend.Cexec.html">reference interpreter</A>.
+<LI> <A HREF="html/compcert.cfrontend.Clight.html">Clight</A>: a simpler version of CompCert C where expressions contain no side-effects.
+<LI> <A HREF="html/compcert.cfrontend.Csharpminor.html">Csharpminor</A>: low-level
structured language.
-<LI> <A HREF="html/Cminor.html">Cminor</A>: low-level structured
+<LI> <A HREF="html/compcert.backend.Cminor.html">Cminor</A>: low-level structured
language, with explicit stack allocation of certain local variables.
-<LI> <A HREF="html/CminorSel.html">CminorSel</A>: like Cminor,
+<LI> <A HREF="html/compcert.backend.CminorSel.html">CminorSel</A>: like Cminor,
with machine-specific operators and addressing modes.
-<LI> <A HREF="html/RTL.html">RTL</A>: register transfer language (3-address
+<LI> <A HREF="html/compcert.backend.RTL.html">RTL</A>: register transfer language (3-address
code, control-flow graph, infinitely many pseudo-registers). <BR>
-See also: <A HREF="html/Registers.html">Registers</A> (representation of
+See also: <A HREF="html/compcert.backend.Registers.html">Registers</A> (representation of
pseudo-registers).
-<LI> <A HREF="html/LTL.html">LTL</A>: location transfer language (3-address
+<LI> <A HREF="html/compcert.backend.LTL.html">LTL</A>: location transfer language (3-address
code, control-flow graph of basic blocks, finitely many physical registers, infinitely
many stack slots). <BR>
-See also: <A HREF="html/Locations.html">Locations</A> (representation of
-locations) and <A HREF="html/Machregs.html"><I>Machregs</I></A> (description of processor registers).
-<LI> <A HREF="html/Linear.html">Linear</A>: like LTL, but the CFG is
+See also: <A HREF="html/compcert.backend.Locations.html">Locations</A> (representation of
+locations) and <A HREF="html/compcert.powerpc.Machregs.html"><I>Machregs</I></A> (description of processor registers).
+<LI> <A HREF="html/compcert.backend.Linear.html">Linear</A>: like LTL, but the CFG is
replaced by a linear list of instructions with explicit branches and labels.
-<LI> <A HREF="html/Mach.html">Mach</A>: like Linear, with a more concrete
+<LI> <A HREF="html/compcert.backend.Mach.html">Mach</A>: like Linear, with a more concrete
view of the activation record.
-<LI> <A HREF="html/Asm.html"><I>Asm</I></A>: abstract syntax for PowerPC assembly
+<LI> <A HREF="html/compcert.powerpc.Asm.html"><I>Asm</I></A>: abstract syntax for PowerPC assembly
code.
</UL>
@@ -153,170 +153,170 @@ code.
<TD>Pulling side-effects out of expressions;<br>
fixing an evaluation order</TD>
<TD>CompCert C to Clight</TD>
- <TD><A HREF="html/SimplExpr.html">SimplExpr</A></TD>
- <TD><A HREF="html/SimplExprspec.html">SimplExprspec</A><br>
- <A HREF="html/SimplExprproof.html">SimplExprproof</A></TD>
+ <TD><A HREF="html/compcert.cfrontend.SimplExpr.html">SimplExpr</A></TD>
+ <TD><A HREF="html/compcert.cfrontend.SimplExprspec.html">SimplExprspec</A><br>
+ <A HREF="html/compcert.cfrontend.SimplExprproof.html">SimplExprproof</A></TD>
</TR>
<TR valign="top">
<TD>Pulling non-adressable scalar local variables out of memory</TD>
<TD>Clight to Clight</TD>
- <TD><A HREF="html/SimplLocals.html">SimplLocals</A></TD>
- <TD><A HREF="html/SimplLocalsproof.html">SimplLocalsproof</A></TD>
+ <TD><A HREF="html/compcert.cfrontend.SimplLocals.html">SimplLocals</A></TD>
+ <TD><A HREF="html/compcert.cfrontend.SimplLocalsproof.html">SimplLocalsproof</A></TD>
</TR>
<TR valign="top">
<TD>Simplification of control structures; <br>
explication of type-dependent computations</TD>
<TD>Clight to Csharpminor</TD>
- <TD><A HREF="html/Cshmgen.html">Cshmgen</A></TD>
- <TD><A HREF="html/Cshmgenproof.html">Cshmgenproof</A></TD>
+ <TD><A HREF="html/compcert.cfrontend.Cshmgen.html">Cshmgen</A></TD>
+ <TD><A HREF="html/compcert.cfrontend.Cshmgenproof.html">Cshmgenproof</A></TD>
</TR>
<TR valign="top">
<TD>Stack allocation of local variables<br>
whose address is taken;<br>
simplification of switch statements</TD>
<TD>Csharpminor to Cminor</TD>
- <TD><A HREF="html/Cminorgen.html">Cminorgen</A></TD>
- <TD><A HREF="html/Cminorgenproof.html">Cminorgenproof</A></TD>
+ <TD><A HREF="html/compcert.cfrontend.Cminorgen.html">Cminorgen</A></TD>
+ <TD><A HREF="html/compcert.cfrontend.Cminorgenproof.html">Cminorgenproof</A></TD>
</TR>
<TR valign="top">
<TD>Recognition of operators<br>and addressing modes</TD>
<TD>Cminor to CminorSel</TD>
- <TD><A HREF="html/Selection.html">Selection</A><br>
- <A HREF="html/SelectOp.html"><I>SelectOp</I></A><br>
- <A HREF="html/SelectLong.html"><I>SelectLong</I></A><br>
- <A HREF="html/SelectDiv.html">SelectDiv</A><br>
- <A HREF="html/SplitLong.html">SplitLong</A></TD>
- <TD><A HREF="html/Selectionproof.html">Selectionproof</A><br>
- <A HREF="html/SelectOpproof.html"><I>SelectOpproof</I></A><br>
- <A HREF="html/SelectLongproof.html"><I>SelectLongproof</I></A><br>
- <A HREF="html/SelectDivproof.html">SelectDivproof</A><br>
- <A HREF="html/SplitLongproof.html">SplitLongproof</A></TD>
+ <TD><A HREF="html/compcert.backend.Selection.html">Selection</A><br>
+ <A HREF="html/Selectcompcert.powerpc.Op.html"><I>SelectOp</I></A><br>
+ <A HREF="html/compcert.powerpc.SelectLong.html"><I>SelectLong</I></A><br>
+ <A HREF="html/compcert.backend.SelectDiv.html">SelectDiv</A><br>
+ <A HREF="html/compcert.backend.SplitLong.html">SplitLong</A></TD>
+ <TD><A HREF="html/compcert.backend.Selectionproof.html">Selectionproof</A><br>
+ <A HREF="html/compcert.powerpc.SelectOpproof.html"><I>SelectOpproof</I></A><br>
+ <A HREF="html/compcert.powerpc.SelectLongproof.html"><I>SelectLongproof</I></A><br>
+ <A HREF="html/compcert.backend.SelectDivproof.html">SelectDivproof</A><br>
+ <A HREF="html/compcert.backend.SplitLongproof.html">SplitLongproof</A></TD>
</TR>
<TR valign="top">
<TD>Construction of the CFG, <br>3-address code generation</TD>
<TD>CminorSel to RTL</TD>
- <TD><A HREF="html/RTLgen.html">RTLgen</A></TD>
- <TD><A HREF="html/RTLgenspec.html">RTLgenspec</A><BR>
- <A HREF="html/RTLgenproof.html">RTLgenproof</A></TD>
+ <TD><A HREF="html/compcert.backend.RTLgen.html">RTLgen</A></TD>
+ <TD><A HREF="html/compcert.backend.RTLgenspec.html">RTLgenspec</A><BR>
+ <A HREF="html/compcert.backend.RTLgenproof.html">RTLgenproof</A></TD>
</TR>
<TR valign="top">
<TD>Recognition of tail calls</TD>
<TD>RTL to RTL</TD>
- <TD><A HREF="html/Tailcall.html">Tailcall</A></TD>
- <TD><A HREF="html/Tailcallproof.html">Tailcallproof</A></TD>
+ <TD><A HREF="html/compcert.backend.Tailcall.html">Tailcall</A></TD>
+ <TD><A HREF="html/compcert.backend.Tailcallproof.html">Tailcallproof</A></TD>
</TR>
<TR valign="top">
<TD>Function inlining</TD>
<TD>RTL to RTL</TD>
- <TD><A HREF="html/Inlining.html">Inlining</A></TD>
- <TD><A HREF="html/Inliningspec.html">Inliningspec</A><BR>
- <A HREF="html/Inliningproof.html">Inliningproof</A></TD>
+ <TD><A HREF="html/compcert.backend.Inlining.html">Inlining</A></TD>
+ <TD><A HREF="html/compcert.backend.Inliningspec.html">Inliningspec</A><BR>
+ <A HREF="html/compcert.backend.Inliningproof.html">Inliningproof</A></TD>
</TR>
<TR valign="top">
<TD>Postorder renumbering of the CFG</TD>
<TD>RTL to RTL</TD>
- <TD><A HREF="html/Renumber.html">Renumber</A></TD>
- <TD><A HREF="html/Renumberproof.html">Renumberproof</A></TD>
+ <TD><A HREF="html/compcert.backend.Renumber.html">Renumber</A></TD>
+ <TD><A HREF="html/compcert.backend.Renumberproof.html">Renumberproof</A></TD>
</TR>
<TR valign="top">
<TD>Constant propagation</TD>
<TD>RTL to RTL</TD>
- <TD><A HREF="html/Constprop.html">Constprop</A><br>
- <A HREF="html/ConstpropOp.html"><I>ConstpropOp</I></A></TD>
- <TD><A HREF="html/Constpropproof.html">Constpropproof</A><br>
- <A HREF="html/ConstpropOpproof.html"><I>ConstproppOproof</I></A></TD>
+ <TD><A HREF="html/compcert.backend.Constprop.html">Constprop</A><br>
+ <A HREF="html/compcert.powerpc.Constpropcompcert.powerpc.Op.html"><I>ConstpropOp</I></A></TD>
+ <TD><A HREF="html/compcert.backend.Constpropproof.html">Constpropproof</A><br>
+ <A HREF="html/compcert.powerpc.ConstpropOpproof.html"><I>ConstproppOproof</I></A></TD>
</TR>
<TR valign="top">
<TD>Common subexpression elimination</TD>
<TD>RTL to RTL</TD>
- <TD><A HREF="html/CSE.html">CSE</A><BR>
- <A HREF="html/CombineOp.html"><I>CombineOp</I></A></TD>
- <TD><A HREF="html/CSEproof.html">CSEproof</A><BR>
- <A HREF="html/CombineOpproof.html"><I>CombineOpproof</I></A></TD>
+ <TD><A HREF="html/compcert.backend.CSE.html">CSE</A><BR>
+ <A HREF="html/compcert.powerpc.Combinecompcert.powerpc.Op.html"><I>CombineOp</I></A></TD>
+ <TD><A HREF="html/compcert.backend.CSEproof.html">CSEproof</A><BR>
+ <A HREF="html/compcert.powerpc.CombineOpproof.html"><I>CombineOpproof</I></A></TD>
</TR>
<TR valign="top">
<TD>Redundancy elimination</TD>
<TD>RTL to RTL</TD>
- <TD><A HREF="html/Deadcode.html">Deadcode</A></TD>
- <TD><A HREF="html/Deadcodeproof.html">Deadcodeproof</A></TD>
+ <TD><A HREF="html/compcert.backend.Deadcode.html">Deadcode</A></TD>
+ <TD><A HREF="html/compcert.backend.Deadcodeproof.html">Deadcodeproof</A></TD>
</TR>
<TR valign="top">
<TD>Removal of unused static globals</TD>
<TD>RTL to RTL</TD>
- <TD><A HREF="html/Unusedglob.html">Unusedglob</A></TD>
- <TD><A HREF="html/Unusedglobproof.html">Unusedglobproof</A></TD>
+ <TD><A HREF="html/compcert.backend.Unusedglob.html">Unusedglob</A></TD>
+ <TD><A HREF="html/compcert.backend.Unusedglobproof.html">Unusedglobproof</A></TD>
</TR>
<TR valign="top">
<TD>Register allocation (validation a posteriori)</TD>
<TD>RTL to LTL</TD>
- <TD><A HREF="html/Allocation.html">Allocation</A></TD>
- <TD><A HREF="html/Allocproof.html">Allocproof</A></TD>
+ <TD><A HREF="html/compcert.backend.Allocation.html">Allocation</A></TD>
+ <TD><A HREF="html/compcert.backend.Allocproof.html">Allocproof</A></TD>
</TR>
<TR valign="top">
<TD>Branch tunneling</TD>
<TD>LTL to LTL</TD>
- <TD><A HREF="html/Tunneling.html">Tunneling</A></TD>
- <TD><A HREF="html/Tunnelingproof.html">Tunnelingproof</A></TD>
+ <TD><A HREF="html/compcert.backend.Tunneling.html">Tunneling</A></TD>
+ <TD><A HREF="html/compcert.backend.Tunnelingproof.html">Tunnelingproof</A></TD>
</TR>
<TR valign="top">
<TD>Linearization of the CFG</TD>
<TD>LTL to Linear</TD>
- <TD><A HREF="html/Linearize.html">Linearize</A></TD>
- <TD><A HREF="html/Linearizeproof.html">Linearizeproof</A></TD>
+ <TD><A HREF="html/compcert.backend.Linearize.html">Linearize</A></TD>
+ <TD><A HREF="html/compcert.backend.Linearizeproof.html">Linearizeproof</A></TD>
</TR>
<TR valign="top">
<TD>Removal of unreferenced labels</TD>
<TD>Linear to Linear</TD>
- <TD><A HREF="html/CleanupLabels.html">CleanupLabels</A></TD>
- <TD><A HREF="html/CleanupLabelsproof.html">CleanupLabelsproof</A></TD>
+ <TD><A HREF="html/compcert.backend.CleanupLabels.html">CleanupLabels</A></TD>
+ <TD><A HREF="html/compcert.backend.CleanupLabelsproof.html">CleanupLabelsproof</A></TD>
</TR>
<TR valign="top">
<TD>Synthesis of debugging information</TD>
<TD>Linear to Linear</TD>
- <TD><A HREF="html/Debugvar.html">Debugvar</A></TD>
- <TD><A HREF="html/Debugvarproof.html">Debugvarproof</A></TD>
+ <TD><A HREF="html/compcert.backend.Debugvar.html">Debugvar</A></TD>
+ <TD><A HREF="html/compcert.backend.Debugvarproof.html">Debugvarproof</A></TD>
</TR>
<TR valign="top">
<TD>Laying out the activation records</TD>
<TD>Linear to Mach</TD>
- <TD><A HREF="html/Stacking.html">Stacking</A><BR>
- <A HREF="html/Bounds.html">Bounds</A><BR>
- <A HREF="html/Stacklayout.html"><I>Stacklayout</I></A></TD>
- <TD><A HREF="html/Stackingproof.html">Stackingproof</A><br>
- <A HREF="html/Separation.html">Separation</A></TD>
+ <TD><A HREF="html/compcert.backend.Stacking.html">Stacking</A><BR>
+ <A HREF="html/compcert.backend.Bounds.html">Bounds</A><BR>
+ <A HREF="html/compcert.powerpc.Stacklayout.html"><I>Stacklayout</I></A></TD>
+ <TD><A HREF="html/compcert.backend.Stackingproof.html">Stackingproof</A><br>
+ <A HREF="html/compcert.common.Separation.html">Separation</A></TD>
</TR>
<TR valign="top">
<TD>Emission of assembly code</TD>
<TD>Mach to Asm</TD>
- <TD><A HREF="html/Asmgen.html"><I>Asmgen</I></A></TD>
- <TD><A HREF="html/Asmgenproof0.html"><I>Asmgenproof0</I></A><BR>
- <A HREF="html/Asmgenproof1.html"><I>Asmgenproof1</I></A><BR>
- <A HREF="html/Asmgenproof.html"><I>Asmgenproof</I></A></TD>
+ <TD><A HREF="html/compcert.powerpc.Asmgen.html"><I>Asmgen</I></A></TD>
+ <TD><A HREF="html/compcert.backend.Asmgenproof0.html"><I>Asmgenproof0</I></A><BR>
+ <A HREF="html/compcert.powerpc.Asmgenproof1.html"><I>Asmgenproof1</I></A><BR>
+ <A HREF="html/compcert.powerpc.Asmgenproof.html"><I>Asmgenproof</I></A></TD>
</TR>
</TABLE>
<H3>All together</H3>
<UL>
-<LI> <A HREF="html/Compiler.html">Compiler</A>: composing the passes together;
+<LI> <A HREF="html/compcert.driver.Compiler.html">Compiler</A>: composing the passes together;
whole-compiler semantic preservation theorems.
-<LI> <A HREF="html/Complements.html">Complements</A>: interesting consequences of the semantic preservation theorems.
+<LI> <A HREF="html/compcert.driver.Complements.html">Complements</A>: interesting consequences of the semantic preservation theorems.
</UL>
<H3>Static analyses</H3>
@@ -325,23 +325,23 @@ The following static analyses are performed over the RTL intermediate
representation to support optimizations such as constant propagation,
CSE, and dead code elimination.
<UL>
-<LI> <A HREF="html/Liveness.html">Liveness</A>: liveness analysis</A>.
-<LI> <A HREF="html/ValueAnalysis.html">ValueAnalysis</A>: value and alias analysis</A> <BR>
-See also: <A HREF="html/ValueDomain.html">ValueDomain</A>: the abstract domain for value analysis.<BR>
-See also: <A HREF="html/ValueAOp.html"><I>ValueAOp</I></A>: processor-dependent parts of value analysis.
-<LI> <A HREF="html/Deadcode.html">Deadcode</A>: neededness analysis</A> <BR>
-See also: <A HREF="html/NeedDomain.html">NeedDomain</A>: the abstract domain for neededness analysis.<BR>
-See also: <A HREF="html/NeedOp.html"><I>NeedOp</I></A>: processor-dependent parts of neededness analysis.
+<LI> <A HREF="html/compcert.backend.Liveness.html">Liveness</A>: liveness analysis</A>.
+<LI> <A HREF="html/compcert.backend.ValueAnalysis.html">ValueAnalysis</A>: value and alias analysis</A> <BR>
+See also: <A HREF="html/compcert.backend.ValueDomain.html">ValueDomain</A>: the abstract domain for value analysis.<BR>
+See also: <A HREF="html/ValueAcompcert.powerpc.Op.html"><I>ValueAOp</I></A>: processor-dependent parts of value analysis.
+<LI> <A HREF="html/compcert.backend.Deadcode.html">Deadcode</A>: neededness analysis</A> <BR>
+See also: <A HREF="html/compcert.backend.NeedDomain.html">NeedDomain</A>: the abstract domain for neededness analysis.<BR>
+See also: <A HREF="html/compcert.powerpc.Needcompcert.powerpc.Op.html"><I>NeedOp</I></A>: processor-dependent parts of neededness analysis.
</UL>
<H3>Type systems</H3>
-The <A HREF="html/Ctyping.html">type system of CompCert C</A> is fully formalized. For some intermediate languages of the back-end, simpler type systems are used to statically capture well-formedness conditions.
+The <A HREF="html/compcert.cfrontend.Ctyping.html">type system of CompCert C</A> is fully formalized. For some intermediate languages of the back-end, simpler type systems are used to statically capture well-formedness conditions.
<UL>
-<LI> <A HREF="html/Ctyping.html">RTLtyping</A>: typing for CompCert C + type-checking functions.
-<LI> <A HREF="html/RTLtyping.html">RTLtyping</A>: typing for RTL + type
+<LI> <A HREF="html/compcert.cfrontend.Ctyping.html">Ctyping</A>: typing for CompCert C + type-checking functions.
+<LI> <A HREF="html/compcert.backend.RTLtyping.html">RTLtyping</A>: typing for RTL + type
reconstruction.
-<LI> <A HREF="html/Lineartyping.html">Lineartyping</A>: typing for Linear.
+<LI> <A HREF="html/compcert.backend.Lineartyping.html">Lineartyping</A>: typing for Linear.
</UL>
<HR>
diff --git a/driver/Assembler.mli b/driver/Assembler.mli
index d8a4e32b..4f2e95ae 100644
--- a/driver/Assembler.mli
+++ b/driver/Assembler.mli
@@ -15,7 +15,7 @@ val assemble: string -> string -> unit
(** From asm to object file *)
val assembler_actions: (Commandline.pattern * Commandline.action) list
- (** Commandline optins affecting the assembler *)
+ (** Commandline options affecting the assembler *)
val assembler_help: string
(** Commandline help description *)
diff --git a/driver/Commandline.ml b/driver/Commandline.ml
index f139212d..75ca1683 100644
--- a/driver/Commandline.ml
+++ b/driver/Commandline.ml
@@ -74,7 +74,7 @@ let parse_array spec argv first last =
with Not_found -> find_action s inexact_cases in
match optact with
| None ->
- let msg = sprintf "Unknown argument `%s'" s in
+ let msg = sprintf "unknown argument `%s'" s in
raise (CmdError msg)
| Some(Set r) ->
r := true; parse (i+1)
@@ -86,7 +86,7 @@ let parse_array spec argv first last =
if i + 1 <= last then begin
fn argv.(i+1); parse (i+2)
end else begin
- let msg = sprintf "Option `%s' expects an argument" s in
+ let msg = sprintf "option `%s' expects an argument" s in
raise (CmdError msg)
end
| Some(Integer fn) ->
@@ -95,19 +95,19 @@ let parse_array spec argv first last =
try
int_of_string argv.(i+1)
with Failure _ ->
- let msg = sprintf "Argument to option `%s' must be an integer" s in
+ let msg = sprintf "argument to option `%s' must be an integer" s in
raise (CmdError msg)
in
fn n; parse (i+2)
end else begin
- let msg = sprintf "Option `%s' expects an argument" s in
+ let msg = sprintf "option `%s' expects an argument" s in
raise (CmdError msg)
end
| Some (Ignore) ->
if i + 1 <= last then begin
parse (i+2)
end else begin
- let msg = sprintf "Option `%s' expects an argument" s in
+ let msg = sprintf "option `%s' expects an argument" s in
raise (CmdError msg)
end
| Some (Unit f) -> f (); parse (i+1)
@@ -131,7 +131,7 @@ let long_int_action key s =
try
int_of_string s
with Failure _ ->
- let msg = sprintf "Argument to option `%s' must be an integer" key in
+ let msg = sprintf "argument to option `%s' must be an integer" key in
raise (CmdError msg)
let longopt_int key f =
diff --git a/driver/Complements.v b/driver/Complements.v
index d1bea1b3..3660fff0 100644
--- a/driver/Complements.v
+++ b/driver/Complements.v
@@ -13,30 +13,20 @@
(** Corollaries of the main semantic preservation theorem. *)
Require Import Classical.
-Require Import Coqlib.
-Require Import AST.
-Require Import Integers.
-Require Import Values.
-Require Import Events.
-Require Import Globalenvs.
-Require Import Smallstep.
-Require Import Behaviors.
-Require Import Csyntax.
-Require Import Csem.
-Require Import Cstrategy.
-Require Import Clight.
-Require Import Cminor.
-Require Import RTL.
-Require Import Asm.
+Require Import Coqlib Errors.
+Require Import AST Linking Events Smallstep Behaviors.
+Require Import Csyntax Csem Cstrategy Asm.
Require Import Compiler.
-Require Import Errors.
(** * Preservation of whole-program behaviors *)
(** From the simulation diagrams proved in file [Compiler]. it follows that
whole-program observable behaviors are preserved in the following sense.
First, every behavior of the generated assembly code is matched by
- a behavior of the source C code. *)
+ a behavior of the source C code. The behavior [beh] of the assembly
+ code is either identical to the behavior [beh'] of the source C code
+ or ``improves upon'' [beh'] by replacing a ``going wrong'' behavior
+ with a more defined behavior. *)
Theorem transf_c_program_preservation:
forall p tp beh,
@@ -48,8 +38,9 @@ Proof.
apply transf_c_program_correct; auto.
Qed.
-(** As a corollary, if the source C code cannot go wrong, the behavior of the
- generated assembly code is one of the possible behaviors of the source C code. *)
+(** As a corollary, if the source C code cannot go wrong, i.e. is free of
+ undefined behaviors, the behavior of the generated assembly code is
+ one of the possible behaviors of the source C code. *)
Theorem transf_c_program_is_refinement:
forall p tp,
@@ -124,83 +115,190 @@ Qed.
(** * Satisfaction of specifications *)
(** The second additional results shows that if all executions
- of the source C program satisfies a given specification
- (a predicate on the observable behavior of the program),
+ of the source C program satisfies a given specification,
then all executions of the produced Asm program satisfy
- this specification as well.
-
- We first show this result for specifications that are stable
- under the [behavior_improves] relation. *)
-
-Section SPECS_PRESERVED.
-
-Variable spec: program_behavior -> Prop.
+ this specification as well. *)
+
+(** The specifications we consider here are sets of observable
+ behaviors, representing the good behaviors a program is expected
+ to have. A specification can be as simple as
+ ``the program does not go wrong'' or as precise as
+ ``the program prints a prime number then terminates with code 0''.
+ As usual in Coq, sets of behaviors are represented as predicates
+ [program_behavior -> Prop]. *)
+
+Definition specification := program_behavior -> Prop.
+
+(** A program satisfies a specification if all its observable behaviors
+ are in the specification. *)
+
+Definition c_program_satisfies_spec (p: Csyntax.program) (spec: specification): Prop :=
+ forall beh, program_behaves (Csem.semantics p) beh -> spec beh.
+Definition asm_program_satisfies_spec (p: Asm.program) (spec: specification): Prop :=
+ forall beh, program_behaves (Asm.semantics p) beh -> spec beh.
+
+(** It is not always the case that if the source program satisfies a
+ specification, then the generated assembly code satisfies it as
+ well. For example, if the specification is ``the program goes wrong
+ on an undefined behavior'', a C source that goes wrong satisfies
+ this specification but can be compiled into Asm code that does not
+ go wrong and therefore does not satisfy the specification.
+
+ For this reason, we restrict ourselves to safety-enforcing specifications:
+ specifications that exclude ``going wrong'' behaviors and are satisfied
+ only by programs that execute safely. *)
+
+Definition safety_enforcing_specification (spec: specification): Prop :=
+ forall beh, spec beh -> not_wrong beh.
-Hypothesis spec_stable:
- forall beh1 beh2, behavior_improves beh1 beh2 -> spec beh1 -> spec beh2.
+(** As the main result of this section, we show that CompCert
+ compilation preserves safety-enforcing specifications:
+ any such specification that is satisfied by the source C program is
+ always satisfied by the generated assembly code. *)
Theorem transf_c_program_preserves_spec:
- forall p tp,
+ forall p tp spec,
transf_c_program p = OK tp ->
- (forall beh, program_behaves (Csem.semantics p) beh -> spec beh) ->
- (forall beh, program_behaves (Asm.semantics tp) beh -> spec beh).
+ safety_enforcing_specification spec ->
+ c_program_satisfies_spec p spec ->
+ asm_program_satisfies_spec tp spec.
Proof.
- intros.
- exploit transf_c_program_preservation; eauto. intros [beh' [A B]].
- apply spec_stable with beh'; auto.
+ intros p tp spec TRANSF SES CSAT; red; intros beh AEXEC.
+ exploit transf_c_program_preservation; eauto. intros (beh' & CEXEC & IMPR).
+ apply CSAT in CEXEC. destruct IMPR as [EQ | [t [A B]]].
+- congruence.
+- subst beh'. apply SES in CEXEC. contradiction.
Qed.
-End SPECS_PRESERVED.
+(** Safety-enforcing specifications are not the only good properties
+ of source programs that are preserved by compilation. Another example
+ of a property that is preserved is the ``initial trace'' property:
+ all executions of the program start by producing an expected trace
+ of I/O actions, representing the good behavior expected from the program.
+ After that, the program may terminate, or continue running, or go wrong
+ on an undefined behavior. What matters is that the program produced
+ the expected trace at the beginning of its execution. This is a typical
+ liveness property, and it is preserved by compilation. *)
+
+Definition c_program_has_initial_trace (p: Csyntax.program) (t: trace): Prop :=
+ forall beh, program_behaves (Csem.semantics p) beh -> behavior_prefix t beh.
+Definition asm_program_has_initial_trace (p: Asm.program) (t: trace): Prop :=
+ forall beh, program_behaves (Asm.semantics p) beh -> behavior_prefix t beh.
+
+Theorem transf_c_program_preserves_initial_trace:
+ forall p tp t,
+ transf_c_program p = OK tp ->
+ c_program_has_initial_trace p t ->
+ asm_program_has_initial_trace tp t.
+Proof.
+ intros p tp t TRANSF CTRACE; red; intros beh AEXEC.
+ exploit transf_c_program_preservation; eauto. intros (beh' & CEXEC & IMPR).
+ apply CTRACE in CEXEC. destruct IMPR as [EQ | [t' [A B]]].
+- congruence.
+- destruct CEXEC as (beh1' & EQ').
+ destruct B as (beh1 & EQ).
+ subst beh'. destruct beh1'; simpl in A; inv A.
+ exists (behavior_app t0 beh1). apply behavior_app_assoc.
+Qed.
-(** As a corollary, we obtain preservation of safety specifications:
- specifications that exclude "going wrong" behaviors. *)
+(** * Extension to separate compilation *)
-Section SAFETY_PRESERVED.
+(** The results above were given in terms of whole-program compilation.
+ They also extend to separate compilation followed by linking. *)
-Variable spec: program_behavior -> Prop.
+Section SEPARATE_COMPILATION.
-Hypothesis spec_safety:
- forall beh, spec beh -> not_wrong beh.
+(** The source: a list of C compilation units *)
+Variable c_units: nlist Csyntax.program.
-Theorem transf_c_program_preserves_safety_spec:
- forall p tp,
- transf_c_program p = OK tp ->
- (forall beh, program_behaves (Csem.semantics p) beh -> spec beh) ->
- (forall beh, program_behaves (Asm.semantics tp) beh -> spec beh).
+(** The compiled code: a list of Asm compilation units, obtained by separate compilation *)
+Variable asm_units: nlist Asm.program.
+Hypothesis separate_compilation_succeeds:
+ nlist_forall2 (fun cu tcu => transf_c_program cu = OK tcu) c_units asm_units.
+
+(** We assume that the source C compilation units can be linked together
+ to obtain a monolithic C program [c_program]. *)
+Variable c_program: Csyntax.program.
+Hypothesis source_linking: link_list c_units = Some c_program.
+
+(** Then, linking the Asm units obtained by separate compilation succeeds. *)
+Lemma compiled_linking_succeeds:
+ { asm_program | link_list asm_units = Some asm_program }.
Proof.
- intros. eapply transf_c_program_preserves_spec; eauto.
- intros. destruct H2. congruence. destruct H2 as [t [EQ1 EQ2]].
- subst beh1. elim (spec_safety _ H3).
+ destruct (link_list asm_units) eqn:E.
+- exists p; auto.
+- exfalso.
+ exploit separate_transf_c_program_correct; eauto. intros (a & P & Q).
+ congruence.
Qed.
-End SAFETY_PRESERVED.
+(** Let asm_program be the result of linking the Asm units. *)
+Let asm_program: Asm.program := proj1_sig compiled_linking_succeeds.
+Let compiled_linking: link_list asm_units = Some asm_program := proj2_sig compiled_linking_succeeds.
+
+(** Then, [asm_program] preserves the semantics and the specifications of
+ [c_program], in the following sense.
+ First, every behavior of [asm_program] improves upon one of the possible
+ behaviors of [c_program]. *)
-(** We also have preservation of liveness specifications:
- specifications that assert the existence of a prefix of the observable
- trace satisfying some conditions. *)
+Theorem separate_transf_c_program_preservation:
+ forall beh,
+ program_behaves (Asm.semantics asm_program) beh ->
+ exists beh', program_behaves (Csem.semantics c_program) beh' /\ behavior_improves beh' beh.
+Proof.
+ intros. exploit separate_transf_c_program_correct; eauto. intros (a & P & Q).
+ assert (a = asm_program) by congruence. subst a.
+ eapply backward_simulation_behavior_improves; eauto.
+Qed.
-Section LIVENESS_PRESERVED.
+(** As a corollary, if [c_program] is free of undefined behaviors,
+ the behavior of [asm_program] is one of the possible behaviors of [c_program]. *)
-Variable spec: trace -> Prop.
+Theorem separate_transf_c_program_is_refinement:
+ (forall beh, program_behaves (Csem.semantics c_program) beh -> not_wrong beh) ->
+ (forall beh, program_behaves (Asm.semantics asm_program) beh -> program_behaves (Csem.semantics c_program) beh).
+Proof.
+ intros. exploit separate_transf_c_program_preservation; eauto. intros (beh' & P & Q).
+ assert (not_wrong beh') by auto.
+ inv Q.
+- auto.
+- destruct H2 as (t & U & V). subst beh'. elim H1.
+Qed.
-Definition liveness_spec_satisfied (b: program_behavior) : Prop :=
- exists t, behavior_prefix t b /\ spec t.
+(** We now show that if all executions of [c_program] satisfy a specification,
+ then all executions of [asm_program] also satisfy the specification, provided
+ the specification is of the safety-enforcing kind. *)
-Theorem transf_c_program_preserves_liveness_spec:
- forall p tp,
- transf_c_program p = OK tp ->
- (forall beh, program_behaves (Csem.semantics p) beh -> liveness_spec_satisfied beh) ->
- (forall beh, program_behaves (Asm.semantics tp) beh -> liveness_spec_satisfied beh).
+Theorem separate_transf_c_program_preserves_spec:
+ forall spec,
+ safety_enforcing_specification spec ->
+ c_program_satisfies_spec c_program spec ->
+ asm_program_satisfies_spec asm_program spec.
Proof.
- intros. eapply transf_c_program_preserves_spec; eauto.
- intros. destruct H3 as [t1 [A B]]. destruct H2.
- subst. exists t1; auto.
- destruct H2 as [t [C D]]. subst.
- destruct A as [b1 E]. destruct D as [b2 F].
- destruct b1; simpl in E; inv E.
- exists t1; split; auto.
- exists (behavior_app t0 b2); apply behavior_app_assoc.
+ intros spec SES CSAT; red; intros beh AEXEC.
+ exploit separate_transf_c_program_preservation; eauto. intros (beh' & CEXEC & IMPR).
+ apply CSAT in CEXEC. destruct IMPR as [EQ | [t [A B]]].
+- congruence.
+- subst beh'. apply SES in CEXEC. contradiction.
Qed.
-End LIVENESS_PRESERVED.
+(** As another corollary of [separate_transf_c_program_preservation],
+ if all executions of [c_program] have a trace [t] as initial trace,
+ so do all executions of [asm_program]. *)
+
+Theorem separate_transf_c_program_preserves_initial_trace:
+ forall t,
+ c_program_has_initial_trace c_program t ->
+ asm_program_has_initial_trace asm_program t.
+Proof.
+ intros t CTRACE; red; intros beh AEXEC.
+ exploit separate_transf_c_program_preservation; eauto. intros (beh' & CEXEC & IMPR).
+ apply CTRACE in CEXEC. destruct IMPR as [EQ | [t' [A B]]].
+- congruence.
+- destruct CEXEC as (beh1' & EQ').
+ destruct B as (beh1 & EQ).
+ subst beh'. destruct beh1'; simpl in A; inv A.
+ exists (behavior_app t0 beh1). apply behavior_app_assoc.
+Qed.
+End SEPARATE_COMPILATION.
diff --git a/driver/Driver.ml b/driver/Driver.ml
index 0ad820ea..8ab8557c 100644
--- a/driver/Driver.ml
+++ b/driver/Driver.ml
@@ -404,7 +404,7 @@ let _ =
parse_cmdline cmdline_actions;
DebugInit.init (); (* Initialize the debug functions *)
if nolink () && !option_o <> None && !num_source_files >= 2 then
- fatal_error no_loc "Ambiguous '-o' option (multiple source files)";
+ fatal_error no_loc "ambiguous '-o' option (multiple source files)";
if !num_input_files = 0 then
fatal_error no_loc "no input file";
let linker_args = time "Total compilation time" perform_actions () in
diff --git a/driver/Driveraux.ml b/driver/Driveraux.ml
index ccc3d00d..5b2d792e 100644
--- a/driver/Driveraux.ml
+++ b/driver/Driveraux.ml
@@ -47,7 +47,7 @@ let command stdout args =
match status with
| Unix.WEXITED rc -> rc
| Unix.WSIGNALED n | Unix.WSTOPPED n ->
- error no_loc "Command '%s' killed on a signal." argv.(0); -1
+ error no_loc "command '%s' killed on a signal." argv.(0); -1
with Unix.Unix_error(err, fn, param) ->
error no_loc "executing '%s': %s: %s %s"
argv.(0) fn (Unix.error_message err) param;
diff --git a/driver/Frontend.ml b/driver/Frontend.ml
index db84a9f9..b29bb7f3 100644
--- a/driver/Frontend.ml
+++ b/driver/Frontend.ml
@@ -17,6 +17,15 @@ open Driveraux
(* Common frontend functions between clightgen and ccomp *)
+let predefined_macros =
+ [
+ "-D__COMPCERT__";
+ "-U__STDC_IEC_559_COMPLEX__";
+ "-D__STDC_NO_ATOMICS__";
+ "-D__STDC_NO_COMPLEX__";
+ "-D__STDC_NO_THREADS__";
+ "-D__STDC_NO_VLA__"
+ ]
(* From C to preprocessed C *)
@@ -26,7 +35,7 @@ let preprocess ifile ofile =
if ofile = "-" then None else Some ofile in
let cmd = List.concat [
Configuration.prepro;
- ["-D__COMPCERT__"];
+ predefined_macros;
(if !Clflags.use_standard_headers
then ["-I" ^ Filename.concat !Clflags.stdlib_path "include" ]
else []);
@@ -64,10 +73,12 @@ let parse_c_file sourcename ifile =
let init () =
Machine.config:=
begin match Configuration.arch with
- | "powerpc" -> if Configuration.gnu_toolchain
- then if Configuration.abi = "linux"
- then Machine.ppc_32_linux_bigendian
- else Machine.ppc_32_bigendian
+ | "powerpc" -> if Configuration.model = "e5500" || Configuration.model = "ppc64"
+ then if Configuration.abi = "linux" then Machine.ppc_32_r64_linux_bigendian
+ else if Configuration.gnu_toolchain then Machine.ppc_32_r64_bigendian
+ else Machine.ppc_32_r64_diab_bigendian
+ else if Configuration.abi = "linux" then Machine.ppc_32_linux_bigendian
+ else if Configuration.gnu_toolchain then Machine.ppc_32_bigendian
else Machine.ppc_32_diab_bigendian
| "arm" -> if Configuration.is_big_endian
then Machine.arm_bigendian
@@ -116,7 +127,7 @@ let gnu_prepro_actions = [
Exact "-imacros", String (gnu_prepro_opt_key "-imacros");
Exact "-idirafter", String (gnu_prepro_opt_key "-idirafter");
Exact "-isystem", String (gnu_prepro_opt_key "-isystem");
- Exact "-iquote", String (gnu_prepro_opt_key "-iquore");
+ Exact "-iquote", String (gnu_prepro_opt_key "-iquote");
Exact "-P", Self gnu_prepro_opt;
Exact "-C", Self gnu_prepro_opt;
Exact "-CC", Self gnu_prepro_opt;]
diff --git a/driver/Frontend.mli b/driver/Frontend.mli
index 39f0e612..a18c2704 100644
--- a/driver/Frontend.mli
+++ b/driver/Frontend.mli
@@ -18,7 +18,7 @@ val parse_c_file: string -> string -> Csyntax.coq_function Ctypes.program
(** From preprocessed C to Csyntax *)
val prepro_actions: (Commandline.pattern * Commandline.action) list
- (** Commandline optins affecting the frontend *)
+ (** Commandline options affecting the frontend *)
val prepro_help: string
(** Commandline help description *)
diff --git a/driver/Linker.ml b/driver/Linker.ml
index 6e6ad6b4..d6e1d384 100644
--- a/driver/Linker.ml
+++ b/driver/Linker.ml
@@ -86,4 +86,4 @@ let linker_actions =
push_linker_arg s);
Prefix "-Wl,", Self push_linker_arg;
Prefix "-WUl,", Self (fun s -> List.iter push_linker_arg (explode_comma_option s));
- Exact "-u", Self push_linker_arg;]
+ Exact "-u", String (fun s -> push_linker_arg "-u"; push_linker_arg s);]
diff --git a/driver/Linker.mli b/driver/Linker.mli
index 3b92da05..dd034543 100644
--- a/driver/Linker.mli
+++ b/driver/Linker.mli
@@ -12,10 +12,10 @@
(* *********************************************************************)
val linker: string -> string list -> unit
- (** Link files into executbale *)
+ (** Link files into executable *)
val linker_actions: (Commandline.pattern * Commandline.action) list
- (** Commandline optins affecting the assembler *)
+ (** Commandline options affecting the assembler *)
val linker_help: string
(** Commandline help description *)
diff --git a/exportclight/Clightgen.ml b/exportclight/Clightgen.ml
index 9cb0674e..1eb4fe03 100644
--- a/exportclight/Clightgen.ml
+++ b/exportclight/Clightgen.ml
@@ -53,7 +53,8 @@ let compile_c_ast sourcename csyntax ofile =
end;
(* Print Clight in Coq syntax *)
let oc = open_out ofile in
- ExportClight.print_program (Format.formatter_of_out_channel oc) clight;
+ ExportClight.print_program (Format.formatter_of_out_channel oc)
+ clight sourcename !option_normalize;
close_out oc
(* From C source to Clight *)
diff --git a/exportclight/ExportClight.ml b/exportclight/ExportClight.ml
index 1ae78c15..b124586a 100644
--- a/exportclight/ExportClight.ml
+++ b/exportclight/ExportClight.ml
@@ -487,8 +487,7 @@ let print_assertions p =
let prologue = "\
From Coq Require Import String List ZArith.\n\
From compcert Require Import Coqlib Integers Floats AST Ctypes Cop Clight Clightdefs.\n\
-Local Open Scope Z_scope.\n\
-\n"
+Local Open Scope Z_scope.\n"
(* Naming the compiler-generated temporaries occurring in the program *)
@@ -543,13 +542,30 @@ let name_globdef (id, g) =
let name_program p =
List.iter name_globdef p.Ctypes.prog_defs
+(* Information about this run of clightgen *)
+
+let print_clightgen_info p sourcefile normalized =
+ fprintf p "@[<v 2>Module Info.";
+ fprintf p "@ Definition version := %S%%string." Version.version;
+ fprintf p "@ Definition build_number := %S%%string." Version.buildnr;
+ fprintf p "@ Definition build_tag := %S%%string." Version.tag;
+ fprintf p "@ Definition arch := %S%%string." Configuration.arch;
+ fprintf p "@ Definition model := %S%%string." Configuration.model;
+ fprintf p "@ Definition abi := %S%%string." Configuration.abi;
+ fprintf p "@ Definition bitsize := %d." (if Archi.ptr64 then 64 else 32);
+ fprintf p "@ Definition big_endian := %B." Archi.big_endian;
+ fprintf p "@ Definition source_file := %S%%string." sourcefile;
+ fprintf p "@ Definition normalized := %B." normalized;
+ fprintf p "@]@ End Info.@ @ "
+
(* All together *)
-let print_program p prog =
+let print_program p prog sourcefile normalized =
Hashtbl.clear temp_names;
name_program prog;
fprintf p "@[<v 0>";
fprintf p "%s" prologue;
+ print_clightgen_info p sourcefile normalized;
define_idents p;
List.iter (print_globdef p) prog.Ctypes.prog_defs;
fprintf p "Definition composites : list composite_definition :=@ ";
diff --git a/flocq/Appli/Fappli_IEEE.v b/flocq/Appli/Fappli_IEEE.v
index 161b545a..7503dc1d 100644
--- a/flocq/Appli/Fappli_IEEE.v
+++ b/flocq/Appli/Fappli_IEEE.v
@@ -597,9 +597,8 @@ revert H1. clear -H2.
rewrite Zpos_digits2_pos.
unfold fexp, FLT_exp.
generalize (Zdigits radix2 (Zpos mx)).
-intros ; zify ; subst.
-clear -H H2. clearbody emin.
-omega.
+clearbody emin.
+intros ; zify ; omega.
Qed.
Theorem abs_B2R_lt_emax :
diff --git a/flocq/Appli/Fappli_double_round.v b/flocq/Appli/Fappli_double_round.v
index 2c4937ab..82f61da3 100644
--- a/flocq/Appli/Fappli_double_round.v
+++ b/flocq/Appli/Fappli_double_round.v
@@ -5,6 +5,7 @@ Require Import Fcore_defs.
Require Import Fcore_generic_fmt.
Require Import Fcalc_ops.
Require Import Fcore_ulp.
+Require Fcore_FLX Fcore_FLT Fcore_FTZ.
Require Import Psatz.
@@ -659,7 +660,7 @@ Qed.
Section Double_round_mult_FLX.
-Require Import Fcore_FLX.
+Import Fcore_FLX.
Variable prec : Z.
Variable prec' : Z.
@@ -685,8 +686,8 @@ End Double_round_mult_FLX.
Section Double_round_mult_FLT.
-Require Import Fcore_FLX.
-Require Import Fcore_FLT.
+Import Fcore_FLX.
+Import Fcore_FLT.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -718,7 +719,8 @@ End Double_round_mult_FLT.
Section Double_round_mult_FTZ.
-Require Import Fcore_FTZ.
+Import Fcore_FLX.
+Import Fcore_FTZ.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -796,7 +798,7 @@ Lemma ln_beta_minus_disj :
\/ (ln_beta (x - y) = (ln_beta x - 1)%Z :> Z)).
Proof.
intros x y Px Py Hln.
-assert (Hxy : y < x); [now apply (ln_beta_lt_pos beta); [| |omega]|].
+assert (Hxy : y < x); [now apply (ln_beta_lt_pos beta); [ |omega]|].
generalize (ln_beta_minus beta x y Py Hxy); intro Hln2.
generalize (ln_beta_minus_lb beta x y Px Py Hln); intro Hln3.
omega.
@@ -1611,7 +1613,7 @@ Qed.
Section Double_round_plus_FLX.
-Require Import Fcore_FLX.
+Import Fcore_FLX.
Variable prec : Z.
Variable prec' : Z.
@@ -1667,8 +1669,8 @@ End Double_round_plus_FLX.
Section Double_round_plus_FLT.
-Require Import Fcore_FLX.
-Require Import Fcore_FLT.
+Import Fcore_FLX.
+Import Fcore_FLT.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -1739,8 +1741,8 @@ End Double_round_plus_FLT.
Section Double_round_plus_FTZ.
-Require Import Fcore_FLX.
-Require Import Fcore_FTZ.
+Import Fcore_FLX.
+Import Fcore_FTZ.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -2325,7 +2327,7 @@ Qed.
Section Double_round_plus_beta_ge_3_FLX.
-Require Import Fcore_FLX.
+Import Fcore_FLX.
Variable prec : Z.
Variable prec' : Z.
@@ -2385,8 +2387,8 @@ End Double_round_plus_beta_ge_3_FLX.
Section Double_round_plus_beta_ge_3_FLT.
-Require Import Fcore_FLX.
-Require Import Fcore_FLT.
+Import Fcore_FLX.
+Import Fcore_FLT.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -2461,8 +2463,8 @@ End Double_round_plus_beta_ge_3_FLT.
Section Double_round_plus_beta_ge_3_FTZ.
-Require Import Fcore_FLX.
-Require Import Fcore_FTZ.
+Import Fcore_FLX.
+Import Fcore_FTZ.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -2880,7 +2882,7 @@ Qed.
Section Double_round_sqrt_FLX.
-Require Import Fcore_FLX.
+Import Fcore_FLX.
Variable prec : Z.
Variable prec' : Z.
@@ -2917,8 +2919,8 @@ End Double_round_sqrt_FLX.
Section Double_round_sqrt_FLT.
-Require Import Fcore_FLX.
-Require Import Fcore_FLT.
+Import Fcore_FLX.
+Import Fcore_FLT.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -2972,8 +2974,8 @@ End Double_round_sqrt_FLT.
Section Double_round_sqrt_FTZ.
-Require Import Fcore_FLX.
-Require Import Fcore_FTZ.
+Import Fcore_FLX.
+Import Fcore_FTZ.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -3318,7 +3320,7 @@ Qed.
Section Double_round_sqrt_beta_ge_4_FLX.
-Require Import Fcore_FLX.
+Import Fcore_FLX.
Variable prec : Z.
Variable prec' : Z.
@@ -3357,8 +3359,8 @@ End Double_round_sqrt_beta_ge_4_FLX.
Section Double_round_sqrt_beta_ge_4_FLT.
-Require Import Fcore_FLX.
-Require Import Fcore_FLT.
+Import Fcore_FLX.
+Import Fcore_FLT.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -3414,8 +3416,8 @@ End Double_round_sqrt_beta_ge_4_FLT.
Section Double_round_sqrt_beta_ge_4_FTZ.
-Require Import Fcore_FLX.
-Require Import Fcore_FTZ.
+Import Fcore_FLX.
+Import Fcore_FTZ.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -4401,7 +4403,7 @@ Qed.
Section Double_round_div_FLX.
-Require Import Fcore_FLX.
+Import Fcore_FLX.
Variable prec : Z.
Variable prec' : Z.
@@ -4445,8 +4447,8 @@ End Double_round_div_FLX.
Section Double_round_div_FLT.
-Require Import Fcore_FLX.
-Require Import Fcore_FLT.
+Import Fcore_FLX.
+Import Fcore_FLT.
Variable emin prec : Z.
Variable emin' prec' : Z.
@@ -4515,8 +4517,8 @@ End Double_round_div_FLT.
Section Double_round_div_FTZ.
-Require Import Fcore_FLX.
-Require Import Fcore_FTZ.
+Import Fcore_FLX.
+Import Fcore_FTZ.
Variable emin prec : Z.
Variable emin' prec' : Z.
diff --git a/flocq/Core/Fcore_FLT.v b/flocq/Core/Fcore_FLT.v
index 53dc48a7..2258b1d9 100644
--- a/flocq/Core/Fcore_FLT.v
+++ b/flocq/Core/Fcore_FLT.v
@@ -257,32 +257,33 @@ apply Rle_lt_trans with (2:=Hx).
now apply He.
Qed.
-Theorem ulp_FLT_le: forall x, (bpow (emin+prec) <= Rabs x)%R ->
- (ulp beta FLT_exp x <= Rabs x * bpow (1-prec))%R.
+Theorem ulp_FLT_le :
+ forall x, (bpow (emin + prec - 1) <= Rabs x)%R ->
+ (ulp beta FLT_exp x <= Rabs x * bpow (1 - prec))%R.
Proof.
intros x Hx.
-assert (x <> 0)%R.
-intros Z; contradict Hx; apply Rgt_not_le, Rlt_gt.
-rewrite Z, Rabs_R0; apply bpow_gt_0.
-rewrite ulp_neq_0; try assumption.
+assert (Zx : (x <> 0)%R).
+ intros Z; contradict Hx; apply Rgt_not_le, Rlt_gt.
+ rewrite Z, Rabs_R0; apply bpow_gt_0.
+rewrite ulp_neq_0 with (1 := Zx).
unfold canonic_exp, FLT_exp.
destruct (ln_beta beta x) as (e,He).
apply Rle_trans with (bpow (e-1)*bpow (1-prec))%R.
rewrite <- bpow_plus.
right; apply f_equal.
-apply trans_eq with (e-prec)%Z;[idtac|ring].
-simpl; apply Z.max_l.
-assert (emin+prec <= e)%Z; try omega.
-apply le_bpow with beta.
-apply Rle_trans with (1:=Hx).
-left; now apply He.
+replace (e - 1 + (1 - prec))%Z with (e - prec)%Z by ring.
+apply Z.max_l.
+assert (emin+prec-1 < e)%Z; try omega.
+apply lt_bpow with beta.
+apply Rle_lt_trans with (1:=Hx).
+now apply He.
apply Rmult_le_compat_r.
apply bpow_ge_0.
now apply He.
Qed.
-
-Theorem ulp_FLT_ge: forall x, (Rabs x * bpow (-prec) < ulp beta FLT_exp x)%R.
+Theorem ulp_FLT_gt :
+ forall x, (Rabs x * bpow (-prec) < ulp beta FLT_exp x)%R.
Proof.
intros x; case (Req_dec x 0); intros Hx.
rewrite Hx, ulp_FLT_small, Rabs_R0, Rmult_0_l; try apply bpow_gt_0.
diff --git a/flocq/Core/Fcore_Raux.v b/flocq/Core/Fcore_Raux.v
index 44db6c35..77235e63 100644
--- a/flocq/Core/Fcore_Raux.v
+++ b/flocq/Core/Fcore_Raux.v
@@ -1842,10 +1842,13 @@ Qed.
Lemma ln_beta_lt_pos :
forall x y,
- (0 < x)%R -> (0 < y)%R ->
+ (0 < y)%R ->
(ln_beta x < ln_beta y)%Z -> (x < y)%R.
Proof.
-intros x y Px Py.
+intros x y Py.
+case (Rle_or_lt x 0); intros Px.
+intros H.
+now apply Rle_lt_trans with 0%R.
destruct (ln_beta x) as (ex, Hex).
destruct (ln_beta y) as (ey, Hey).
simpl.
@@ -2099,7 +2102,7 @@ assert (Hbeta : (2 <= r)%Z).
{ destruct r as (beta_val,beta_prop).
now apply Zle_bool_imp_le. }
intros x y Px Py Hln.
-assert (Oxy : (y < x)%R); [now apply ln_beta_lt_pos; [| |omega]|].
+assert (Oxy : (y < x)%R); [apply ln_beta_lt_pos;[assumption|omega]|].
destruct (ln_beta x) as (ex,Hex).
destruct (ln_beta y) as (ey,Hey).
simpl in Hln |- *.
diff --git a/flocq/Core/Fcore_ulp.v b/flocq/Core/Fcore_ulp.v
index 3bc0eac3..4fdd319e 100644
--- a/flocq/Core/Fcore_ulp.v
+++ b/flocq/Core/Fcore_ulp.v
@@ -43,7 +43,6 @@ now left.
now right.
Qed.
-
(** [negligible_exp] is either none (as in FLX) or Some n such that n <= fexp n. *)
Definition negligible_exp: option Z :=
match (LPO_Z _ (fun z => Z_le_dec_aux z (fexp z))) with
@@ -272,6 +271,7 @@ Qed.
Lemma not_FTZ_generic_format_ulp:
(forall x, F (ulp x)) -> Exp_not_FTZ fexp.
+Proof.
intros H e.
specialize (H (bpow (e-1))).
rewrite ulp_neq_0 in H.
@@ -1483,23 +1483,27 @@ now apply generic_format_opp.
now apply Ropp_lt_contravar.
Qed.
-
-Theorem lt_succ_le:
+Theorem lt_succ_le :
forall x y,
- F x -> F y -> (y <> 0)%R ->
+ (y <> 0)%R ->
(x <= y)%R ->
(x < succ y)%R.
Proof.
-intros x y Fx Fy Zy Hxy.
-case (Rle_or_lt (succ y) x); trivial; intros H.
-absurd (succ y = y)%R.
-apply Rgt_not_eq.
+intros x y Zy Hxy.
+apply Rle_lt_trans with (1 := Hxy).
now apply succ_gt_id.
-apply Rle_antisym.
-now apply Rle_trans with x.
-apply succ_ge_id.
Qed.
+Theorem pred_lt_le :
+ forall x y,
+ (x <> 0)%R ->
+ (x <= y)%R ->
+ (pred x < y)%R.
+Proof.
+intros x y Zy Hxy.
+apply Rlt_le_trans with (2 := Hxy).
+now apply pred_lt_id.
+Qed.
Theorem succ_pred_aux : forall x, F x -> (0 < x)%R -> succ (pred x)=x.
Proof.
@@ -1510,17 +1514,15 @@ rewrite succ_eq_pos.
now apply pred_pos_plus_ulp.
Qed.
-Theorem pred_succ_aux_0 : (pred (succ 0)=0)%R.
+Theorem pred_ulp_0 :
+ pred (ulp 0) = 0%R.
Proof.
-unfold succ; rewrite Rle_bool_true.
-2: apply Rle_refl.
-rewrite Rplus_0_l.
rewrite pred_eq_pos.
2: apply ulp_ge_0.
unfold ulp; rewrite Req_bool_true; trivial.
case negligible_exp_spec'.
(* *)
-intros (H1,H2); rewrite H1.
+intros [H1 _]; rewrite H1.
unfold pred_pos; rewrite Req_bool_false.
2: apply Rlt_not_eq, bpow_gt_0.
unfold ulp; rewrite Req_bool_true; trivial.
@@ -1535,111 +1537,73 @@ apply Rminus_diag_eq, f_equal.
apply sym_eq, valid_exp; omega.
Qed.
-Theorem pred_succ_aux : forall x, F x -> (0 < x)%R -> pred (succ x)=x.
+Theorem succ_0 :
+ succ 0 = ulp 0.
Proof.
-intros x Fx Hx.
-rewrite succ_eq_pos;[idtac|now left].
-rewrite pred_eq_pos.
-2: apply Rplus_le_le_0_compat;[now left| apply ulp_ge_0].
-unfold pred_pos.
-case Req_bool_spec; intros H1.
-(* *)
-pose (l:=(ln_beta beta (x+ulp x))).
-rewrite H1 at 1; fold l.
-apply Rplus_eq_reg_r with (ulp x).
-rewrite H1; fold l.
-rewrite (ulp_neq_0 x) at 3.
-2: now apply Rgt_not_eq.
-unfold canonic_exp.
-replace (fexp (ln_beta beta x)) with (fexp (l-1))%Z.
-ring.
-apply f_equal, sym_eq.
-apply Zle_antisym.
-assert (ln_beta beta x - 1 < l - 1)%Z;[idtac|omega].
-apply lt_bpow with beta.
-unfold l; rewrite <- H1.
-apply Rle_lt_trans with x.
-destruct (ln_beta beta x) as (e,He); simpl.
-rewrite <- (Rabs_right x) at 1.
-2: apply Rle_ge; now left.
-now apply He, Rgt_not_eq.
-apply Rplus_lt_reg_l with (-x)%R; ring_simplify.
-rewrite ulp_neq_0.
-apply bpow_gt_0.
-now apply Rgt_not_eq.
-apply le_bpow with beta.
-unfold l; rewrite <- H1.
-apply id_p_ulp_le_bpow; trivial.
-rewrite <- (Rabs_right x) at 1.
-2: apply Rle_ge; now left.
-apply bpow_ln_beta_gt.
-(* *)
-replace (ulp (x+ ulp x)) with (ulp x).
-ring.
-rewrite ulp_neq_0 at 1.
-2: now apply Rgt_not_eq.
-rewrite ulp_neq_0 at 1.
-2: apply Rgt_not_eq, Rlt_gt.
-2: apply Rlt_le_trans with (1:=Hx).
-2: apply Rplus_le_reg_l with (-x)%R; ring_simplify.
-2: apply ulp_ge_0.
-apply f_equal; unfold canonic_exp; apply f_equal.
-apply sym_eq, ln_beta_unique.
-rewrite Rabs_right.
-2: apply Rle_ge; left.
-2: apply Rlt_le_trans with (1:=Hx).
-2: apply Rplus_le_reg_l with (-x)%R; ring_simplify.
-2: apply ulp_ge_0.
-destruct (ln_beta beta x) as (e,He); simpl.
-rewrite Rabs_right in He.
-2: apply Rle_ge; now left.
-split.
-apply Rle_trans with x.
-apply He, Rgt_not_eq; assumption.
-apply Rplus_le_reg_l with (-x)%R; ring_simplify.
-apply ulp_ge_0.
-case (Rle_lt_or_eq_dec (x+ulp x) (bpow e)); trivial.
-apply id_p_ulp_le_bpow; trivial.
-apply He, Rgt_not_eq; assumption.
-intros K; contradict H1.
-rewrite K, ln_beta_bpow.
-apply f_equal; ring.
+unfold succ.
+rewrite Rle_bool_true.
+apply Rplus_0_l.
+apply Rle_refl.
Qed.
+Theorem pred_0 :
+ pred 0 = Ropp (ulp 0).
+Proof.
+rewrite <- succ_0.
+rewrite <- Ropp_0 at 1.
+apply pred_opp.
+Qed.
-
-Theorem succ_pred : forall x, F x -> succ (pred x)=x.
+Theorem pred_succ_aux :
+ forall x, F x -> (0 < x)%R ->
+ pred (succ x) = x.
+Proof.
+intros x Fx Hx.
+apply Rle_antisym.
+- apply Rnot_lt_le.
+ intros H.
+ apply succ_le_lt with (1 := Fx) in H.
+ revert H.
+ apply Rlt_not_le.
+ apply pred_lt_id.
+ apply Rgt_not_eq.
+ apply Rlt_le_trans with (1 := Hx).
+ apply succ_ge_id.
+ now apply generic_format_pred, generic_format_succ.
+- apply le_pred_lt with (1 := Fx).
+ now apply generic_format_succ.
+ apply succ_gt_id.
+ now apply Rgt_not_eq.
+Qed.
+
+Theorem succ_pred :
+ forall x, F x ->
+ succ (pred x) = x.
Proof.
intros x Fx.
-case (Rle_or_lt 0 x); intros Hx.
-destruct Hx as [Hx|Hx].
+destruct (Rle_or_lt 0 x) as [[Hx|Hx]|Hx].
now apply succ_pred_aux.
rewrite <- Hx.
-rewrite pred_eq_opp_succ_opp, succ_opp, Ropp_0.
-rewrite pred_succ_aux_0; ring.
+rewrite pred_0, succ_opp, pred_ulp_0.
+apply Ropp_0.
rewrite pred_eq_opp_succ_opp, succ_opp.
rewrite pred_succ_aux.
-ring.
+apply Ropp_involutive.
now apply generic_format_opp.
now apply Ropp_0_gt_lt_contravar.
Qed.
-Theorem pred_succ : forall x, F x -> pred (succ x)=x.
+Theorem pred_succ :
+ forall x, F x ->
+ pred (succ x) = x.
Proof.
intros x Fx.
-case (Rle_or_lt 0 x); intros Hx.
-destruct Hx as [Hx|Hx].
-now apply pred_succ_aux.
-rewrite <- Hx.
-apply pred_succ_aux_0.
-rewrite succ_eq_opp_pred_opp, pred_opp.
-rewrite succ_pred_aux.
-ring.
+rewrite <- (Ropp_involutive x).
+rewrite succ_opp, pred_opp.
+apply f_equal, succ_pred.
now apply generic_format_opp.
-now apply Ropp_0_gt_lt_contravar.
Qed.
-
Theorem round_UP_pred_plus_eps :
forall x, F x ->
forall eps, (0 < eps <= if (Rle_bool x 0) then (ulp x)
@@ -2041,26 +2005,16 @@ apply error_le_half_ulp.
rewrite round_DN_opp; apply Ropp_0_gt_lt_contravar; apply Rlt_gt; assumption.
Qed.
-
-Theorem pred_le: forall x y,
- F x -> F y -> (x <= y)%R -> (pred x <= pred y)%R.
+Theorem pred_le :
+ forall x y, F x -> F y -> (x <= y)%R ->
+ (pred x <= pred y)%R.
Proof.
-intros x y Fx Fy Hxy.
-assert (V:( ((x = 0) /\ (y = 0)) \/ (x <>0 \/ x < y))%R).
-case (Req_dec x 0); intros Zx.
-case Hxy; intros Zy.
-now right; right.
-left; split; trivial; now rewrite <- Zy.
-now right; left.
-destruct V as [(V1,V2)|V].
-rewrite V1,V2; now right.
-apply le_pred_lt; try assumption.
-apply generic_format_pred; try assumption.
-case V; intros V1.
-apply Rlt_le_trans with (2:=Hxy).
-now apply pred_lt_id.
-apply Rle_lt_trans with (2:=V1).
-now apply pred_le_id.
+intros x y Fx Fy [Hxy| ->].
+2: apply Rle_refl.
+apply le_pred_lt with (2 := Fy).
+now apply generic_format_pred.
+apply Rle_lt_trans with (2 := Hxy).
+apply pred_le_id.
Qed.
Theorem succ_le: forall x y,
@@ -2088,6 +2042,28 @@ rewrite <- (pred_succ x), <- (pred_succ y); try assumption.
apply pred_le; trivial; now apply generic_format_succ.
Qed.
+Theorem pred_lt :
+ forall x y, F x -> F y -> (x < y)%R ->
+ (pred x < pred y)%R.
+Proof.
+intros x y Fx Fy Hxy.
+apply Rnot_le_lt.
+intros H.
+apply Rgt_not_le with (1 := Hxy).
+now apply pred_le_inv.
+Qed.
+
+Theorem succ_lt :
+ forall x y, F x -> F y -> (x < y)%R ->
+ (succ x < succ y)%R.
+Proof.
+intros x y Fx Fy Hxy.
+apply Rnot_le_lt.
+intros H.
+apply Rgt_not_le with (1 := Hxy).
+now apply succ_le_inv.
+Qed.
+
(* was lt_UP_le_DN *)
Theorem le_round_DN_lt_UP :
forall x y, F y ->
diff --git a/flocq/Flocq_version.v b/flocq/Flocq_version.v
index b01a08f9..72d4fe20 100644
--- a/flocq/Flocq_version.v
+++ b/flocq/Flocq_version.v
@@ -29,4 +29,4 @@ Definition Flocq_version := Eval vm_compute in
parse t major (minor * 10 + N_of_ascii h - N_of_ascii "0"%char)%N
| Empty_string => (major * 100 + minor)%N
end in
- parse "2.5.2"%string N0 N0.
+ parse "2.6.1"%string N0 N0.
diff --git a/flocq/Prop/Fprop_mult_error.v b/flocq/Prop/Fprop_mult_error.v
index 7c71627b..44448cd6 100644
--- a/flocq/Prop/Fprop_mult_error.v
+++ b/flocq/Prop/Fprop_mult_error.v
@@ -158,7 +158,6 @@ Notation bpow e := (bpow beta e).
Variable emin prec : Z.
Context { prec_gt_0_ : Prec_gt_0 prec }.
-Variable Hpemin: (emin <= prec)%Z.
Notation format := (generic_format beta (FLT_exp emin prec)).
Notation cexp := (canonic_exp beta (FLT_exp emin prec)).
@@ -173,7 +172,6 @@ Theorem mult_error_FLT :
(x*y = 0)%R \/ (bpow (emin + 2*prec - 1) <= Rabs (x * y))%R ->
format (round beta (FLT_exp emin prec) rnd (x * y) - (x * y))%R.
Proof with auto with typeclass_instances.
-clear Hpemin.
intros x y Hx Hy Hxy.
set (f := (round beta (FLT_exp emin prec) rnd (x * y))).
destruct (Req_dec (f - x * y) 0) as [Hr0|Hr0].
diff --git a/flocq/Prop/Fprop_plus_error.v b/flocq/Prop/Fprop_plus_error.v
index 41c2f031..9bb5aee8 100644
--- a/flocq/Prop/Fprop_plus_error.v
+++ b/flocq/Prop/Fprop_plus_error.v
@@ -19,6 +19,7 @@ COPYING file for more details.
(** * Error of the rounded-to-nearest addition is representable. *)
+Require Import Psatz.
Require Import Fcore_Raux.
Require Import Fcore_defs.
Require Import Fcore_float_prop.
@@ -26,6 +27,7 @@ Require Import Fcore_generic_fmt.
Require Import Fcore_FIX.
Require Import Fcore_FLX.
Require Import Fcore_FLT.
+Require Import Fcore_ulp.
Require Import Fcalc_ops.
@@ -267,3 +269,270 @@ rewrite Z2R_plus; ring.
Qed.
End Fprop_plus_FLT.
+
+Section Fprop_plus_mult_ulp.
+
+Variable beta : radix.
+Notation bpow e := (bpow beta e).
+
+Variable fexp : Z -> Z.
+Context { valid_exp : Valid_exp fexp }.
+Context { monotone_exp : Monotone_exp fexp }.
+Variable rnd : R -> Z.
+Context { valid_rnd : Valid_rnd rnd }.
+
+Notation format := (generic_format beta fexp).
+Notation cexp := (canonic_exp beta fexp).
+
+Lemma ex_shift :
+ forall x e, format x -> (e <= cexp x)%Z ->
+ exists m, (x = Z2R m * bpow e)%R.
+Proof with auto with typeclass_instances.
+intros x e Fx He.
+exists (Ztrunc (scaled_mantissa beta fexp x)*Zpower beta (cexp x -e))%Z.
+rewrite Fx at 1; unfold F2R; simpl.
+rewrite Z2R_mult, Rmult_assoc.
+f_equal.
+rewrite Z2R_Zpower.
+2: omega.
+rewrite <- bpow_plus; f_equal; ring.
+Qed.
+
+Lemma ln_beta_minus1 :
+ forall z, z <> 0%R ->
+ (ln_beta beta z - 1)%Z = ln_beta beta (z / Z2R beta).
+Proof.
+intros z Hz.
+unfold Zminus.
+rewrite <- ln_beta_mult_bpow with (1 := Hz).
+now rewrite bpow_opp, bpow_1.
+Qed.
+
+Theorem round_plus_mult_ulp :
+ forall x y, format x -> format y -> (x <> 0)%R ->
+ exists m, (round beta fexp rnd (x+y) = Z2R m * ulp beta fexp (x/Z2R beta))%R.
+Proof with auto with typeclass_instances.
+intros x y Fx Fy Zx.
+case (Zle_or_lt (ln_beta beta (x/Z2R beta)) (ln_beta beta y)); intros H1.
+pose (e:=cexp (x / Z2R beta)).
+destruct (ex_shift x e) as (nx, Hnx); try exact Fx.
+apply monotone_exp.
+rewrite <- (ln_beta_minus1 x Zx); omega.
+destruct (ex_shift y e) as (ny, Hny); try assumption.
+apply monotone_exp...
+destruct (round_repr_same_exp beta fexp rnd (nx+ny) e) as (n,Hn).
+exists n.
+apply trans_eq with (F2R (Float beta n e)).
+rewrite <- Hn; f_equal.
+rewrite Hnx, Hny; unfold F2R; simpl; rewrite Z2R_plus; ring.
+unfold F2R; simpl.
+rewrite ulp_neq_0; try easy.
+apply Rmult_integral_contrapositive_currified; try assumption.
+apply Rinv_neq_0_compat.
+apply Rgt_not_eq.
+apply radix_pos.
+(* *)
+destruct (ex_shift (round beta fexp rnd (x + y)) (cexp (x/Z2R beta))) as (n,Hn).
+apply generic_format_round...
+apply Zle_trans with (cexp (x+y)).
+apply monotone_exp.
+rewrite <- ln_beta_minus1 by easy.
+rewrite <- (ln_beta_abs beta (x+y)).
+(* . *)
+assert (U: (Rabs (x+y) = Rabs x + Rabs y)%R \/ (y <> 0 /\ Rabs (x+y) = Rabs x - Rabs y)%R).
+assert (V: forall x y, (Rabs y <= Rabs x)%R ->
+ (Rabs (x+y) = Rabs x + Rabs y)%R \/ (y <> 0 /\ Rabs (x+y) = Rabs x - Rabs y)%R).
+clear; intros x y.
+case (Rle_or_lt 0 y); intros Hy.
+case Hy; intros Hy'.
+case (Rle_or_lt 0 x); intros Hx.
+intros _; rewrite (Rabs_pos_eq y) by easy.
+rewrite (Rabs_pos_eq x) by easy.
+left; apply Rabs_pos_eq.
+now apply Rplus_le_le_0_compat.
+rewrite (Rabs_pos_eq y) by easy.
+rewrite (Rabs_left x) by easy.
+intros H; right; split.
+now apply Rgt_not_eq.
+rewrite Rabs_left1.
+ring.
+apply Rplus_le_reg_l with (-x)%R; ring_simplify; assumption.
+intros _; left.
+now rewrite <- Hy', Rabs_R0, 2!Rplus_0_r.
+case (Rle_or_lt 0 x); intros Hx.
+rewrite (Rabs_left y) by easy.
+rewrite (Rabs_pos_eq x) by easy.
+intros H; right; split.
+now apply Rlt_not_eq.
+rewrite Rabs_pos_eq.
+ring.
+apply Rplus_le_reg_l with (-y)%R; ring_simplify; assumption.
+intros _; left.
+rewrite (Rabs_left y) by easy.
+rewrite (Rabs_left x) by easy.
+rewrite Rabs_left1.
+ring.
+lra.
+apply V; left.
+apply ln_beta_lt_pos with beta.
+now apply Rabs_pos_lt.
+rewrite <- ln_beta_minus1 in H1; try assumption.
+rewrite 2!ln_beta_abs; omega.
+(* . *)
+destruct U as [U|U].
+rewrite U; apply Zle_trans with (ln_beta beta x).
+omega.
+rewrite <- ln_beta_abs.
+apply ln_beta_le.
+now apply Rabs_pos_lt.
+apply Rplus_le_reg_l with (-Rabs x)%R; ring_simplify.
+apply Rabs_pos.
+destruct U as (U',U); rewrite U.
+rewrite <- ln_beta_abs.
+apply ln_beta_minus_lb.
+now apply Rabs_pos_lt.
+now apply Rabs_pos_lt.
+rewrite 2!ln_beta_abs.
+assert (ln_beta beta y < ln_beta beta x - 1)%Z.
+now rewrite (ln_beta_minus1 x Zx).
+omega.
+apply canonic_exp_round_ge...
+intros K.
+apply round_plus_eq_zero in K...
+contradict H1; apply Zle_not_lt.
+rewrite <- (ln_beta_minus1 x Zx).
+replace y with (-x)%R.
+rewrite ln_beta_opp; omega.
+lra.
+exists n.
+rewrite ulp_neq_0.
+assumption.
+apply Rmult_integral_contrapositive_currified; try assumption.
+apply Rinv_neq_0_compat.
+apply Rgt_not_eq.
+apply radix_pos.
+Qed.
+
+Context {exp_not_FTZ : Exp_not_FTZ fexp}.
+
+Theorem round_plus_ge_ulp :
+ forall x y, format x -> format y ->
+ round beta fexp rnd (x+y) = 0%R \/
+ (ulp beta fexp (x/Z2R beta) <= Rabs (round beta fexp rnd (x+y)))%R.
+Proof with auto with typeclass_instances.
+intros x y Fx Fy.
+case (Req_dec x 0); intros Zx.
+(* *)
+rewrite Zx, Rplus_0_l.
+rewrite round_generic...
+unfold Rdiv; rewrite Rmult_0_l.
+rewrite Fy at 2.
+unfold F2R; simpl; rewrite Rabs_mult.
+rewrite (Rabs_pos_eq (bpow _)) by apply bpow_ge_0.
+case (Z.eq_dec (Ztrunc (scaled_mantissa beta fexp y)) 0); intros Hm.
+left.
+rewrite Fy, Hm; unfold F2R; simpl; ring.
+right.
+apply Rle_trans with (1*bpow (cexp y))%R.
+rewrite Rmult_1_l.
+rewrite <- ulp_neq_0.
+apply ulp_ge_ulp_0...
+intros K; apply Hm.
+rewrite K, scaled_mantissa_0.
+apply (Ztrunc_Z2R 0).
+apply Rmult_le_compat_r.
+apply bpow_ge_0.
+rewrite <- Z2R_abs.
+apply (Z2R_le 1).
+apply (Zlt_le_succ 0).
+now apply Z.abs_pos.
+(* *)
+destruct (round_plus_mult_ulp x y Fx Fy Zx) as (m,Hm).
+case (Z.eq_dec m 0); intros Zm.
+left.
+rewrite Hm, Zm; simpl; ring.
+right.
+rewrite Hm, Rabs_mult.
+rewrite (Rabs_pos_eq (ulp _ _ _)) by apply ulp_ge_0.
+apply Rle_trans with (1*ulp beta fexp (x/Z2R beta))%R.
+right; ring.
+apply Rmult_le_compat_r.
+apply ulp_ge_0.
+rewrite <- Z2R_abs.
+apply (Z2R_le 1).
+apply (Zlt_le_succ 0).
+now apply Z.abs_pos.
+Qed.
+
+End Fprop_plus_mult_ulp.
+
+Section Fprop_plus_ge_ulp.
+
+Variable beta : radix.
+Notation bpow e := (bpow beta e).
+
+Variable rnd : R -> Z.
+Context { valid_rnd : Valid_rnd rnd }.
+Variable emin prec : Z.
+Context { prec_gt_0_ : Prec_gt_0 prec }.
+
+Theorem round_plus_ge_ulp_FLT : forall x y e,
+ generic_format beta (FLT_exp emin prec) x -> generic_format beta (FLT_exp emin prec) y ->
+ (bpow e <= Rabs x)%R ->
+ round beta (FLT_exp emin prec) rnd (x+y) = 0%R \/
+ (bpow (e - prec) <= Rabs (round beta (FLT_exp emin prec) rnd (x+y)))%R.
+Proof with auto with typeclass_instances.
+intros x y e Fx Fy He.
+assert (Zx: x <> 0%R).
+ contradict He.
+ apply Rlt_not_le; rewrite He, Rabs_R0.
+ apply bpow_gt_0.
+case round_plus_ge_ulp with beta (FLT_exp emin prec) rnd x y...
+intros H; right.
+apply Rle_trans with (2:=H).
+rewrite ulp_neq_0.
+unfold canonic_exp.
+rewrite <- ln_beta_minus1 by easy.
+unfold FLT_exp; apply bpow_le.
+apply Zle_trans with (2:=Z.le_max_l _ _).
+destruct (ln_beta beta x) as (n,Hn); simpl.
+assert (e < n)%Z; try omega.
+apply lt_bpow with beta.
+apply Rle_lt_trans with (1:=He).
+now apply Hn.
+apply Rmult_integral_contrapositive_currified; try assumption.
+apply Rinv_neq_0_compat.
+apply Rgt_not_eq.
+apply radix_pos.
+Qed.
+
+Theorem round_plus_ge_ulp_FLX : forall x y e,
+ generic_format beta (FLX_exp prec) x -> generic_format beta (FLX_exp prec) y ->
+ (bpow e <= Rabs x)%R ->
+ round beta (FLX_exp prec) rnd (x+y) = 0%R \/
+ (bpow (e - prec) <= Rabs (round beta (FLX_exp prec) rnd (x+y)))%R.
+Proof with auto with typeclass_instances.
+intros x y e Fx Fy He.
+assert (Zx: x <> 0%R).
+ contradict He.
+ apply Rlt_not_le; rewrite He, Rabs_R0.
+ apply bpow_gt_0.
+case round_plus_ge_ulp with beta (FLX_exp prec) rnd x y...
+intros H; right.
+apply Rle_trans with (2:=H).
+rewrite ulp_neq_0.
+unfold canonic_exp.
+rewrite <- ln_beta_minus1 by easy.
+unfold FLX_exp; apply bpow_le.
+destruct (ln_beta beta x) as (n,Hn); simpl.
+assert (e < n)%Z; try omega.
+apply lt_bpow with beta.
+apply Rle_lt_trans with (1:=He).
+now apply Hn.
+apply Rmult_integral_contrapositive_currified; try assumption.
+apply Rinv_neq_0_compat.
+apply Rgt_not_eq.
+apply radix_pos.
+Qed.
+
+End Fprop_plus_ge_ulp.
diff --git a/lib/Camlcoq.ml b/lib/Camlcoq.ml
index 5c25796e..d94e3582 100644
--- a/lib/Camlcoq.ml
+++ b/lib/Camlcoq.ml
@@ -20,7 +20,7 @@ open BinNums
open BinNat
open BinInt
open BinPos
-open Floats
+open! Floats
(* Coq's [nat] type and some of its operations *)
diff --git a/lib/Coqlib.v b/lib/Coqlib.v
index 3fe1ea2e..3b8e5b3b 100644
--- a/lib/Coqlib.v
+++ b/lib/Coqlib.v
@@ -17,6 +17,7 @@
used throughout the development. It complements the Coq standard
library. *)
+Require Export String.
Require Export ZArith.
Require Export Znumtheory.
Require Export List.
diff --git a/lib/Readconfig.mll b/lib/Readconfig.mll
index e71c8fb7..7b98255e 100644
--- a/lib/Readconfig.mll
+++ b/lib/Readconfig.mll
@@ -43,9 +43,9 @@ let error msg lexbuf =
lexbuf.lex_curr_p.pos_lnum,
msg)))
-let ill_formed_line lexbuf = error "Ill-formed line" lexbuf
-let unterminated_quote lexbuf = error "Unterminated quote" lexbuf
-let lone_backslash lexbuf = error "Lone \\ (backslash) at end of file" lexbuf
+let ill_formed_line lexbuf = error "ill-formed line" lexbuf
+let unterminated_quote lexbuf = error "unterminated quote" lexbuf
+let lone_backslash lexbuf = error "lone \\ (backslash) at end of file" lexbuf
}
diff --git a/powerpc/Asm.v b/powerpc/Asm.v
index 746a610b..aa15547b 100644
--- a/powerpc/Asm.v
+++ b/powerpc/Asm.v
@@ -239,6 +239,7 @@ Inductive instruction : Type :=
| Pld: ireg -> constant -> ireg -> instruction (**r load 64-bit int (PPC64) *)
| Pldx: ireg -> ireg -> ireg -> instruction (**r same, with 2 index regs *)
| Pld_a: ireg -> constant -> ireg -> instruction (**r load 64-bit quantity to int reg (PPC64) *)
+ | Pldbrx: ireg -> ireg -> ireg -> instruction (**r load 64-bit int and reverse endianness (PPC64) *)
| Pldx_a: ireg -> ireg -> ireg -> instruction (**r same, with 2 index regs *)
| Plfd: freg -> constant -> ireg -> instruction (**r load 64-bit float *)
| Plfdx: freg -> ireg -> ireg -> instruction (**r same, with 2 index regs *)
@@ -307,6 +308,7 @@ Inductive instruction : Type :=
| Pstbx: ireg -> ireg -> ireg -> instruction (**r same, with 2 index regs *)
| Pstd: ireg -> constant -> ireg -> instruction (**r store 64-bit integer (PPC64) *)
| Pstdx: ireg -> ireg -> ireg -> instruction (**r same, with 2 index regs (PPC64) *)
+ | Pstdbrx: ireg -> ireg -> ireg -> instruction (**r store 64-bit int with reverse endianness (PPC64) *)
| Pstdu: ireg -> constant -> ireg -> instruction (**r store 64-bit integer with update (PPC64) *)
| Pstd_a: ireg -> constant -> ireg -> instruction (**r store 64-bit quantity from int reg (PPC64) *)
| Pstdx_a: ireg -> ireg -> ireg -> instruction (**r same, with 2 index regs (PPC64) *)
@@ -1077,6 +1079,7 @@ Definition exec_instr (f: function) (i: instruction) (rs: regset) (m: mem) : out
| Picbi _ _
| Picbtls _ _ _
| Pisync
+ | Pldbrx _ _ _
| Plwsync
| Plhbrx _ _ _
| Plwzu _ _ _
@@ -1086,6 +1089,7 @@ Definition exec_instr (f: function) (i: instruction) (rs: regset) (m: mem) : out
| Pmtspr _ _
| Prldicl _ _ _ _
| Prldimi _ _ _ _
+ | Pstdbrx _ _ _
| Pstdu _ _ _
| Pstwbrx _ _ _
| Pstwcx_ _ _ _
@@ -1126,6 +1130,15 @@ Definition preg_of (r: mreg) : preg :=
| F28 => FPR28 | F29 => FPR29 | F30 => FPR30 | F31 => FPR31
end.
+(** Undefine all registers except SP and callee-save registers *)
+
+Definition undef_caller_save_regs (rs: regset) : regset :=
+ fun r =>
+ if preg_eq r SP
+ || In_dec preg_eq r (List.map preg_of (List.filter is_callee_save all_mregs))
+ then rs r
+ else Vundef.
+
(** Extract the values of the arguments of an external call.
We exploit the calling conventions from module [Conventions], except that
we use PPC registers instead of locations. *)
@@ -1185,7 +1198,7 @@ Inductive step: state -> trace -> state -> Prop :=
Genv.find_funct_ptr ge b = Some (External ef) ->
external_call ef ge args m t res m' ->
extcall_arguments rs m (ef_sig ef) args ->
- rs' = (set_pair (loc_external_result (ef_sig ef)) res rs) #PC <- (rs RA) ->
+ rs' = (set_pair (loc_external_result (ef_sig ef)) res (undef_caller_save_regs rs)) #PC <- (rs RA) ->
step (State rs m) t (State rs' m').
End RELSEM.
diff --git a/powerpc/AsmToJSON.ml b/powerpc/AsmToJSON.ml
index 720d09a6..ee3eaca8 100644
--- a/powerpc/AsmToJSON.ml
+++ b/powerpc/AsmToJSON.ml
@@ -97,14 +97,14 @@ let mnemonic_names =["Padd"; "Paddc"; "Padde"; "Paddi"; "Paddic"; "Paddis"; "Pa
"Pfmadd"; "Pfmr"; "Pfmsub"; "Pfmul"; "Pfmuls"; "Pfneg"; "Pfnmadd";
"Pfnmsub"; "Pfres"; "Pfrsp"; "Pfrsqrte"; "Pfsel"; "Pfsqrt"; "Pfsub";
"Pfsubs"; "Picbi"; "Picbtls"; "Pinlineasm"; "Pisel"; "Pisync"; "Plabel";
- "Plbz"; "Plbzx"; "Pld"; "Pldi"; "Pldx"; "Plfd"; "Plfdx"; "Plfi"; "Plfis";
+ "Plbz"; "Plbzx"; "Pld"; "Pldbrx"; "Pldi"; "Pldx"; "Plfd"; "Plfdx"; "Plfi"; "Plfis";
"Plfs"; "Plfsx"; "Plha"; "Plhax"; "Plhbrx"; "Plhz"; "Plhzx"; "Plwarx";
"Plwbrx"; "Plwsync"; "Plwz"; "Plwzu"; "Plwzx"; "Pmbar"; "Pmfcr"; "Pmflr";
"Pmfspr"; "Pmr"; "Pmtctr"; "Pmtlr"; "Pmtspr"; "Pmulhd"; "Pmulhdu"; "Pmulhw";
"Pmulhwu"; "Pmulld"; "Pmulli"; "Pmullw"; "Pnand"; "Pnor"; "Por"; "Porc";
"Pori"; "Poris"; "Prldicl"; "Prldimi"; "Prldinm"; "Prlwimi"; "Prlwinm";
"Psld"; "Pslw"; "Psrad"; "Psradi"; "Psraw"; "Psrawi"; "Psrd"; "Psrw";
- "Pstb"; "Pstbx"; "Pstd"; "Pstdu"; "Pstdx"; "Pstfd"; "Pstfdu"; "Pstfdx";
+ "Pstb"; "Pstbx"; "Pstd"; "Pstdbrx"; "Pstdu"; "Pstdx"; "Pstfd"; "Pstfdu"; "Pstfdx";
"Pstfs"; "Pstfsx"; "Psth"; "Psthbrx"; "Psthx"; "Pstw"; "Pstwbrx"; "Pstwcx_";
"Pstwu"; "Pstwux"; "Pstwx"; "Psubfc"; "Psubfe"; "Psubfic"; "Psubfze";
"Psync"; "Ptrap"; "Pxor"; "Pxori"; "Pxoris"]
@@ -236,6 +236,7 @@ let pp_instructions pp ic =
| Plbzx (ir1,ir2,ir3) -> instruction pp "Plbzx" [Ireg ir1; Ireg ir2; Ireg ir3]
| Pld (ir1,c,ir2)
| Pld_a (ir1,c,ir2) -> instruction pp "Pld" [Ireg ir1; Constant c; Ireg ir2]
+ | Pldbrx (ir1,ir2,ir3) -> instruction pp "Pldbrx" [Ireg ir1; Ireg ir2; Ireg ir3]
| Pldx (ir1,ir2,ir3)
| Pldx_a (ir1,ir2,ir3) -> instruction pp "Pldx" [Ireg ir1; Ireg ir2; Ireg ir3]
| Plfd (fr,c,ir)
@@ -305,6 +306,7 @@ let pp_instructions pp ic =
| Pstbx (ir1,ir2,ir3) -> instruction pp "Pstbx" [Ireg ir1; Ireg ir2; Ireg ir3]
| Pstd (ir1,c,ir2)
| Pstd_a (ir1,c,ir2) -> instruction pp "Pstd" [Ireg ir1; Constant c; Ireg ir2]
+ | Pstdbrx (ir1,ir2,ir3) -> instruction pp "Pstdbrx" [Ireg ir1; Ireg ir2; Ireg ir3]
| Pstdx (ir1,ir2,ir3)
| Pstdx_a (ir1,ir2,ir3) -> instruction pp "Pstdx" [Ireg ir1; Ireg ir2; Ireg ir3]
| Pstdu (ir1,c,ir2) -> instruction pp "Pstdu" [Ireg ir1; Constant c; Ireg ir2]
diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml
index 96b11056..5a2df8d3 100644
--- a/powerpc/Asmexpand.ml
+++ b/powerpc/Asmexpand.ml
@@ -433,6 +433,16 @@ let expand_builtin_inline name args res =
emit (Pmulhw(res, a1, a2))
| "__builtin_mulhwu", [BA(IR a1); BA(IR a2)], BR(IR res) ->
emit (Pmulhwu(res, a1, a2))
+ | "__builtin_mulhd", [BA(IR a1); BA(IR a2)], BR(IR res) ->
+ if Archi.ppc64 then
+ emit (Pmulhd(res, a1, a2))
+ else
+ raise (Error "__builtin_mulhd is only supported for PPC64 targets")
+ | "__builtin_mulhdu", [BA(IR a1); BA(IR a2)], BR(IR res) ->
+ if Archi.ppc64 then
+ emit (Pmulhdu(res, a1, a2))
+ else
+ raise (Error "__builtin_mulhdu is only supported for PPC64 targets")
| ("__builtin_clz" | "__builtin_clzl"), [BA(IR a1)], BR(IR res) ->
emit (Pcntlzw(res, a1))
| "__builtin_clzll", [BA(IR a1)], BR(IR res) ->
@@ -543,10 +553,20 @@ let expand_builtin_inline name args res =
emit (Plhbrx(res, GPR0, a1))
| "__builtin_read32_reversed", [BA(IR a1)], BR(IR res) ->
emit (Plwbrx(res, GPR0, a1))
+ | "__builtin_read64_reversed", [BA(IR a1)], BR(IR res) ->
+ if Archi.ppc64 then
+ emit (Pldbrx(res, GPR0, a1))
+ else
+ raise (Error "__builtin_read64_reversed is only supported for PPC64 targets")
| "__builtin_write16_reversed", [BA(IR a1); BA(IR a2)], _ ->
emit (Psthbrx(a2, GPR0, a1))
| "__builtin_write32_reversed", [BA(IR a1); BA(IR a2)], _ ->
emit (Pstwbrx(a2, GPR0, a1))
+ | "__builtin_write64_reversed", [BA(IR a1); BA(IR a2)], _ ->
+ if Archi.ppc64 then
+ emit (Pstdbrx(a2, GPR0, a1))
+ else
+ raise (Error "__builtin_write64_reversed is only supported for PPC64 targets")
(* Synchronization *)
| "__builtin_membar", [], _ ->
()
@@ -562,7 +582,7 @@ let expand_builtin_inline name args res =
if not (mo = _0 || mo = _1) then
raise (Error "the argument of __builtin_mbar must be 0 or 1");
emit (Pmbar mo)
- | "__builin_mbar", _, _ ->
+ | "__builtin_mbar", _, _ ->
raise (Error "the argument of __builtin_mbar must be a constant");
| "__builtin_trap", [], _ ->
emit (Ptrap)
@@ -871,7 +891,7 @@ let expand_instruction instr =
expand_builtin_memcpy (Z.to_int sz) (Z.to_int al) args
| EF_annot_val(kind,txt, targ) ->
expand_annot_val kind txt targ args res
- | EF_annot _ | EF_debug _ | EF_inline_asm _ ->
+ | EF_annot _ | EF_debug _ | EF_inline_asm _ ->
emit instr
| _ ->
assert false
@@ -912,10 +932,7 @@ let preg_to_dwarf = function
let expand_function id fn =
try
set_current_function fn;
- if !Clflags.option_g then
- expand_debug id 1 preg_to_dwarf expand_instruction fn.fn_code
- else
- List.iter expand_instruction fn.fn_code;
+ expand id 1 preg_to_dwarf expand_instruction fn.fn_code;
Errors.OK (get_current_function ())
with Error s ->
Errors.Error (Errors.msg (coqstring_of_camlstring s))
diff --git a/powerpc/Asmgenproof.v b/powerpc/Asmgenproof.v
index 9f258e3d..8ad28aea 100644
--- a/powerpc/Asmgenproof.v
+++ b/powerpc/Asmgenproof.v
@@ -918,8 +918,8 @@ Local Transparent destroyed_by_jumptable.
apply plus_one. eapply exec_step_external; eauto.
eapply external_call_symbols_preserved; eauto. apply senv_preserved.
econstructor; eauto.
- unfold loc_external_result.
- apply agree_set_other; auto. apply agree_set_pair; auto.
+ unfold loc_external_result. apply agree_set_other; auto. apply agree_set_pair; auto.
+ apply agree_undef_caller_save_regs; auto.
- (* return *)
inv STACKS. simpl in *.
diff --git a/powerpc/CBuiltins.ml b/powerpc/CBuiltins.ml
index 35d6b89f..c76b69ba 100644
--- a/powerpc/CBuiltins.ml
+++ b/powerpc/CBuiltins.ml
@@ -42,6 +42,11 @@ let builtins = {
(TInt(IInt, []), [TInt(IULongLong, [])], false);
"__builtin_cmpb",
(TInt (IUInt, []), [TInt(IUInt, []);TInt(IUInt, [])], false);
+ (* Integer arithmetic in 32/64-bit hybrid mode *)
+ "__builtin_mulhd",
+ (TInt(ILongLong, []), [TInt(ILongLong, []); TInt(ILongLong, [])], false);
+ "__builtin_mulhdu",
+ (TInt(IULongLong, []), [TInt(IULongLong, []); TInt(IULongLong, [])], false);
(* Float arithmetic *)
"__builtin_fmadd",
(TFloat(FDouble, []),
@@ -80,6 +85,11 @@ let builtins = {
(TVoid [], [TPtr(TInt(IUShort, []), []); TInt(IUShort, [])], false);
"__builtin_write32_reversed",
(TVoid [], [TPtr(TInt(IUInt, []), []); TInt(IUInt, [])], false);
+ (* Memory accesses in 32/64-bit hybrid mode *)
+ "__builtin_read64_reversed",
+ (TInt(IULongLong, []), [TPtr(TInt(IULongLong, [AConst]), [])], false);
+ "__builtin_write64_reversed",
+ (TVoid [], [TPtr(TInt(IULongLong, []), []); TInt(IULongLong, [])], false);
(* Synchronization *)
"__builtin_eieio",
(TVoid [], [], false);
@@ -113,7 +123,7 @@ let builtins = {
(TInt(IUInt, []), [TInt(IInt, [])], false);
"__builtin_set_spr",
(TVoid [], [TInt(IInt, []); TInt(IUInt, [])], false);
- (* Access to special registers in 32bit hybrid mode*)
+ (* Access to special registers in 32/64-bit hybrid mode *)
"__builtin_get_spr64",
(TInt(IULongLong, []), [TInt(IInt, [])], false);
"__builtin_set_spr64",
@@ -135,7 +145,7 @@ let builtins = {
(* no operation *)
"__builtin_nop",
(TVoid [], [], false);
- (* atomic operations *)
+ (* Atomic operations *)
"__builtin_atomic_exchange",
(TVoid [], [TPtr (TInt(IInt, []),[]);TPtr (TInt(IInt, []),[]);TPtr (TInt(IInt, []),[])],false);
"__builtin_atomic_load",
diff --git a/powerpc/TargetPrinter.ml b/powerpc/TargetPrinter.ml
index 9a6840b1..c1aaa55d 100644
--- a/powerpc/TargetPrinter.ml
+++ b/powerpc/TargetPrinter.ml
@@ -605,7 +605,7 @@ module Target (System : SYSTEM):TARGET =
| Pisel (r1,r2,r3,cr) ->
fprintf oc " isel %a, %a, %a, %a\n" ireg r1 ireg r2 ireg r3 crbit cr
| Picbi (r1,r2) ->
- fprintf oc " icbi %a,%a\n" ireg r1 ireg r2
+ fprintf oc " icbi %a, %a\n" ireg r1 ireg r2
| Picbtls (n,r1,r2) ->
fprintf oc " icbtls %ld, %a, %a\n" (camlint_of_coqint n) ireg r1 ireg r2
| Pisync ->
@@ -618,6 +618,8 @@ module Target (System : SYSTEM):TARGET =
fprintf oc " lbzx %a, %a, %a\n" ireg r1 ireg r2 ireg r3
| Pld(r1, c, r2) | Pld_a(r1, c, r2) ->
fprintf oc " ld %a, %a(%a)\n" ireg r1 constant c ireg r2
+ | Pldbrx(r1, r2, r3) ->
+ fprintf oc " ldbrx %a, %a, %a\n" ireg r1 ireg r2 ireg r3
| Pldx(r1, r2, r3) | Pldx_a(r1, r2, r3) ->
fprintf oc " ldx %a, %a, %a\n" ireg r1 ireg r2 ireg r3
| Plfd(r1, c, r2) | Plfd_a(r1, c, r2) ->
@@ -772,6 +774,8 @@ module Target (System : SYSTEM):TARGET =
fprintf oc " stbx %a, %a, %a\n" ireg r1 ireg r2 ireg r3
| Pstd(r1, c, r2) | Pstd_a(r1, c, r2) ->
fprintf oc " std %a, %a(%a)\n" ireg r1 constant c ireg r2
+ | Pstdbrx(r1, r2, r3) ->
+ fprintf oc " stdbrx %a, %a, %a\n" ireg r1 ireg r2 ireg r3
| Pstdx(r1, r2, r3) | Pstdx_a(r1, r2, r3) ->
fprintf oc " stdx %a, %a, %a\n" ireg r1 ireg r2 ireg r3
| Pstdu(r1, c, r2) ->
@@ -840,7 +844,7 @@ module Target (System : SYSTEM):TARGET =
fprintf oc "%s annotation: %S\n" comment annot
| 2 -> let lbl = new_label () in
- fprintf oc "%a: " label lbl;
+ fprintf oc "%a:\n" label lbl;
add_ais_annot lbl preg_annot "r1" (camlstring_of_coqstring txt) args
| _ -> assert false
end
@@ -875,6 +879,7 @@ module Target (System : SYSTEM):TARGET =
| Pbf(bit, lbl) -> 2
| Pbt(bit, lbl) -> 2
| Pbtbl(r, tbl) -> 5
+ | Pldi (r1,c) -> 2
| Plfi(r1, c) -> 2
| Plfis(r1, c) -> 2
| Plabel lbl -> 0
diff --git a/riscV/Asm.v b/riscV/Asm.v
index 4cd3b1fd..1d8fda11 100644
--- a/riscV/Asm.v
+++ b/riscV/Asm.v
@@ -344,7 +344,8 @@ Inductive instruction : Type :=
| Ploadsi (rd: freg) (f: float32) (**r load an immediate single *)
| Pbtbl (r: ireg) (tbl: list label) (**r N-way branch through a jump table *)
| Pbuiltin: external_function -> list (builtin_arg preg)
- -> builtin_res preg -> instruction. (**r built-in function (pseudo) *)
+ -> builtin_res preg -> instruction (**r built-in function (pseudo) *)
+ | Pnop : instruction. (**r nop instruction *)
(** The pseudo-instructions are the following:
@@ -985,6 +986,7 @@ Definition exec_instr (f: function) (i: instruction) (rs: regset) (m: mem) : out
| Pfmsubd _ _ _ _
| Pfnmaddd _ _ _ _
| Pfnmsubd _ _ _ _
+ | Pnop
=> Stuck
end.
@@ -1013,6 +1015,15 @@ Definition preg_of (r: mreg) : preg :=
| Machregs.F28 => F28 | Machregs.F29 => F29 | Machregs.F30 => F30 | Machregs.F31 => F31
end.
+(** Undefine all registers except SP and callee-save registers *)
+
+Definition undef_caller_save_regs (rs: regset) : regset :=
+ fun r =>
+ if preg_eq r SP
+ || In_dec preg_eq r (List.map preg_of (List.filter is_callee_save all_mregs))
+ then rs r
+ else Vundef.
+
(** Extract the values of the arguments of an external call.
We exploit the calling conventions from module [Conventions], except that
we use RISC-V registers instead of locations. *)
@@ -1073,7 +1084,7 @@ Inductive step: state -> trace -> state -> Prop :=
Genv.find_funct_ptr ge b = Some (External ef) ->
external_call ef ge args m t res m' ->
extcall_arguments rs m (ef_sig ef) args ->
- rs' = (set_pair (loc_external_result (ef_sig ef) ) res rs)#PC <- (rs RA) ->
+ rs' = (set_pair (loc_external_result (ef_sig ef) ) res (undef_caller_save_regs rs))#PC <- (rs RA) ->
step (State rs m) t (State rs' m').
End RELSEM.
diff --git a/riscV/Asmexpand.ml b/riscV/Asmexpand.ml
index 945974e0..3e734747 100644
--- a/riscV/Asmexpand.ml
+++ b/riscV/Asmexpand.ml
@@ -23,7 +23,7 @@ open Asm
open Asmexpandaux
open AST
open Camlcoq
-open Integers
+open !Integers
exception Error of string
@@ -468,7 +468,8 @@ let expand_builtin_inline name args res =
(fun rl ->
emit (Pmulw (rl, X a, X b));
emit (Pmulhuw (rh, X a, X b)))
-
+ | "__builtin_nop", [], _ ->
+ emit Pnop
(* Catch-all *)
| _ ->
raise (Error ("unrecognized builtin " ^ name))
@@ -598,10 +599,7 @@ let preg_to_dwarf = function
let expand_function id fn =
try
set_current_function fn;
- if !Clflags.option_g then
- expand_debug id (* sp= *) 2 preg_to_dwarf expand_instruction fn.fn_code
- else
- List.iter expand_instruction fn.fn_code;
+ expand id (* sp= *) 2 preg_to_dwarf expand_instruction fn.fn_code;
Errors.OK (get_current_function ())
with Error s ->
Errors.Error (Errors.msg (coqstring_of_camlstring s))
diff --git a/riscV/Asmgenproof.v b/riscV/Asmgenproof.v
index cc45a8de..5ec57886 100644
--- a/riscV/Asmgenproof.v
+++ b/riscV/Asmgenproof.v
@@ -975,8 +975,8 @@ Local Transparent destroyed_at_function_entry.
apply plus_one. eapply exec_step_external; eauto.
eapply external_call_symbols_preserved; eauto. apply senv_preserved.
econstructor; eauto.
- unfold loc_external_result.
- apply agree_set_other; auto. apply agree_set_pair; auto.
+ unfold loc_external_result. apply agree_set_other; auto. apply agree_set_pair; auto.
+ apply agree_undef_caller_save_regs; auto.
- (* return *)
inv STACKS. simpl in *.
diff --git a/riscV/TargetPrinter.ml b/riscV/TargetPrinter.ml
index e3fbfe36..19704bad 100644
--- a/riscV/TargetPrinter.ml
+++ b/riscV/TargetPrinter.ml
@@ -564,6 +564,8 @@ module Target : TARGET =
fprintf oc " jr x5\n";
jumptables := (lbl, tbl) :: !jumptables;
fprintf oc "%s end pseudoinstr btbl\n" comment
+ | Pnop ->
+ fprintf oc " nop\n"
| Pbuiltin(ef, args, res) ->
begin match ef with
| EF_annot(kind,txt, targs) ->
@@ -571,7 +573,7 @@ module Target : TARGET =
| 1 -> let annot = annot_text preg_annot "x2" (camlstring_of_coqstring txt) args in
fprintf oc "%s annotation: %S\n" comment annot
| 2 -> let lbl = new_label () in
- fprintf oc "%a: " label lbl;
+ fprintf oc "%a:\n" label lbl;
add_ais_annot lbl preg_annot "x2" (camlstring_of_coqstring txt) args
| _ -> assert false
end
diff --git a/runtime/include/stddef.h b/runtime/include/stddef.h
index 452497c3..6056db62 100644
--- a/runtime/include/stddef.h
+++ b/runtime/include/stddef.h
@@ -117,4 +117,13 @@ typedef signed int wchar_t;
#define offsetof(ty,member) (__builtin_offsetof(ty,member))
#endif
+#ifdef _STDDEF_H
+/* Type whose alignment is supported in every context and is at least
+ as great as that of any standard type not using alignment
+ specifiers. Since we do not support long double per default the type
+ with the maximum alignment supported in every context is long long.
+*/
+typedef long long max_align_t;
+#endif
+
#endif
diff --git a/test/Makefile b/test/Makefile
index e53dfd83..504e4c53 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,4 +1,9 @@
+include ../Makefile.config
+
DIRS=c compression raytracer spass regression
+ifeq ($(CLIGHTGEN),true)
+DIRS+=clightgen
+endif
all:
set -e; for i in $(DIRS); do $(MAKE) CCOMPOPTS='$(CCOMPOPTS)' -C $$i all; done
@@ -6,6 +11,9 @@ all:
test:
set -e; for i in $(DIRS); do $(MAKE) SIMU='$(SIMU)' -C $$i test; done
+parallel:
+ parallel $(MAKE) SIMU='$(SIMU)' -C {} test ::: $(DIRS)
+
bench:
for i in $(DIRS); do $(MAKE) -C $$i bench; done
diff --git a/test/clightgen/Makefile b/test/clightgen/Makefile
new file mode 100644
index 00000000..0607e2fa
--- /dev/null
+++ b/test/clightgen/Makefile
@@ -0,0 +1,44 @@
+include ../../Makefile.config
+
+ifeq ($(wildcard ../../$(ARCH)_$(BITSIZE)),)
+ARCHDIRS=$(ARCH)
+else
+ARCHDIRS=$(ARCH)_$(BITSIZE) $(ARCH)
+endif
+RECDIRS=lib common $(ARCHDIRS) cfrontend flocq exportclight
+COQINCLUDES=$(foreach d, $(RECDIRS), -R ../../$(d) compcert.$(d))
+
+CLIGHTGEN=../../clightgen
+COQC=coqc
+
+# Regression tests in the current directory
+SRC=$(wildcard *.c)
+# From ../c
+SRC+=aes.c almabench.c binarytrees.c bisect.c chomp.c fannkuch.c fft.c \
+ fftsp.c fftw.c fib.c integr.c knucleotide.c lists.c mandelbrot.c \
+ nbody.c nsievebits.c nsieve.c perlin.c qsort.c sha1.c sha3.c \
+ siphash24.c spectral.c vmach.c
+# From ../raytracer
+SRC+=arrays.c eval.c gmllexer.c gmlparser.c intersect.c light.c main.c \
+ matrix.c memory.c object.c render.c simplify.c surface.c vector.c
+
+all: $(SRC:.c=.vo)
+
+test:
+
+%.v: %.c
+ $(CLIGHTGEN) $(CFLAGS) -o $@ $<
+
+%.v: ../c/%.c
+ $(CLIGHTGEN) $(CFLAGS) -o $@ $<
+
+%.v: ../raytracer/%.c
+ $(CLIGHTGEN) -I../raytracer -fall $(CFLAGS) -o $@ $<
+
+%.vo: %.v
+ $(COQC) $(COQINCLUDES) -noglob $<
+
+.SECONDARY: $(SRC:.c=.v)
+
+clean:
+ rm -f *.v *.vo .*.aux
diff --git a/test/clightgen/empty.c b/test/clightgen/empty.c
new file mode 100644
index 00000000..8f8871a7
--- /dev/null
+++ b/test/clightgen/empty.c
@@ -0,0 +1 @@
+/* The empty source file */
diff --git a/test/clightgen/issue196.c b/test/clightgen/issue196.c
new file mode 100644
index 00000000..1821fd6d
--- /dev/null
+++ b/test/clightgen/issue196.c
@@ -0,0 +1,927 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+
+typedef int ASN1_BOOLEAN;
+typedef int ASN1_NULL;
+typedef struct ASN1_ITEM_st ASN1_ITEM;
+typedef struct asn1_object_st ASN1_OBJECT;
+typedef struct asn1_pctx_st ASN1_PCTX;
+typedef struct asn1_string_st ASN1_BIT_STRING;
+typedef struct asn1_string_st ASN1_BMPSTRING;
+typedef struct asn1_string_st ASN1_ENUMERATED;
+typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
+typedef struct asn1_string_st ASN1_GENERALSTRING;
+typedef struct asn1_string_st ASN1_IA5STRING;
+typedef struct asn1_string_st ASN1_INTEGER;
+typedef struct asn1_string_st ASN1_OCTET_STRING;
+typedef struct asn1_string_st ASN1_PRINTABLESTRING;
+typedef struct asn1_string_st ASN1_STRING;
+typedef struct asn1_string_st ASN1_T61STRING;
+typedef struct asn1_string_st ASN1_TIME;
+typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
+typedef struct asn1_string_st ASN1_UTCTIME;
+typedef struct asn1_string_st ASN1_UTF8STRING;
+typedef struct asn1_string_st ASN1_VISIBLESTRING;
+
+typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
+typedef struct DIST_POINT_st DIST_POINT;
+typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
+typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
+typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
+typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
+typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
+typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
+typedef struct X509_algor_st X509_ALGOR;
+typedef struct X509_crl_st X509_CRL;
+typedef struct X509_pubkey_st X509_PUBKEY;
+typedef struct bignum_ctx BN_CTX;
+typedef struct bignum_st BIGNUM;
+typedef struct bio_method_st BIO_METHOD;
+typedef struct bio_st BIO;
+typedef struct bn_gencb_st BN_GENCB;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct buf_mem_st BUF_MEM;
+typedef struct cbb_st CBB;
+typedef struct cbs_st CBS;
+typedef struct conf_st CONF;
+typedef struct dh_method DH_METHOD;
+typedef struct dh_st DH;
+typedef struct dsa_method DSA_METHOD;
+typedef struct dsa_st DSA;
+typedef struct ec_key_st EC_KEY;
+typedef struct ecdsa_method_st ECDSA_METHOD;
+typedef struct ecdsa_sig_st ECDSA_SIG;
+typedef struct engine_st ENGINE;
+typedef struct env_md_ctx_st EVP_MD_CTX;
+typedef struct env_md_st EVP_MD;
+typedef struct evp_aead_st EVP_AEAD;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
+typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
+typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
+typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
+typedef struct evp_pkey_st EVP_PKEY;
+typedef struct hmac_ctx_st HMAC_CTX;
+typedef struct md4_state_st MD4_CTX;
+typedef struct md5_state_st MD5_CTX;
+typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
+typedef struct pkcs12_st PKCS12;
+typedef struct rand_meth_st RAND_METHOD;
+typedef struct rc4_key_st RC4_KEY;
+typedef struct rsa_meth_st RSA_METHOD;
+typedef struct rsa_st RSA;
+typedef struct sha256_state_st SHA256_CTX;
+typedef struct sha512_state_st SHA512_CTX;
+typedef struct sha_state_st SHA_CTX;
+typedef struct ssl_ctx_st SSL_CTX;
+typedef struct ssl_st SSL;
+typedef struct st_ERR_FNS ERR_FNS;
+typedef struct v3_ext_ctx X509V3_CTX;
+typedef struct x509_crl_method_st X509_CRL_METHOD;
+typedef struct x509_revoked_st X509_REVOKED;
+typedef struct x509_st X509;
+typedef struct x509_store_ctx_st X509_STORE_CTX;
+typedef struct x509_store_st X509_STORE;
+typedef void *OPENSSL_BLOCK;
+ const EVP_MD *EVP_md4(void);
+ const EVP_MD *EVP_md5(void);
+ const EVP_MD *EVP_sha1(void);
+ const EVP_MD *EVP_sha224(void);
+ const EVP_MD *EVP_sha256(void);
+ const EVP_MD *EVP_sha384(void);
+ const EVP_MD *EVP_sha512(void);
+
+
+
+ const EVP_MD *EVP_md5_sha1(void);
+
+
+
+ const EVP_MD *EVP_get_digestbynid(int nid);
+
+
+
+ const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj);
+ void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
+
+
+
+ EVP_MD_CTX *EVP_MD_CTX_create(void);
+
+
+
+ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
+
+
+ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
+
+
+
+ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+
+
+
+
+
+
+
+ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type,
+ ENGINE *engine);
+
+
+
+ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+
+
+
+ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
+ size_t len);
+ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out,
+ unsigned int *out_size);
+
+
+
+ int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md_out,
+ unsigned int *out_size);
+
+
+
+
+
+
+ int EVP_Digest(const void *data, size_t len, uint8_t *md_out,
+ unsigned int *md_out_size, const EVP_MD *type,
+ ENGINE *impl);
+ int EVP_MD_type(const EVP_MD *md);
+
+
+ const char *EVP_MD_name(const EVP_MD *md);
+
+
+
+ uint32_t EVP_MD_flags(const EVP_MD *md);
+
+
+ size_t EVP_MD_size(const EVP_MD *md);
+
+
+ size_t EVP_MD_block_size(const EVP_MD *md);
+ int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+
+
+
+ int EVP_add_digest(const EVP_MD *digest);
+
+
+
+
+
+
+ const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+
+
+
+ unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx);
+
+
+
+ unsigned EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx);
+
+
+
+
+ int EVP_MD_CTX_type(const EVP_MD_CTX *ctx);
+
+
+ void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags);
+
+
+
+ void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, uint32_t flags);
+
+
+
+ uint32_t EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx,
+ uint32_t flags);
+
+
+struct evp_md_pctx_ops;
+
+struct env_md_ctx_st {
+
+ const EVP_MD *digest;
+
+ uint32_t flags;
+
+
+ void *md_data;
+
+
+
+ int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
+
+
+
+ EVP_PKEY_CTX *pctx;
+
+
+
+ const struct evp_md_pctx_ops *pctx_ops;
+} ;
+
+ int MD4_Init(MD4_CTX *md4);
+
+
+ int MD4_Update(MD4_CTX *md4, const void *data, size_t len);
+
+
+
+
+ int MD4_Final(uint8_t *md, MD4_CTX *md4);
+
+
+
+ void MD4_Transform(MD4_CTX *md4, const uint8_t *block);
+
+struct md4_state_st {
+ uint32_t A, B, C, D;
+ uint32_t Nl, Nh;
+ uint32_t data[16];
+ unsigned int num;
+};
+ int MD5_Init(MD5_CTX *md5);
+
+
+ int MD5_Update(MD5_CTX *md5, const void *data, size_t len);
+
+
+
+
+ int MD5_Final(uint8_t *md, MD5_CTX *md5);
+
+
+
+ uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out);
+
+
+
+ void MD5_Transform(MD5_CTX *md5, const uint8_t *block);
+
+struct md5_state_st {
+ uint32_t A, B, C, D;
+ uint32_t Nl, Nh;
+ uint32_t data[16];
+ unsigned int num;
+};
+struct cbs_st {
+ const uint8_t *data;
+ size_t len;
+};
+
+
+
+ void CBS_init(CBS *cbs, const uint8_t *data, size_t len);
+
+
+
+ int CBS_skip(CBS *cbs, size_t len);
+
+
+ const uint8_t *CBS_data(const CBS *cbs);
+
+
+ size_t CBS_len(const CBS *cbs);
+
+
+
+
+
+
+ int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len);
+ int CBS_strdup(const CBS *cbs, char **out_ptr);
+
+
+
+ int CBS_contains_zero_byte(const CBS *cbs);
+
+
+
+
+ int CBS_mem_equal(const CBS *cbs, const uint8_t *data,
+ size_t len);
+
+
+
+ int CBS_get_u8(CBS *cbs, uint8_t *out);
+
+
+
+ int CBS_get_u16(CBS *cbs, uint16_t *out);
+
+
+
+ int CBS_get_u24(CBS *cbs, uint32_t *out);
+
+
+
+ int CBS_get_u32(CBS *cbs, uint32_t *out);
+
+
+
+ int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
+
+
+
+
+ int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out);
+
+
+
+
+ int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out);
+
+
+
+
+ int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
+ int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value);
+
+
+
+ int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value);
+
+
+
+
+
+
+ int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value);
+ int CBS_get_any_asn1_element(CBS *cbs, CBS *out,
+ unsigned *out_tag,
+ size_t *out_header_len);
+
+
+
+
+
+ int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out);
+
+
+
+
+
+
+ int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
+ unsigned tag);
+
+
+
+
+
+
+
+ int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out,
+ int *out_present,
+ unsigned tag);
+
+
+
+
+
+
+ int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out,
+ unsigned tag,
+ uint64_t default_value);
+
+
+
+
+
+
+ int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
+ int default_value);
+struct cbb_buffer_st {
+ uint8_t *buf;
+ size_t len;
+ size_t cap;
+ char can_resize;
+
+};
+
+struct cbb_st {
+ struct cbb_buffer_st *base;
+
+
+ size_t offset;
+
+ struct cbb_st *child;
+
+
+ uint8_t pending_len_len;
+ char pending_is_asn1;
+
+
+ char is_top_level;
+};
+
+
+
+
+ int CBB_init(CBB *cbb, size_t initial_capacity);
+
+
+
+
+ int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
+
+
+
+
+ void CBB_cleanup(CBB *cbb);
+ int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
+
+
+
+
+ int CBB_flush(CBB *cbb);
+
+
+
+
+ int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents);
+
+
+
+
+ int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
+
+
+
+
+ int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
+
+
+
+
+
+
+ int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
+
+
+
+ int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
+
+
+
+
+
+ int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len);
+
+
+
+ int CBB_add_u8(CBB *cbb, uint8_t value);
+
+
+
+ int CBB_add_u16(CBB *cbb, uint16_t value);
+
+
+
+ int CBB_add_u24(CBB *cbb, uint32_t value);
+
+
+
+
+ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
+ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *obj);
+
+
+
+ int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b);
+
+
+
+
+
+
+ int OBJ_obj2nid(const ASN1_OBJECT *obj);
+
+
+
+ int OBJ_cbs2nid(const CBS *cbs);
+
+
+
+ int OBJ_sn2nid(const char *short_name);
+
+
+
+ int OBJ_ln2nid(const char *long_name);
+
+
+
+
+ int OBJ_txt2nid(const char *s);
+
+
+
+
+
+
+ const ASN1_OBJECT *OBJ_nid2obj(int nid);
+
+
+ const char *OBJ_nid2sn(int nid);
+
+
+ const char *OBJ_nid2ln(int nid);
+
+
+
+ int OBJ_nid2cbb(CBB *out, int nid);
+ ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names);
+ int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj,
+ int dont_return_name);
+
+
+
+
+
+
+ int OBJ_create(const char *oid, const char *short_name,
+ const char *long_name);
+ int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid,
+ int *out_pkey_nid);
+
+
+
+
+
+
+ int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid,
+ int pkey_nid);
+ int SHA1_Init(SHA_CTX *sha);
+
+
+ int SHA1_Update(SHA_CTX *sha, const void *data, size_t len);
+
+
+
+
+ int SHA1_Final(uint8_t *md, SHA_CTX *sha);
+
+
+
+
+ uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out);
+
+
+
+ void SHA1_Transform(SHA_CTX *sha, const uint8_t *block);
+
+struct sha_state_st {
+ uint32_t h0, h1, h2, h3, h4;
+ uint32_t Nl, Nh;
+ uint32_t data[16];
+ unsigned int num;
+};
+ int SHA224_Init(SHA256_CTX *sha);
+
+
+ int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len);
+
+
+
+ int SHA224_Final(uint8_t *md, SHA256_CTX *sha);
+
+
+
+
+ uint8_t *SHA224(const uint8_t *data, size_t len, uint8_t *out);
+ int SHA256_Init(SHA256_CTX *sha);
+
+
+ int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len);
+
+
+
+ int SHA256_Final(uint8_t *md, SHA256_CTX *sha);
+
+
+
+
+ uint8_t *SHA256(const uint8_t *data, size_t len, uint8_t *out);
+
+
+
+ void SHA256_Transform(SHA256_CTX *sha, const uint8_t *data);
+
+struct sha256_state_st {
+ uint32_t h[8];
+ uint32_t Nl, Nh;
+ uint32_t data[16];
+ unsigned int num, md_len;
+};
+ int SHA384_Init(SHA512_CTX *sha);
+
+
+ int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len);
+
+
+
+ int SHA384_Final(uint8_t *md, SHA512_CTX *sha);
+
+
+
+
+ uint8_t *SHA384(const uint8_t *data, size_t len, uint8_t *out);
+
+
+
+ void SHA384_Transform(SHA512_CTX *sha, const uint8_t *data);
+ int SHA512_Init(SHA512_CTX *sha);
+
+
+ int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len);
+
+
+
+ int SHA512_Final(uint8_t *md, SHA512_CTX *sha);
+
+
+
+
+ uint8_t *SHA512(const uint8_t *data, size_t len, uint8_t *out);
+
+
+
+ void SHA512_Transform(SHA512_CTX *sha, const uint8_t *data);
+
+struct sha512_state_st {
+ uint64_t h[8];
+ uint64_t Nl, Nh;
+ union {
+ uint64_t d[16];
+ uint8_t p[128];
+ } u;
+ unsigned int num, md_len;
+};
+
+struct env_md_st {
+
+
+ int type;
+
+
+ unsigned md_size;
+
+
+ uint32_t flags;
+
+
+
+ int (*init)(EVP_MD_CTX *ctx);
+
+
+ int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
+
+
+ int (*final)(EVP_MD_CTX *ctx, uint8_t *out);
+
+
+ unsigned block_size;
+
+
+ unsigned ctx_size;
+};
+
+
+
+
+struct evp_md_pctx_ops {
+
+
+ void (*free) (EVP_PKEY_CTX *pctx);
+
+
+
+ EVP_PKEY_CTX* (*dup) (EVP_PKEY_CTX *pctx);
+
+
+
+ int (*begin_digest) (EVP_MD_CTX *ctx);
+};
+
+
+static int md4_init(EVP_MD_CTX *ctx) { return MD4_Init(ctx->md_data); }
+
+static int md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return MD4_Update(ctx->md_data, data, count);
+}
+
+static int md4_final(EVP_MD_CTX *ctx, unsigned char *out) {
+ return MD4_Final(out, ctx->md_data);
+}
+
+static const EVP_MD md4_md = {
+ 257, 16, 0 , md4_init,
+ md4_update, md4_final, 64 , sizeof(MD4_CTX),
+};
+
+const EVP_MD *EVP_md4(void) { return &md4_md; }
+
+
+static int md5_init(EVP_MD_CTX *ctx) { return MD5_Init(ctx->md_data); }
+
+static int md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return MD5_Update(ctx->md_data, data, count);
+}
+
+static int md5_final(EVP_MD_CTX *ctx, unsigned char *out) {
+ return MD5_Final(out, ctx->md_data);
+}
+
+static const EVP_MD md5_md = {
+ 4, 16, 0 , md5_init,
+ md5_update, md5_final, 64 , sizeof(MD5_CTX),
+};
+
+const EVP_MD *EVP_md5(void) { return &md5_md; }
+
+
+static int sha1_init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); }
+
+static int sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int sha1_final(EVP_MD_CTX *ctx, unsigned char *md) {
+ return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha1_md = {
+ 64, 20, 0 , sha1_init,
+ sha1_update, sha1_final, 64 , sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_sha1(void) { return &sha1_md; }
+
+
+static int sha224_init(EVP_MD_CTX *ctx) { return SHA224_Init(ctx->md_data); }
+
+static int sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return SHA224_Update(ctx->md_data, data, count);
+}
+
+static int sha224_final(EVP_MD_CTX *ctx, unsigned char *md) {
+ return SHA224_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha224_md = {
+ 675, 28, 0 ,
+ sha224_init, sha224_update, sha224_final,
+ 64 , sizeof(SHA256_CTX),
+};
+
+const EVP_MD *EVP_sha224(void) { return &sha224_md; }
+
+
+static int sha256_init(EVP_MD_CTX *ctx) { return SHA256_Init(ctx->md_data); }
+
+static int sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return SHA256_Update(ctx->md_data, data, count);
+}
+
+static int sha256_final(EVP_MD_CTX *ctx, unsigned char *md) {
+ return SHA256_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha256_md = {
+ 672, 32, 0 ,
+ sha256_init, sha256_update, sha256_final,
+ 64 , sizeof(SHA256_CTX),
+};
+
+const EVP_MD *EVP_sha256(void) { return &sha256_md; }
+
+
+static int sha384_init(EVP_MD_CTX *ctx) { return SHA384_Init(ctx->md_data); }
+
+static int sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return SHA384_Update(ctx->md_data, data, count);
+}
+
+static int sha384_final(EVP_MD_CTX *ctx, unsigned char *md) {
+ return SHA384_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha384_md = {
+ 673, 48, 0 ,
+ sha384_init, sha384_update, sha384_final,
+ 128 , sizeof(SHA512_CTX),
+};
+
+const EVP_MD *EVP_sha384(void) { return &sha384_md; }
+
+
+static int sha512_init(EVP_MD_CTX *ctx) { return SHA512_Init(ctx->md_data); }
+
+static int sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return SHA512_Update(ctx->md_data, data, count);
+}
+
+static int sha512_final(EVP_MD_CTX *ctx, unsigned char *md) {
+ return SHA512_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha512_md = {
+ 674, 64, 0 ,
+ sha512_init, sha512_update, sha512_final,
+ 128 , sizeof(SHA512_CTX),
+};
+
+const EVP_MD *EVP_sha512(void) { return &sha512_md; }
+
+
+typedef struct {
+ MD5_CTX md5;
+ SHA_CTX sha1;
+} MD5_SHA1_CTX;
+
+static int md5_sha1_init(EVP_MD_CTX *md_ctx) {
+ MD5_SHA1_CTX *ctx = md_ctx->md_data;
+ return MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1);
+}
+
+static int md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data, size_t count) {
+ MD5_SHA1_CTX *ctx = md_ctx->md_data;
+ return MD5_Update(&ctx->md5, data, count) && SHA1_Update(&ctx->sha1, data, count);
+}
+
+static int md5_sha1_final(EVP_MD_CTX *md_ctx, unsigned char *out) {
+ MD5_SHA1_CTX *ctx = md_ctx->md_data;
+ if (!MD5_Final(out, &ctx->md5) ||
+ !SHA1_Final(out + 16, &ctx->sha1)) {
+ return 0;
+ }
+ return 1;
+}
+
+static const EVP_MD md5_sha1_md = {
+ 114,
+ 16 + 20,
+ 0 ,
+ md5_sha1_init,
+ md5_sha1_update,
+ md5_sha1_final,
+ 64 ,
+ sizeof(MD5_SHA1_CTX),
+};
+
+const EVP_MD *EVP_md5_sha1(void) { return &md5_sha1_md; }
+
+
+struct nid_to_digest {
+ int nid;
+ const EVP_MD* (*md_func)(void);
+};
+
+static const struct nid_to_digest nid_to_digest_mapping[] = {
+ { 4, EVP_md5 },
+ { 64, EVP_sha1 },
+ { 675, EVP_sha224 },
+ { 672, EVP_sha256 },
+ { 673, EVP_sha384 },
+ { 674, EVP_sha512 },
+ { 114, EVP_md5_sha1 },
+ { 66, EVP_sha1 },
+ { 113, EVP_sha1 },
+ { 416, EVP_sha1 },
+ { 8, EVP_md5 },
+ { 65, EVP_sha1 },
+ { 671, EVP_sha224 },
+ { 668, EVP_sha256 },
+ { 669, EVP_sha384 },
+ { 670, EVP_sha512 },
+};
+
+const EVP_MD* EVP_get_digestbynid(int nid) {
+ unsigned i;
+
+ for (i = 0; i < sizeof(nid_to_digest_mapping) / sizeof(struct nid_to_digest);
+ i++) {
+ if (nid_to_digest_mapping[i].nid == nid) {
+ return nid_to_digest_mapping[i].md_func();
+ }
+ }
+
+ return
+ ((void *)0)
+ ;
+}
+
+const EVP_MD* EVP_get_digestbyobj(const ASN1_OBJECT *obj) {
+ return EVP_get_digestbynid(OBJ_obj2nid(obj));
+}
diff --git a/test/clightgen/issue216.c b/test/clightgen/issue216.c
new file mode 100644
index 00000000..796b69b4
--- /dev/null
+++ b/test/clightgen/issue216.c
@@ -0,0 +1,5 @@
+#include <stddef.h>
+
+struct list {unsigned head; struct list *tail;};
+struct list three[] = { {1, three+1}, {2, three+2}, {3, NULL} };
+int f(int x) { return x;}
diff --git a/test/regression/Makefile b/test/regression/Makefile
index 48e2b7b3..191a2285 100644
--- a/test/regression/Makefile
+++ b/test/regression/Makefile
@@ -1,7 +1,9 @@
include ../../Makefile.config
CCOMP=../../ccomp
-CCOMPFLAGS=$(CCOMPOPTS) -stdlib ../../runtime -dparse -dc -dclight -dasm -fall
+CCOMPFLAGS=$(CCOMPOPTS) -stdlib ../../runtime \
+ -dparse -dc -dclight -dasm -fall \
+ -DARCH_$(ARCH) -DMODEL_$(MODEL)
INTERPFLAGS=-stdlib ../../runtime -interp -quiet -fall
LIBS=$(LIBMATH)
@@ -20,18 +22,9 @@ TESTS=int32 int64 floats floats-basics \
TESTS_COMP=attribs1 bitfields1 bitfields2 bitfields3 bitfields4 \
bitfields5 bitfields6 bitfields7 bitfields8 \
- builtins-$(ARCH) packedstruct2 alignas \
+ builtins-$(ARCH) packedstruct1 packedstruct2 alignas \
varargs1 varargs2 sections alias
-# packedstruct1 makes unaligned memory accesses
-
-ifeq ($(ARCH),powerpc)
-TESTS_COMP+=packedstruct1
-endif
-ifeq ($(ARCH),x86)
-TESTS_COMP+=packedstruct1
-endif
-
# Can run, both in compiled mode and in interpreter mode,
# but produce processor-dependent results, so no reference output in Results
@@ -70,12 +63,12 @@ clean:
test:
@echo "----------- Compiled tests -------------"
- @for i in $(TESTS) $(TESTS_COMP); do \
+ @set -e; for i in $(TESTS) $(TESTS_COMP); do \
SIMU='$(SIMU)' ./Runtest $$i ./$$i.compcert; \
done
@echo "----------- Interpreted tests -------------"
- @for i in $(TESTS); do \
- SIMU='' ./Runtest $$i $(CCOMP) $(INTERPFLAGS) $$i.c; \
+ @set -e; for i in $(TESTS); do \
+ SIMU='' INTERP=1 ./Runtest $$i $(CCOMP) $(INTERPFLAGS) $$i.c; \
done
@for i in $(TESTS_DIFF); do \
if $(CCOMP) -fall -interp -quiet $$i.c > _cinterp.log; then \
diff --git a/test/regression/Results/alignas b/test/regression/Results/alignas
index 581a4377..620b5e76 100644
--- a/test/regression/Results/alignas
+++ b/test/regression/Results/alignas
@@ -1,9 +1,10 @@
-a: size = 4, alignment = 16, address mod 16 = 0
-b: size = 12, alignment = 16, address mod 16 = 0
-bb: size = 12, alignment = 16, address mod 16 = 0
-c: size = 32, alignment = 16, address mod 16 = 0
-d: size = 32, alignment = 64, address mod 64 = 0
-e: size = 16, alignment = 16, address mod 16 = 0
-f: size = 16, alignment = 32, address mod 32 = 0
-g: size = 96, alignment = 16, address mod 16 = 0
-h: size = 192, alignment = 64, address mod 64 = 0
+a: size = 4, address mod 16 = 0
+b: size = 12, address mod 16 = 0
+bb: size = 12, address mod 16 = 0
+bbb: size = 12, address mod 16 = 0
+c: size = 32, address mod 16 = 0
+d: size = 32, address mod 64 = 0
+e: size = 16, address mod 16 = 0
+f: size = 16, address mod 32 = 0
+g: size = 96, address mod 16 = 0
+h: size = 192, address mod 64 = 0
diff --git a/test/regression/Results/bitfields9 b/test/regression/Results/bitfields9
index a1d0e9fd..e35c2414 100644
--- a/test/regression/Results/bitfields9
+++ b/test/regression/Results/bitfields9
@@ -1,10 +1,18 @@
glob_s = { a = -12, b = 1 }
glob_t = { c = 123, d = 1, e = -45 }
+glob_u_u = { u = -3 }
+glob_u_v = { v = 6 }
loc_s = { a = 11, b = 2 }
loc_t = { c = 11, d = 1, e = 2 }
+loc_u_u = { u = -5 }
+loc_u_v = { v = 3 }
compound_s = { a = 2, b = 3 }
compound_t = { c = 2, d = 1, e = -11 }
+compound_u = { u = 2 }
loc_s = { a = 7, b = 2 }
loc_t = { c = 7, d = 1, e = 50 }
+loc_u_u = { u = 7 }
+loc_u_v = { v = 2 }
compound_s = { a = -14, b = 3 }
compound_t = { c = 50, d = 1, e = -7 }
+compound_u = { u = 2 }
diff --git a/test/regression/Results/packedstruct1-32 b/test/regression/Results/packedstruct1-32
index e4bca769..e7d1c296 100644
--- a/test/regression/Results/packedstruct1-32
+++ b/test/regression/Results/packedstruct1-32
@@ -1,25 +1,37 @@
sizeof(struct s1) = 14
+precomputed sizeof(struct s1) = 14
offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
+precomputed offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
s1 = {x = 123, y = -456, z = 3.14159}
sizeof(struct s2) = 16
+precomputed sizeof(struct s2) = 16
&s2 mod 16 = 0
offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
+precomputed offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
s2 = {x = 57, y = -456, z = 3.14159}
sizeof(struct s3) = 31
+precomputed sizeof(struct s3) = 31
offsetof(s) = 29
+precomputed offsetof(s) = 29
s3 = {x = 123, y = 45678, z = 2147483649, v = -456, w = -1234567, p is ok, t = {111,222,333}, s = {'o','k'}}
sizeof(struct s4) = 16
+precomputed sizeof(struct s4) = 16
offsetof(x) = 0, offsetof(y) = 4, offsetof(z) = 8
+precomputed offsetof(x) = 0, offsetof(y) = 4, offsetof(z) = 8
s4 = {x = 123, y = -456, z = 3.14159}
sizeof(struct s5) = 14
+precomputed sizeof(struct s5) = 14
offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
+precomputed offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
s5 = {x = 123, y = -456, z = 3.14159}
sizeof(struct s6) = 14
+precomputed sizeof(struct s6) = 14
offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
+precomputed offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
s62 = {x = 123, y = -456, z = 3.14159}
diff --git a/test/regression/Results/packedstruct1-64 b/test/regression/Results/packedstruct1-64
index c2a8bcd2..d255595f 100644
--- a/test/regression/Results/packedstruct1-64
+++ b/test/regression/Results/packedstruct1-64
@@ -1,25 +1,37 @@
sizeof(struct s1) = 14
+precomputed sizeof(struct s1) = 14
offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
+precomputed offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
s1 = {x = 123, y = -456, z = 3.14159}
sizeof(struct s2) = 16
+precomputed sizeof(struct s2) = 16
&s2 mod 16 = 0
offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
+precomputed offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
s2 = {x = 57, y = -456, z = 3.14159}
sizeof(struct s3) = 35
+precomputed sizeof(struct s3) = 35
offsetof(s) = 33
+precomputed offsetof(s) = 33
s3 = {x = 123, y = 45678, z = 2147483649, v = -456, w = -1234567, p is ok, t = {111,222,333}, s = {'o','k'}}
sizeof(struct s4) = 16
+precomputed sizeof(struct s4) = 16
offsetof(x) = 0, offsetof(y) = 4, offsetof(z) = 8
+precomputed offsetof(x) = 0, offsetof(y) = 4, offsetof(z) = 8
s4 = {x = 123, y = -456, z = 3.14159}
sizeof(struct s5) = 14
+precomputed sizeof(struct s5) = 14
offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
+precomputed offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
s5 = {x = 123, y = -456, z = 3.14159}
sizeof(struct s6) = 14
+precomputed sizeof(struct s6) = 14
offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
+precomputed offsetof(x) = 0, offsetof(y) = 2, offsetof(z) = 6
s62 = {x = 123, y = -456, z = 3.14159}
diff --git a/test/regression/Runtest b/test/regression/Runtest
index ad2a58f1..f693219a 100755
--- a/test/regression/Runtest
+++ b/test/regression/Runtest
@@ -9,6 +9,9 @@ out="test$$.log"
rm -f $out
trap "rm -f $out" 0 INT QUIT
+# Is the test expected to fail?
+expect_fail=false
+
# The architecture and the bitsize
arch=`sed -n -e 's/^ARCH=//p' ../../Makefile.config`
bits=`sed -n -e 's/^BITSIZE=//p' ../../Makefile.config`
@@ -26,10 +29,23 @@ else
ref=""
fi
+# Special conditions
+
+if test -f "$name.cond"; then
+ RUN=0 SKIP=1 EXPECT_FAIL=2 sh "$name.cond"
+ case "$?" in
+ 1) echo "$name: skipped"; exit 0;;
+ 2) expect_fail=true;;
+ esac
+fi
+
# Administer the test
if $SIMU $* > $out
then
- if test -n "$ref"; then
+ if $expect_fail; then
+ echo "$name: ERROR (should have failed but did not)"
+ exit 2
+ elif test -n "$ref"; then
if cmp -s "$out" "$ref"; then
echo "$name: passed"
exit 0
@@ -43,7 +59,13 @@ then
exit 0
fi
else
- echo "$name: EXECUTION FAILED (status $?)"
- exit 2
+ retcode=$?
+ if $expect_fail; then
+ echo "$name: passed (failed as expected)"
+ exit 0
+ else
+ echo "$name: EXECUTION FAILED (status $retcode)"
+ exit 2
+ fi
fi
diff --git a/test/regression/alignas.c b/test/regression/alignas.c
index b3754039..777c13a5 100644
--- a/test/regression/alignas.c
+++ b/test/regression/alignas.c
@@ -2,16 +2,12 @@
#include <stdio.h>
-#if __STDC_VERSION__ < 201100 && defined(__GNUC__)
-#define _Alignas(x) __attribute__((aligned(x)))
-#define _Alignof(x) __alignof__(x)
-#endif
-
#ifdef _Alignas
#undef _Alignas
#endif
-#ifdef _Alignof
-#undef _Alignof
+
+#if __STDC_VERSION__ < 201100 && defined(__GNUC__)
+#define _Alignas(x) __attribute((aligned(x)))
#endif
/* Base type */
@@ -24,10 +20,9 @@ _Alignas(16) int b[3];
typedef int int3[3];
_Alignas(16) int3 bb;
-#if 0
-typedef _Alignas(16) int int16;
+/* _Alignas is not allowed in typedefs but the "aligned" attribute is */
+typedef __attribute((aligned(16))) int int16;
int16 bbb[3];
-#endif
char filler2;
@@ -72,28 +67,26 @@ char filler8;
int main()
{
- printf("a: size = %u, alignment = %u, address mod 16 = %u\n",
- (unsigned) sizeof(a), (unsigned) _Alignof(a), ((unsigned) &a) & 0xF);
- printf("b: size = %u, alignment = %u, address mod 16 = %u\n",
- (unsigned) sizeof(b), (unsigned) _Alignof(b), ((unsigned) &b) & 0xF);
- printf("bb: size = %u, alignment = %u, address mod 16 = %u\n",
- (unsigned) sizeof(bb), (unsigned) _Alignof(bb), ((unsigned) &bb) & 0xF);
-#if 0
- printf("bbb: size = %u, alignment = %u, address mod 16 = %u\n",
- (unsigned) sizeof(bbb), (unsigned) _Alignof(bbb), ((unsigned) &bbb) & 0xF);
-#endif
- printf("c: size = %u, alignment = %u, address mod 16 = %u\n",
- (unsigned) sizeof(c), (unsigned) _Alignof(c), ((unsigned) &c) & 0xF);
- printf("d: size = %u, alignment = %u, address mod 64 = %u\n",
- (unsigned) sizeof(d), (unsigned) _Alignof(d), ((unsigned) &d) & 0x3F);
- printf("e: size = %u, alignment = %u, address mod 16 = %u\n",
- (unsigned) sizeof(e), (unsigned) _Alignof(e), ((unsigned) &e) & 0xF);
- printf("f: size = %u, alignment = %u, address mod 32 = %u\n",
- (unsigned) sizeof(f), (unsigned) _Alignof(f), ((unsigned) &f) & 0x1F);
- printf("g: size = %u, alignment = %u, address mod 16 = %u\n",
- (unsigned) sizeof(g), (unsigned) _Alignof(g), ((unsigned) &g) & 0xF);
- printf("h: size = %u, alignment = %u, address mod 64 = %u\n",
- (unsigned) sizeof(h), (unsigned) _Alignof(h), ((unsigned) &h) & 0x3F);
+ printf("a: size = %u, address mod 16 = %u\n",
+ (unsigned) sizeof(a), ((unsigned) &a) & 0xF);
+ printf("b: size = %u, address mod 16 = %u\n",
+ (unsigned) sizeof(b), ((unsigned) &b) & 0xF);
+ printf("bb: size = %u, address mod 16 = %u\n",
+ (unsigned) sizeof(bb), ((unsigned) &bb) & 0xF);
+ printf("bbb: size = %u, address mod 16 = %u\n",
+ (unsigned) sizeof(bbb), ((unsigned) &bbb) & 0xF);
+ printf("c: size = %u, address mod 16 = %u\n",
+ (unsigned) sizeof(c), ((unsigned) &c) & 0xF);
+ printf("d: size = %u, address mod 64 = %u\n",
+ (unsigned) sizeof(d), ((unsigned) &d) & 0x3F);
+ printf("e: size = %u, address mod 16 = %u\n",
+ (unsigned) sizeof(e), ((unsigned) &e) & 0xF);
+ printf("f: size = %u, address mod 32 = %u\n",
+ (unsigned) sizeof(f), ((unsigned) &f) & 0x1F);
+ printf("g: size = %u, address mod 16 = %u\n",
+ (unsigned) sizeof(g), ((unsigned) &g) & 0xF);
+ printf("h: size = %u, address mod 64 = %u\n",
+ (unsigned) sizeof(h), ((unsigned) &h) & 0x3F);
return 0;
}
diff --git a/test/regression/bitfields9.c b/test/regression/bitfields9.c
index be87057b..eef20168 100644
--- a/test/regression/bitfields9.c
+++ b/test/regression/bitfields9.c
@@ -11,6 +11,12 @@ struct t {
unsigned int c: 16;
_Bool d: 1;
short e: 8;
+ int : 10;
+};
+
+union u {
+ int u: 4;
+ unsigned int v: 3;
};
void print_s(char * msg, struct s p)
@@ -23,25 +29,45 @@ void print_t(char * msg, struct t p)
printf("%s = { c = %d, d = %d, e = %d }\n", msg, p.c, p.d, p.e);
}
+void print_u_u(char * msg, union u p)
+{
+ printf("%s = { u = %d }\n", msg, p.u);
+}
+
+void print_u_v(char * msg, union u p)
+{
+ printf("%s = { v = %u }\n", msg, p.v);
+}
+
+
/* Global initialization */
struct s glob_s = { -12, 1 };
struct t glob_t = { 123, 2, -45 };
+union u glob_u_u = { -3 };
+union u glob_u_v = { .v = 6 };
/* Local initialization */
void f(int x, int y, int z)
{
struct s loc_s = { x, y };
struct t loc_t = { x, z, y };
+ union u loc_u_u = { .u = x };
+ union u loc_u_v = { .v = z };
print_s("loc_s", loc_s);
print_t("loc_t", loc_t);
+ print_u_u("loc_u_u", loc_u_u);
+ print_u_v("loc_u_v", loc_u_v);
print_s("compound_s", (struct s) { y, x });
print_t("compound_t", (struct t) { y, ~z, -x });
+ print_u_u("compound_u", (union u) { y });
}
int main()
{
print_s("glob_s", glob_s);
print_t("glob_t", glob_t);
+ print_u_u("glob_u_u", glob_u_u);
+ print_u_v("glob_u_v", glob_u_v);
f(11, 2, 3);
f(7, 50, 2);
return 0;
diff --git a/test/regression/extasm.c b/test/regression/extasm.c
index a41c4202..babc57f1 100644
--- a/test/regression/extasm.c
+++ b/test/regression/extasm.c
@@ -18,7 +18,10 @@ int clobbers(int x, int z)
return y + z;
}
-#if defined(__x86_64__) || __riscv_xlen == 64
+#if (defined(ARCH_x86) && defined(MODEL_64)) \
+ || (defined(ARCH_riscV) && defined(MODEL_64)) \
+ || (defined(ARCH_powerpc) && defined(MODEL_ppc64)) \
+ || (defined(ARCH_powerpc) && defined(MODEL_e5500))
#define SIXTYFOUR
#else
#undef SIXTYFOUR
diff --git a/test/regression/funptr2.cond b/test/regression/funptr2.cond
new file mode 100644
index 00000000..ab460efb
--- /dev/null
+++ b/test/regression/funptr2.cond
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+if test -n "$INTERP"
+then exit $EXPECT_FAIL
+else exit $RUN
+fi
diff --git a/test/regression/interop1.cond b/test/regression/interop1.cond
new file mode 100644
index 00000000..77904189
--- /dev/null
+++ b/test/regression/interop1.cond
@@ -0,0 +1,10 @@
+#!/bin/sh
+arch=`sed -n -e 's/^ARCH=//p' ../../Makefile.config`
+model=`sed -n -e 's/^MODEL=//p' ../../Makefile.config`
+system=`sed -n -e 's/^SYSTEM=//p' ../../Makefile.config`
+
+case "$arch,$model,$system" in
+ *,*,cygwin) exit $SKIP;;
+ x86,32sse2,*|arm,*,*|powerpc,*,*) exit $RUN;;
+ *) exit $SKIP;;
+esac
diff --git a/test/regression/packedstruct1.c b/test/regression/packedstruct1.c
index 8b138dd4..5d3e7124 100644
--- a/test/regression/packedstruct1.c
+++ b/test/regression/packedstruct1.c
@@ -2,8 +2,18 @@
#include <stdio.h>
+/* offsetof is the offset computed by the verified front-end (cfrontend/) */
#define offsetof(s,f) (int)&(((struct s *)0)->f)
+/* boffsetof is the offset computed by the elaborator (cparser/) */
+#define boffsetof(s,f) (int)__builtin_offsetof(struct s, f)
+
+/* szof is the size computed by the verified front-end (cfrontend/) */
+#define szof(s) (int) sizeof(struct s)
+
+/* bszof is the size computed by the elaborator (cparser/) */
+#define bszof(s) (int) sizeof(char [sizeof(struct s)])
+
/* Simple packing */
struct __packed__(1) s1 { unsigned short x; int y; double z; };
@@ -11,9 +21,12 @@ struct __packed__(1) s1 { unsigned short x; int y; double z; };
void test1(void)
{
struct s1 s1;
- printf("sizeof(struct s1) = %d\n", sizeof(struct s1));
+ printf("sizeof(struct s1) = %d\n", szof(s1));
+ printf("precomputed sizeof(struct s1) = %d\n", bszof(s1));
printf("offsetof(x) = %d, offsetof(y) = %d, offsetof(z) = %d\n",
offsetof(s1,x), offsetof(s1,y), offsetof(s1,z));
+ printf("precomputed offsetof(x) = %d, offsetof(y) = %d, offsetof(z) = %d\n",
+ boffsetof(s1,x), boffsetof(s1,y), boffsetof(s1,z));
s1.x = 123; s1.y = -456; s1.z = 3.14159;
printf("s1 = {x = %d, y = %d, z = %.5f}\n\n", s1.x, s1.y, s1.z);
}
@@ -28,10 +41,13 @@ struct s2 s2;
void test2(void)
{
- printf("sizeof(struct s2) = %d\n", sizeof(struct s2));
+ printf("sizeof(struct s2) = %d\n", szof(s2));
+ printf("precomputed sizeof(struct s2) = %d\n", bszof(s2));
printf("&s2 mod 16 = %d\n", ((int) &s2) & 0xF);
printf("offsetof(x) = %d, offsetof(y) = %d, offsetof(z) = %d\n",
offsetof(s2,x), offsetof(s2,y), offsetof(s2,z));
+ printf("precomputed offsetof(x) = %d, offsetof(y) = %d, offsetof(z) = %d\n",
+ boffsetof(s2,x), boffsetof(s2,y), boffsetof(s2,z));
s2.x = 12345; s2.y = -456; s2.z = 3.14159;
printf("s2 = {x = %d, y = %d, z = %.5f}\n\n", s2.x, s2.y, s2.z);
}
@@ -55,8 +71,10 @@ void test3(void)
{
char xx;
- printf("sizeof(struct s3) = %d\n", sizeof(struct s3));
+ printf("sizeof(struct s3) = %d\n", szof(s3));
+ printf("precomputed sizeof(struct s3) = %d\n", bszof(s3));
printf("offsetof(s) = %d\n", offsetof(s3,s));
+ printf("precomputed offsetof(s) = %d\n", boffsetof(s3,s));
s3.x = 123;
s3.y = 45678;
s3.z = 0x80000001U;
@@ -82,9 +100,13 @@ struct s4 { unsigned short x; int y; double z; };
void test4(void)
{
struct s4 s4;
- printf("sizeof(struct s4) = %d\n", sizeof(struct s4));
+
+ printf("sizeof(struct s4) = %d\n", szof(s4));
+ printf("precomputed sizeof(struct s4) = %d\n", bszof(s4));
printf("offsetof(x) = %d, offsetof(y) = %d, offsetof(z) = %d\n",
offsetof(s4,x), offsetof(s4,y), offsetof(s4,z));
+ printf("precomputed offsetof(x) = %d, offsetof(y) = %d, offsetof(z) = %d\n",
+ boffsetof(s4,x), boffsetof(s4,y), boffsetof(s4,z));
s4.x = 123; s4.y = -456; s4.z = 3.14159;
printf("s4 = {x = %d, y = %d, z = %.5f}\n\n", s4.x, s4.y, s4.z);
}
@@ -96,9 +118,13 @@ struct __attribute((packed)) s5 { unsigned short x; int y; double z; };
void test5(void)
{
struct s5 s5;
- printf("sizeof(struct s5) = %d\n", sizeof(struct s5));
+
+ printf("sizeof(struct s5) = %d\n", szof(s5));
+ printf("precomputed sizeof(struct s5) = %d\n", bszof(s5));
printf("offsetof(x) = %d, offsetof(y) = %d, offsetof(z) = %d\n",
offsetof(s5,x), offsetof(s5,y), offsetof(s5,z));
+ printf("precomputed offsetof(x) = %d, offsetof(y) = %d, offsetof(z) = %d\n",
+ boffsetof(s5,x), boffsetof(s5,y), boffsetof(s5,z));
s5.x = 123; s5.y = -456; s5.z = 3.14159;
printf("s5 = {x = %d, y = %d, z = %.5f}\n\n", s5.x, s5.y, s5.z);
}
@@ -110,9 +136,13 @@ struct s6 { unsigned short x; int y; double z; } __attribute((packed)) const s6
void test6(void)
{
struct s6 s62;
- printf("sizeof(struct s6) = %d\n", sizeof(struct s6));
+
+ printf("sizeof(struct s6) = %d\n", szof(s6));
+ printf("precomputed sizeof(struct s6) = %d\n", bszof(s6));
printf("offsetof(x) = %d, offsetof(y) = %d, offsetof(z) = %d\n",
offsetof(s6,x), offsetof(s6,y), offsetof(s6,z));
+ printf("precomputed offsetof(x) = %d, offsetof(y) = %d, offsetof(z) = %d\n",
+ boffsetof(s6,x), boffsetof(s6,y), boffsetof(s6,z));
s62.x = 123; s62.y = -456; s62.z = 3.14159;
printf("s62 = {x = %d, y = %d, z = %.5f}\n\n", s62.x, s62.y, s62.z);
}
diff --git a/x86/Asm.v b/x86/Asm.v
index 8b873e48..dfa2a88a 100644
--- a/x86/Asm.v
+++ b/x86/Asm.v
@@ -284,6 +284,7 @@ Inductive instruction: Type :=
| Pmovsb
| Pmovsw
| Pmovw_rm (rd: ireg) (ad: addrmode)
+ | Pnop
| Prep_movsl
| Psbbl_rr (rd: ireg) (r2: ireg)
| Psqrtsd (rd: freg) (r1: freg)
@@ -1001,6 +1002,7 @@ Definition exec_instr (f: function) (i: instruction) (rs: regset) (m: mem) : out
| Pmovsb
| Pmovsw
| Pmovw_rm _ _
+ | Pnop
| Prep_movsl
| Psbbl_rr _ _
| Psqrtsd _ _
@@ -1047,6 +1049,15 @@ Definition preg_of (r: mreg) : preg :=
| FP0 => ST0
end.
+(** Undefine all registers except SP and callee-save registers *)
+
+Definition undef_caller_save_regs (rs: regset) : regset :=
+ fun r =>
+ if preg_eq r SP
+ || In_dec preg_eq r (List.map preg_of (List.filter is_callee_save all_mregs))
+ then rs r
+ else Vundef.
+
(** Extract the values of the arguments of an external call.
We exploit the calling conventions from module [Conventions], except that
we use machine registers instead of locations. *)
@@ -1106,7 +1117,7 @@ Inductive step: state -> trace -> state -> Prop :=
Genv.find_funct_ptr ge b = Some (External ef) ->
extcall_arguments rs m (ef_sig ef) args ->
external_call ef ge args m t res m' ->
- rs' = (set_pair (loc_external_result (ef_sig ef)) res rs) #PC <- (rs RA) ->
+ rs' = (set_pair (loc_external_result (ef_sig ef)) res (undef_caller_save_regs rs)) #PC <- (rs RA) ->
step (State rs m) t (State rs' m').
End RELSEM.
diff --git a/x86/Asmexpand.ml b/x86/Asmexpand.ml
index 9927d2fb..16426ce3 100644
--- a/x86/Asmexpand.ml
+++ b/x86/Asmexpand.ml
@@ -331,9 +331,17 @@ let expand_builtin_inline name args res =
if a1 <> res then
emit (Pmov_rr (res,a1));
emit (Pbswap16 res)
- | ("__builtin_clz"|"__builtin_clzl"), [BA(IR a1)], BR(IR res) ->
+ | "__builtin_clz", [BA(IR a1)], BR(IR res) ->
emit (Pbsrl (res,a1));
emit (Pxorl_ri(res,coqint_of_camlint 31l))
+ | "__builtin_clzl", [BA(IR a1)], BR(IR res) ->
+ if not(Archi.ptr64) then begin
+ emit (Pbsrl (res,a1));
+ emit (Pxorl_ri(res,coqint_of_camlint 31l))
+ end else begin
+ emit (Pbsrq (res,a1));
+ emit (Pxorl_ri(res,coqint_of_camlint 63l))
+ end
| "__builtin_clzll", [BA(IR a1)], BR(IR res) ->
emit (Pbsrq (res,a1));
emit (Pxorl_ri(res,coqint_of_camlint 63l))
@@ -349,8 +357,13 @@ let expand_builtin_inline name args res =
emit (Pbsrl(res, al));
emit (Pxorl_ri(res, coqint_of_camlint 63l));
emit (Plabel lbl2)
- | ("__builtin_ctz" | "__builtin_ctzl"), [BA(IR a1)], BR(IR res) ->
+ | "__builtin_ctz", [BA(IR a1)], BR(IR res) ->
emit (Pbsfl (res,a1))
+ | "__builtin_ctzl", [BA(IR a1)], BR(IR res) ->
+ if not(Archi.ptr64) then
+ emit (Pbsfl (res,a1))
+ else
+ emit (Pbsfq (res,a1))
| "__builtin_ctzll", [BA(IR a1)], BR(IR res) ->
emit (Pbsfq (res,a1))
| "__builtin_ctzll", [BA_splitlong(BA (IR ah), BA (IR al))], BR(IR res) ->
@@ -462,7 +475,7 @@ let expand_builtin_inline name args res =
()
(* no operation *)
| "__builtin_nop", [], _ ->
- emit (Pmov_rr (RAX,RAX))
+ emit Pnop
(* Catch-all *)
| _ ->
raise (Error ("unrecognized builtin " ^ name))
@@ -619,10 +632,7 @@ let preg_to_dwarf = function
let expand_function id fn =
try
set_current_function fn;
- if !Clflags.option_g then
- expand_debug id (int_reg_to_dwarf RSP) preg_to_dwarf expand_instruction fn.fn_code
- else
- List.iter expand_instruction fn.fn_code;
+ expand id (int_reg_to_dwarf RSP) preg_to_dwarf expand_instruction fn.fn_code;
Errors.OK (get_current_function ())
with Error s ->
Errors.Error (Errors.msg (coqstring_of_camlstring s))
diff --git a/x86/Asmgenproof.v b/x86/Asmgenproof.v
index 38816fd2..3aa87a4c 100644
--- a/x86/Asmgenproof.v
+++ b/x86/Asmgenproof.v
@@ -861,8 +861,8 @@ Transparent destroyed_at_function_entry.
apply plus_one. eapply exec_step_external; eauto.
eapply external_call_symbols_preserved; eauto. apply senv_preserved.
econstructor; eauto.
- unfold loc_external_result.
- apply agree_set_other; auto. apply agree_set_pair; auto.
+ unfold loc_external_result. apply agree_set_other; auto. apply agree_set_pair; auto.
+ apply agree_undef_caller_save_regs; auto.
- (* return *)
inv STACKS. simpl in *.
diff --git a/x86/TargetPrinter.ml b/x86/TargetPrinter.ml
index 1bb8c226..3ac2f36e 100644
--- a/x86/TargetPrinter.ml
+++ b/x86/TargetPrinter.ml
@@ -791,6 +791,8 @@ module Target(System: SYSTEM):TARGET =
fprintf oc " movsw\n";
| Pmovw_rm (rd, a) ->
fprintf oc " movw %a, %a\n" addressing a ireg16 rd
+ | Pnop ->
+ fprintf oc " nop\n"
| Prep_movsl ->
fprintf oc " rep movsl\n"
| Psbbl_rr (res,a1) ->
@@ -814,7 +816,7 @@ module Target(System: SYSTEM):TARGET =
| 1 -> let annot = annot_text preg_annot "esp" (camlstring_of_coqstring txt) args in
fprintf oc "%s annotation: %S\n" comment annot
| 2 -> let lbl = new_label () in
- fprintf oc "%a: \n" label lbl;
+ fprintf oc "%a:\n" label lbl;
let sp = if Archi.ptr64 then "rsp" else "esp" in
add_ais_annot lbl preg_ais_annot sp (camlstring_of_coqstring txt) args
| _ -> assert false