[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] pkl: add support for integral unions
From: |
Jose E. Marchesi |
Subject: |
Re: [PATCH] pkl: add support for integral unions |
Date: |
Sat, 24 Sep 2022 16:50:38 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
Hi Mohammad.
Thanks for the patch.
> 2022-09-24 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
>
> * libpoke/pkl-tab.y (tokens): s/token/%token/.
> * libpoke/pkl-typify.c (pkl_typify1_ps_type_struct): Handle integral
> unions.
> * libpoke/pkl-gen.c (pkl_gen_pr_type_struct): Likewise.
> (pkl_gen_pr_decl): Likewise.
> (pkl_gen_pr_cast): In cast from an integral type to struct type,
> add a cast to ITYPE of the struct.
> * libpoke/pkl-gen.pks (RAS_FUNCTION_UNION_INTEGRATOR): New function.
> (RAS_FUNCTION_UNION_DEINTEGRATOR): Likewise.
> (RAS_FUNCTION_STRUCT_INTEGRATOR): Add assertion.
> (RAS_FUNCTION_STRUCT_DEINTEGRATOR): Likewise.
> * libpoke/pvm.jitter (rule dup-drop): New rule.
> (rule dup-nip): Likewise.
> * doc/poke.texi (Integral Unions): Add new section.
> * testsuite/poke.pkl/int-union-1.pk: New test.
> * testsuite/poke.pkl/int-union-2.pk: Likewise.
> * testsuite/poke.pkl/int-union-3.pk: Likewise.
> * testsuite/poke.pkl/int-union-4.pk: Likewise.
> * testsuite/poke.pkl/int-union-5.pk: Likewise.
> * testsuite/poke.pkl/int-union-6.pk: Likewise.
> * testsuite/poke.pkl/int-union-7.pk: Likewise.
> * testsuite/poke.pkl/int-union-8.pk: Likewise.
> * testsuite/poke.pkl/int-union-9.pk: Likewise.
> * testsuite/poke.pkl/int-union-10.pk: Likewise.
> * testsuite/poke.pkl/int-union-11.pk: Likewise.
> * testsuite/poke.pkl/int-union-12.pk: Likewise.
> * testsuite/poke.pkl/int-union-13.pk: Likewise.
> * testsuite/poke.pkl/int-union-14.pk: Likewise.
> * testsuite/poke.pkl/int-union-15.pk: Likewise.
> * testsuite/poke.pkl/int-union-16.pk: Likewise.
> * testsuite/poke.pkl/int-union-17.pk: Likewise.
> * testsuite/poke.pkl/int-union-18.pk: Likewise.
> * testsuite/poke.pkl/int-union-19.pk: Likewise.
> * testsuite/poke.pkl/int-union-20.pk: Likewise.
> * testsuite/poke.pkl/int-union-21.pk: Likewise.
> * testsuite/poke.pkl/int-union-22.pk: Likewise.
> * testsuite/poke.pkl/int-union-23.pk: Likewise.
> * testsuite/poke.pkl/int-union-24.pk: Likewise.
> * testsuite/poke.pkl/int-union-25.pk: Likewise.
> * testsuite/poke.pkl/int-union-26.pk: Likewise.
> * testsuite/poke.pkl/int-union-27.pk: Likewise.
> * testsuite/poke.pkl/int-union-28.pk: Likewise.
> * testsuite/poke.pkl/int-union-29.pk: Likewise.
> * testsuite/poke.pkl/int-union-30.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-1.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-2.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-3.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-4.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-5.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-6.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-7.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-8.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-9.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-10.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-11.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-12.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-13.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-14.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-15.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-16.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-17.pk: Likewise.
> * testsuite/poke.pkl/int-union-type-diag-18.pk: Likewise.
> * testsuite/poke.map/maps-int-union-1.pk: Likewise
> * testsuite/poke.map/maps-int-union-2.pk: Likewise
> * testsuite/poke.map/maps-int-union-3.pk: Likewise
> * testsuite/poke.map/maps-int-union-4.pk: Likewise
> * testsuite/poke.map/maps-int-union-5.pk: Likewise
> * testsuite/Makefile.am (EXTRA_DIST): Update.
> ---
>
> Hi Jose.
>
> Please make sure that everything is right in `union_deintegrator` :)
>
>
> Regards,
> Mohammad-Reza
>
>
> ChangeLog | 70 ++++++
> doc/poke.texi | 45 ++++
> libpoke/pkl-gen.c | 39 +++-
> libpoke/pkl-gen.pks | 203 ++++++++++++++++++
> libpoke/pkl-tab.y | 2 +-
> libpoke/pkl-typify.c | 56 +++--
> libpoke/pvm.jitter | 10 +
> testsuite/Makefile.am | 54 ++++-
> testsuite/poke.map/maps-int-union-1.pk | 17 ++
> testsuite/poke.map/maps-int-union-2.pk | 17 ++
> testsuite/poke.map/maps-int-union-3.pk | 23 ++
> testsuite/poke.map/maps-int-union-4.pk | 23 ++
> testsuite/poke.map/maps-int-union-5.pk | 23 ++
> testsuite/poke.pkl/int-struct-type-diag-11.pk | 6 +-
> testsuite/poke.pkl/int-struct-type-diag-16.pk | 7 -
> testsuite/poke.pkl/int-struct-type-diag-17.pk | 8 -
> testsuite/poke.pkl/int-union-1.pk | 13 ++
> testsuite/poke.pkl/int-union-10.pk | 12 ++
> testsuite/poke.pkl/int-union-11.pk | 12 ++
> testsuite/poke.pkl/int-union-12.pk | 13 ++
> testsuite/poke.pkl/int-union-13.pk | 24 +++
> testsuite/poke.pkl/int-union-14.pk | 20 ++
> testsuite/poke.pkl/int-union-15.pk | 21 ++
> testsuite/poke.pkl/int-union-16.pk | 20 ++
> testsuite/poke.pkl/int-union-17.pk | 29 +++
> testsuite/poke.pkl/int-union-18.pk | 20 ++
> testsuite/poke.pkl/int-union-19.pk | 20 ++
> testsuite/poke.pkl/int-union-2.pk | 10 +
> testsuite/poke.pkl/int-union-20.pk | 16 ++
> testsuite/poke.pkl/int-union-21.pk | 16 ++
> testsuite/poke.pkl/int-union-22.pk | 14 ++
> testsuite/poke.pkl/int-union-23.pk | 14 ++
> testsuite/poke.pkl/int-union-24.pk | 14 ++
> testsuite/poke.pkl/int-union-25.pk | 23 ++
> testsuite/poke.pkl/int-union-26.pk | 20 ++
> testsuite/poke.pkl/int-union-27.pk | 23 ++
> testsuite/poke.pkl/int-union-28.pk | 23 ++
> testsuite/poke.pkl/int-union-29.pk | 24 +++
> testsuite/poke.pkl/int-union-3.pk | 4 +
> testsuite/poke.pkl/int-union-30.pk | 26 +++
> testsuite/poke.pkl/int-union-4.pk | 9 +
> testsuite/poke.pkl/int-union-5.pk | 13 ++
> testsuite/poke.pkl/int-union-6.pk | 10 +
> testsuite/poke.pkl/int-union-7.pk | 6 +
> testsuite/poke.pkl/int-union-8.pk | 9 +
> testsuite/poke.pkl/int-union-9.pk | 19 ++
> testsuite/poke.pkl/int-union-type-diag-1.pk | 6 +
> testsuite/poke.pkl/int-union-type-diag-10.pk | 12 ++
> testsuite/poke.pkl/int-union-type-diag-11.pk | 6 +
> testsuite/poke.pkl/int-union-type-diag-12.pk | 8 +
> testsuite/poke.pkl/int-union-type-diag-13.pk | 8 +
> testsuite/poke.pkl/int-union-type-diag-14.pk | 6 +
> testsuite/poke.pkl/int-union-type-diag-15.pk | 13 ++
> testsuite/poke.pkl/int-union-type-diag-16.pk | 10 +
> testsuite/poke.pkl/int-union-type-diag-17.pk | 8 +
> testsuite/poke.pkl/int-union-type-diag-2.pk | 6 +
> testsuite/poke.pkl/int-union-type-diag-3.pk | 7 +
> testsuite/poke.pkl/int-union-type-diag-4.pk | 8 +
> testsuite/poke.pkl/int-union-type-diag-5.pk | 7 +
> testsuite/poke.pkl/int-union-type-diag-6.pk | 6 +
> testsuite/poke.pkl/int-union-type-diag-7.pk | 8 +
> testsuite/poke.pkl/int-union-type-diag-8.pk | 7 +
> testsuite/poke.pkl/int-union-type-diag-9.pk | 14 ++
> 63 files changed, 1192 insertions(+), 48 deletions(-)
> create mode 100644 testsuite/poke.map/maps-int-union-1.pk
> create mode 100644 testsuite/poke.map/maps-int-union-2.pk
> create mode 100644 testsuite/poke.map/maps-int-union-3.pk
> create mode 100644 testsuite/poke.map/maps-int-union-4.pk
> create mode 100644 testsuite/poke.map/maps-int-union-5.pk
> delete mode 100644 testsuite/poke.pkl/int-struct-type-diag-16.pk
> delete mode 100644 testsuite/poke.pkl/int-struct-type-diag-17.pk
> create mode 100644 testsuite/poke.pkl/int-union-1.pk
> create mode 100644 testsuite/poke.pkl/int-union-10.pk
> create mode 100644 testsuite/poke.pkl/int-union-11.pk
> create mode 100644 testsuite/poke.pkl/int-union-12.pk
> create mode 100644 testsuite/poke.pkl/int-union-13.pk
> create mode 100644 testsuite/poke.pkl/int-union-14.pk
> create mode 100644 testsuite/poke.pkl/int-union-15.pk
> create mode 100644 testsuite/poke.pkl/int-union-16.pk
> create mode 100644 testsuite/poke.pkl/int-union-17.pk
> create mode 100644 testsuite/poke.pkl/int-union-18.pk
> create mode 100644 testsuite/poke.pkl/int-union-19.pk
> create mode 100644 testsuite/poke.pkl/int-union-2.pk
> create mode 100644 testsuite/poke.pkl/int-union-20.pk
> create mode 100644 testsuite/poke.pkl/int-union-21.pk
> create mode 100644 testsuite/poke.pkl/int-union-22.pk
> create mode 100644 testsuite/poke.pkl/int-union-23.pk
> create mode 100644 testsuite/poke.pkl/int-union-24.pk
> create mode 100644 testsuite/poke.pkl/int-union-25.pk
> create mode 100644 testsuite/poke.pkl/int-union-26.pk
> create mode 100644 testsuite/poke.pkl/int-union-27.pk
> create mode 100644 testsuite/poke.pkl/int-union-28.pk
> create mode 100644 testsuite/poke.pkl/int-union-29.pk
> create mode 100644 testsuite/poke.pkl/int-union-3.pk
> create mode 100644 testsuite/poke.pkl/int-union-30.pk
> create mode 100644 testsuite/poke.pkl/int-union-4.pk
> create mode 100644 testsuite/poke.pkl/int-union-5.pk
> create mode 100644 testsuite/poke.pkl/int-union-6.pk
> create mode 100644 testsuite/poke.pkl/int-union-7.pk
> create mode 100644 testsuite/poke.pkl/int-union-8.pk
> create mode 100644 testsuite/poke.pkl/int-union-9.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-1.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-10.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-11.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-12.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-13.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-14.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-15.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-16.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-17.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-2.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-3.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-4.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-5.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-6.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-7.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-8.pk
> create mode 100644 testsuite/poke.pkl/int-union-type-diag-9.pk
>
> diff --git a/ChangeLog b/ChangeLog
> index a2a1d027..7fd4baa4 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,73 @@
> +2022-09-24 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
> +
> + * libpoke/pkl-tab.y (tokens): s/token/%token/.
> + * libpoke/pkl-typify.c (pkl_typify1_ps_type_struct): Handle integral
> unions.
> + * libpoke/pkl-gen.c (pkl_gen_pr_type_struct): Likewise.
> + (pkl_gen_pr_decl): Likewise.
> + (pkl_gen_pr_cast): In cast from an integral type to struct type,
> + add a cast to ITYPE of the struct.
> + * libpoke/pkl-gen.pks (RAS_FUNCTION_UNION_INTEGRATOR): New function.
> + (RAS_FUNCTION_UNION_DEINTEGRATOR): Likewise.
> + (RAS_FUNCTION_STRUCT_INTEGRATOR): Add assertion.
> + (RAS_FUNCTION_STRUCT_DEINTEGRATOR): Likewise.
> + * libpoke/pvm.jitter (rule dup-drop): New rule.
> + (rule dup-nip): Likewise.
> + * doc/poke.texi (Integral Unions): Add new section.
> + * testsuite/poke.pkl/int-union-1.pk: New test.
> + * testsuite/poke.pkl/int-union-2.pk: Likewise.
> + * testsuite/poke.pkl/int-union-3.pk: Likewise.
> + * testsuite/poke.pkl/int-union-4.pk: Likewise.
> + * testsuite/poke.pkl/int-union-5.pk: Likewise.
> + * testsuite/poke.pkl/int-union-6.pk: Likewise.
> + * testsuite/poke.pkl/int-union-7.pk: Likewise.
> + * testsuite/poke.pkl/int-union-8.pk: Likewise.
> + * testsuite/poke.pkl/int-union-9.pk: Likewise.
> + * testsuite/poke.pkl/int-union-10.pk: Likewise.
> + * testsuite/poke.pkl/int-union-11.pk: Likewise.
> + * testsuite/poke.pkl/int-union-12.pk: Likewise.
> + * testsuite/poke.pkl/int-union-13.pk: Likewise.
> + * testsuite/poke.pkl/int-union-14.pk: Likewise.
> + * testsuite/poke.pkl/int-union-15.pk: Likewise.
> + * testsuite/poke.pkl/int-union-16.pk: Likewise.
> + * testsuite/poke.pkl/int-union-17.pk: Likewise.
> + * testsuite/poke.pkl/int-union-18.pk: Likewise.
> + * testsuite/poke.pkl/int-union-19.pk: Likewise.
> + * testsuite/poke.pkl/int-union-20.pk: Likewise.
> + * testsuite/poke.pkl/int-union-21.pk: Likewise.
> + * testsuite/poke.pkl/int-union-22.pk: Likewise.
> + * testsuite/poke.pkl/int-union-23.pk: Likewise.
> + * testsuite/poke.pkl/int-union-24.pk: Likewise.
> + * testsuite/poke.pkl/int-union-25.pk: Likewise.
> + * testsuite/poke.pkl/int-union-26.pk: Likewise.
> + * testsuite/poke.pkl/int-union-27.pk: Likewise.
> + * testsuite/poke.pkl/int-union-28.pk: Likewise.
> + * testsuite/poke.pkl/int-union-29.pk: Likewise.
> + * testsuite/poke.pkl/int-union-30.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-1.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-2.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-3.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-4.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-5.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-6.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-7.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-8.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-9.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-10.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-11.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-12.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-13.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-14.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-15.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-16.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-17.pk: Likewise.
> + * testsuite/poke.pkl/int-union-type-diag-18.pk: Likewise.
> + * testsuite/poke.map/maps-int-union-1.pk: Likewise
> + * testsuite/poke.map/maps-int-union-2.pk: Likewise
> + * testsuite/poke.map/maps-int-union-3.pk: Likewise
> + * testsuite/poke.map/maps-int-union-4.pk: Likewise
> + * testsuite/poke.map/maps-int-union-5.pk: Likewise
> + * testsuite/Makefile.am (EXTRA_DIST): Update.
> +
> 2022-09-24 Jose E. Marchesi <jemarch@gnu.org>
>
> BZ 27481
> diff --git a/doc/poke.texi b/doc/poke.texi
> index a36797b9..7f6e156a 100644
> --- a/doc/poke.texi
> +++ b/doc/poke.texi
> @@ -10766,6 +10766,7 @@ They contain heterogeneous collections of values.
> * Integral Structs:: Composite data stored in integers.
> * Unions:: Dealing with conditional data.
> * Union Constructors:: Constructing union values.
> +* Integral Unions:: Variants of composite data stored in integers.
> * Optional Fields:: Fields that may or may not exist.
> * Casting Structs:: Converting structs from one type to another.
> * Declarations in Structs:: Declaring stuff within a struct.
> @@ -11711,6 +11712,50 @@ Packet @{
> Therefore the alternative @code{b} is considered invalid (it has to be
> bigger than 0) and @code{k} is chosen instead.
>
> +@node Integral Unions
> +@subsection Integral Unions
> +@cindex integral unions
> +
> +Integral unions are useful to cover cases where we have variants of
> +data encoded in integers. One example could be CPU instructions
> +encoded as 16-bit or 32-bit numbers.
> +
> +@example
> +type InstructionFormat_1 =
> + struct uint<32>
> + @{
> + uint<20> imm31_12;
> + uint<5> rd;
> + uint<7> opcode : valid_opcode_for_format_1 (opcode);
> + @};
> +
> +type InstructionFormat_2 =
> + struct uint<32>
> + @{
> + uint<7> funct7;
> + uint<5> rs2;
> + uint<5> rs1;
> + uint<3> funct3;
> + uint<5> rd;
> + uint<7> opcode : valid_opcode_for_format_2 (opcode);
> + @};
> +
> +type Instruction =
> + union uint<32>
> + @{
> + InstructionFormat_1 f1;
> + InstructionFomrat_2 f2;
> + @};
> +@end example
> +
> +
> +Like integral structs, integral unions can be casted to/from integers;
> +e.g., @code{3211411U as Instruction} will create an @code{Instruction}
> +union.
> +
> +Like integral structs, integral unions can have fields of the following
> +types: integral, offset, integral struct/union.
> +
> @node Optional Fields
> @subsection Optional Fields
> @cindex struct fields
> diff --git a/libpoke/pkl-gen.c b/libpoke/pkl-gen.c
> index 971b8e3c..ba0cd818 100644
> --- a/libpoke/pkl-gen.c
> +++ b/libpoke/pkl-gen.c
> @@ -312,10 +312,14 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_decl)
> pvm_val integrator_closure;
>
> PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_INTEGRATOR);
> - RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure,
> - type_struct);
> - PKL_GEN_POP_CONTEXT;
> + if (PKL_AST_TYPE_S_UNION_P (type_struct))
> + RAS_FUNCTION_UNION_INTEGRATOR (integrator_closure,
> + type_struct);
> + else
> + RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure,
> + type_struct);
> PKL_AST_TYPE_S_INTEGRATOR (type_struct) =
> integrator_closure;
> + PKL_GEN_POP_CONTEXT;
> }
>
> pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
> @@ -328,8 +332,12 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_decl)
> pvm_val deintegrator_closure;
>
> PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
> - RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure,
> - type_struct);
> + if (PKL_AST_TYPE_S_UNION_P (type_struct))
> + RAS_FUNCTION_UNION_DEINTEGRATOR (deintegrator_closure,
> + type_struct);
> + else
> + RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure,
> + type_struct);
> PKL_GEN_POP_CONTEXT;
> PKL_AST_TYPE_S_DEINTEGRATOR (type_struct) =
> deintegrator_closure;
> }
> @@ -2445,6 +2453,13 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_cast)
> else if (PKL_AST_TYPE_CODE (to_type) == PKL_TYPE_STRUCT
> && PKL_AST_TYPE_CODE (from_type) == PKL_TYPE_INTEGRAL)
> {
> + pkl_ast_node itype = PKL_AST_TYPE_S_ITYPE (to_type);
> +
> + /* This is guaranteed as per typify. */
> + assert (itype);
> +
> + pkl_asm_insn (pasm, PKL_INSN_NTON, from_type, itype);
> + pkl_asm_insn (pasm, PKL_INSN_NIP);
> PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
> PKL_PASS_SUBPASS (to_type);
> PKL_GEN_POP_CONTEXT;
> @@ -3859,7 +3874,12 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_struct)
> pvm_val integrator_closure = PKL_AST_TYPE_S_INTEGRATOR (type_struct);
>
> if (integrator_closure == PVM_NULL)
> - RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure, type_struct);
> + {
> + if (PKL_AST_TYPE_S_UNION_P (type_struct))
> + RAS_FUNCTION_UNION_INTEGRATOR (integrator_closure, type_struct);
> + else
> + RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure, type_struct);
> + }
> pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, integrator_closure);
> if (!PKL_AST_TYPE_NAME (type_struct))
> pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
> @@ -3873,7 +3893,12 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_struct)
> pvm_val deintegrator_closure = PKL_AST_TYPE_S_DEINTEGRATOR
> (type_struct);
>
> if (deintegrator_closure == PVM_NULL)
> - RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure, type_struct);
> + {
> + if (PKL_AST_TYPE_S_UNION_P (type_struct))
> + RAS_FUNCTION_UNION_DEINTEGRATOR (deintegrator_closure,
> type_struct);
> + else
> + RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure,
> type_struct);
> + }
> pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, deintegrator_closure);
> if (!PKL_AST_TYPE_NAME (type_struct))
> pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
> diff --git a/libpoke/pkl-gen.pks b/libpoke/pkl-gen.pks
> index a60ce55a..ccb8694f 100644
> --- a/libpoke/pkl-gen.pks
> +++ b/libpoke/pkl-gen.pks
> @@ -2060,6 +2060,7 @@
> ;;; passed in the stack.
>
> .function struct_integrator @type_struct
> + .c assert (!PKL_AST_TYPE_S_UNION_P (@type_struct));
Please get rid of this assert. It is not really needed.
> prolog
> pushf 2
> regvar $sct ; Argument
> @@ -2104,6 +2105,77 @@
> return
> .end
>
> +;;; RAS_FUNCTION_UNION_INTEGRATOR @type_struct
> +;;; ( VAL -- IVAL )
> +;;;
> +;;; Assemble a function that, given an integral union, returns
> +;;; its integral value.
> +;;;
> +;;; Macro-arguments:
> +;;;
> +;;; @type_struct is a pkl_ast_node with the type of the struct
> +;;; passed in the stack.
> +
> + .function union_integrator @type_struct
> + .c assert (PKL_AST_TYPE_S_UNION_P (@type_struct));
> + prolog
> + pushf 0
> + .let @itype = PKL_AST_TYPE_S_ITYPE (@type_struct)
> + .let @field
> + .c for (@field = PKL_AST_TYPE_S_ELEMS (@type_struct);
> + .c @field;
> + .c @field = PKL_AST_CHAIN (@field))
> + .c {
> + .c if (PKL_AST_CODE (@field) != PKL_AST_STRUCT_TYPE_FIELD)
> + .c continue;
> + .label .alternative_failed
> + .let @field_name = PKL_AST_STRUCT_TYPE_FIELD_NAME (@field)
> + .let #field_name_str \
> + = pvm_make_string (PKL_AST_IDENTIFIER_POINTER (@field_name))
> + push PVM_E_ELEM ; SCT EXC
> + pushe .alternative_failed ; SCT
> + ;; Note anonymous members are not allowed in unions.
> + push #field_name_str ; SCT FNAME
> + sref ; SCT FNAME VAL
> + pope
> + nip2 ; VAL
> + .let @field_type = PKL_AST_STRUCT_TYPE_FIELD_TYPE (@field)
> + .c if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_INTEGRAL)
> + .c {
> + nton @field_type, @itype ; NUM IVAL
> + .c }
> + .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET)
> + .c {
> + .let @btype = PKL_AST_TYPE_O_BASE_TYPE (@field_type)
> + ogetm ; OFF MAG
> + nton @btype, @itype ; OFF MAG IVAL
> + nip ; OFF IVAL
> + .c }
> + .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
> + .c {
> + .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_INTEGRATOR);
> + .c PKL_PASS_SUBPASS (@field);
> + .c PKL_GEN_POP_CONTEXT;
> + .let @field_itype = PKL_AST_TYPE_S_ITYPE (@field_type)
> + nton @field_itype, @itype ; SCT IVAL
> + .c }
> + .c else
> + .c {
> + .c assert (0 && "unreachable reached!");
> + .c }
Likewise. Do like in struct_field_inserter and be confident in the
compiler :)
BTW, I guess you are not using struct_field_inserter for performance
reasons. A comment in that regard would be useful to have in case some
reader wonders about it.
> + ; VAL IVAL
> + nip ; IVAL
> + ba .done
> +.alternative_failed:
> + ; SCT EXC
> + drop
> + .c }
> + ;; Impossible to reach here!
> +.done:
> + popf 1
> + return
> + .end
> +
> ;;; RAS_MACRO_DEINT_EXTRACT_FIELD_VALUE @uint64_type @itype @field_type
> #bit_offset
> ;;; ( IVAL -- EVAL )
> ;;;
> @@ -2167,6 +2239,7 @@
> ;;; which convert the integer.
>
> .function struct_deintegrator @type_struct
> + .c assert (!PKL_AST_TYPE_S_UNION_P (@type_struct));
> prolog
> pushf 2
> ;; Convert the value to deintegrate to an ulong<64> to ease
> @@ -2271,6 +2344,136 @@
> return
> .end
>
> +;;; RAS_FUNCTION_UNION_DEINTEGRATOR @type_struct
> +;;; ( IVAL -- VAL )
> +;;;
> +;;; Assemble a function that, given an integral value, transforms it
> +;;; into an equivalent integral union with the given type. The
> +;;; integral value in the stack should be the same as the integral
> +;;; type of TYPE_STRUCT.
> +;;;
> +;;; Macro-arguments:
> +;;;
> +;;; @type_struct is a pkl_ast_node with the type of the union to
> +;;; which convert the integer.
> +
> + .function union_deintegrator @type_struct
> + .c assert (PKL_AST_TYPE_S_UNION_P (@type_struct));
> + prolog
> + pushf 0
> + .let @itype = PKL_AST_TYPE_S_ITYPE (@type_struct)
> + .let @field
> + .c for (@field = PKL_AST_TYPE_S_ELEMS (@type_struct);
> + .c @field;
> + .c @field = PKL_AST_CHAIN (@field))
> + .c {
> + .label .alternative_failed
> + .label .construction_failed
> + .label .deintegration_failed
> + .c if (PKL_AST_CODE (@field) != PKL_AST_STRUCT_TYPE_FIELD)
> + .c {
> + .c continue;
> + .c }
> + .let @field_type = PKL_AST_STRUCT_TYPE_FIELD_TYPE (@field)
> + dup ; IVAL IVAL
> + .c if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_INTEGRAL)
> + .c {
> + ; IVAL NUM
> + nton @itype, @field_type
> + nip ; IVAL NUM
> + .c }
> + .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET)
> + .c {
> + ; IVAL MAG
> + .let @btype = PKL_AST_TYPE_O_BASE_TYPE (@field_type)
> + nton @itype, @btype
> + nip ; IVAL NUM
> + .let @ounit = PKL_AST_TYPE_O_UNIT (@field_type)
> + .let #unit = pvm_make_ulong (PKL_AST_INTEGER_VALUE (@ounit), 64)
> + push #unit ; IVAL MAG UNIT
> + mko ; IVAL OFF
> + .c }
> + .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
> + .c {
> + push PVM_E_GENERIC
> + pushe .deintegration_failed
> + .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
> + .c PKL_PASS_SUBPASS (@field_type);
> + .c PKL_GEN_POP_CONTEXT;
> + ; IVAL SCT
> + pope
> + .c }
> + ;; Create a PVM type for field type
> + .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_TYPE);
> + .c PKL_PASS_SUBPASS (@field_type);
> + .c PKL_GEN_POP_CONTEXT;
> + tor ; IVAL VAL [TYP]
> + tor ; IVAL [TYP VAL]
> + ;; Let's create the PVM struct from which final union will be
> + ;; constructed.
> + .let @field_name = PKL_AST_STRUCT_TYPE_FIELD_NAME (@field)
> + .let #field_name_str \
> + = pvm_make_string (PKL_AST_IDENTIFIER_POINTER (@field_name))
> + push null ; ... OFF
> + push null ; ... OFF OFF
> + push #field_name_str ; ... OFF OFF STR
> + fromr ; ... OFF OFF STR VAL
> + push ulong<64>0 ; ... OFF OFF STR VAL NMETH
> + push ulong<64>1 ; ... OFF OFF STR VAL NMETH NFIELD
> + ;; Now we have to create the PVM type for struct
> + push #field_name_str ; ... OFF OFF STR VAL NMETH NFIELD STR
> + fromr ; ... OFF OFF STR VAL NMETH NFIELD STR TYP
> + push ulong<64>1 ; ... OFF OFF STR VAL NMETH NFIELD STR TYP
> NFIELD
> + push null ; ... OFF OFF STR VAL NMETH NFIELD STR TYP
> NFIELD SNAME
> + mktysct ; ... OFF OFF STR VAL NMETH NFIELD TYP
> + mksct ; IVAL SCT
> + push PVM_E_GENERIC
> + pushe .construction_failed
> + .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_CONSTRUCTOR);
> + .c PKL_PASS_SUBPASS (@type_struct);
> + .c PKL_GEN_POP_CONTEXT;
> + pope
> + ba .done
> +.deintegration_failed:
> + ;; HACK
> + ;; struct_deintegrator leaves two items on stack (0UL and EXC),
> + ;; instead of one item (EXC).
> + drop
> + ba .alternative_failed
> +.construction_failed:
> + ;; HACK
> + ;; struct_constructor leaves two items on stack (0UL and EXC),
> + ;; instead of one item (EXC).
> + drop
Are you sure this is the case? Isn't that 0UL yours?
I am asking because in pkl_gen_pr_cast the struct deintegrator is used
like:
else if (PKL_AST_TYPE_CODE (to_type) == PKL_TYPE_STRUCT
&& PKL_AST_TYPE_CODE (from_type) == PKL_TYPE_INTEGRAL)
{
PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
PKL_PASS_SUBPASS (to_type);
PKL_GEN_POP_CONTEXT;
}
And the result of the cast is expected to be just one element in the
stack. Since that works, I am wondering what is going on ;)
> +.alternative_failed:
> + ; IVAL EXC
> + drop ; IVAL
> + .c }
> + ; IVAL
> + drop
> + push PVM_E_CONSTRAINT
> + push "msg"
> + .let @uname = PKL_AST_TYPE_NAME (@type_struct)
> + .c if (@uname)
> + .c {
> + .c char *msg = pk_str_concat ("no valid alternative found for union ", \
> + PKL_AST_IDENTIFIER_POINTER (@uname),
> NULL);
> + .let #msg = pvm_make_string (msg)
> + .c free (msg);
> + push #msg
> + .c }
> + .c else
> + .c {
> + push "no valid alternative found for union"
> + .c }
> + sset
> + raise
> +.done:
> + nip
> + popf 1
> + return
> + .end
> +
> ;;; RAS_MACRO_COMPLEX_LMAP @type #writer
> ;;; ( VAL IOS BOFF -- )
> ;;;
> diff --git a/libpoke/pkl-tab.y b/libpoke/pkl-tab.y
> index 04b1c0a7..b8d9b5ea 100644
> --- a/libpoke/pkl-tab.y
> +++ b/libpoke/pkl-tab.y
> @@ -390,7 +390,7 @@ load_module (struct pkl_parser *parser,
> %token ENUM _("keyword `enum'")
> %token <integer> PINNED _("keyword `pinned'")
> %token STRUCT _("keyword `struct'")
> -token <integer> UNION _("keyword `union'")
> +%token <integer> UNION _("keyword `union'")
> %token CONST _("keyword `const'")
> %token CONTINUE _("keyword `continue'")
> %token ELSE _("keyword `else'")
> diff --git a/libpoke/pkl-typify.c b/libpoke/pkl-typify.c
> index aa53ee61..6fe8bfa6 100644
> --- a/libpoke/pkl-typify.c
> +++ b/libpoke/pkl-typify.c
> @@ -1710,6 +1710,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
> pkl_ast_node struct_type = PKL_PASS_NODE;
> pkl_ast_node struct_type_itype = PKL_AST_TYPE_S_ITYPE (struct_type);
> pkl_ast_node field;
> + int is_union_p = PKL_AST_TYPE_S_UNION_P (struct_type);
>
> if (struct_type_itype)
> {
> @@ -1724,22 +1725,14 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
> char *type_str = pkl_type_str (struct_type_itype, 1);
>
> PKL_ERROR (PKL_AST_LOC (struct_type_itype),
> - "invalid type specifier in integral struct\n"
> + "invalid type specifier in integral %s\n"
> "expected integral, got %s",
> - type_str);
> + is_union_p ? "union" : "struct", type_str);
> free (type_str);
> PKL_TYPIFY_PAYLOAD->errors++;
> PKL_PASS_ERROR;
> }
>
> - if (PKL_AST_TYPE_S_UNION_P (struct_type))
> - {
> - PKL_ERROR (PKL_AST_LOC (struct_type),
> - "unions can't be integral");
> - PKL_TYPIFY_PAYLOAD->errors++;
> - PKL_PASS_ERROR;
> - }
> -
> for (field = PKL_AST_TYPE_S_ELEMS (struct_type);
> field;
> field = PKL_AST_CHAIN (field))
> @@ -1758,9 +1751,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
> char *type_str = pkl_type_str (ftype, 1);
>
> PKL_ERROR (PKL_AST_LOC (field),
> - "invalid field in integral struct\n"
> - "expected integral, offset or integral struct,
> got %s",
> - type_str);
> + "invalid field in integral %s\n"
> + "expected integral, offset or integral
> struct/union, got %s",
> + is_union_p ? "union" : "struct", type_str);
> free (type_str);
> PKL_TYPIFY_PAYLOAD->errors++;
> PKL_PASS_ERROR;
> @@ -1769,7 +1762,8 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
> if (PKL_AST_STRUCT_TYPE_FIELD_LABEL (field))
> {
> PKL_ERROR (PKL_AST_LOC (field),
> - "labels are not allowed in integral structs");
> + "labels are not allowed in integral %ss",
> + is_union_p ? "union" : "struct");
> PKL_TYPIFY_PAYLOAD->errors++;
> PKL_PASS_ERROR;
> }
> @@ -1777,20 +1771,42 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
> if (PKL_AST_STRUCT_TYPE_FIELD_OPTCOND (field))
> {
> PKL_ERROR (PKL_AST_LOC (field),
> - "optional fields are not allowed in integral
> structs");
> + "optional fields are not allowed in integral
> %ss",
> + is_union_p ? "union" : "struct");
> PKL_TYPIFY_PAYLOAD->errors++;
> PKL_PASS_ERROR;
> }
>
> - fields_int_size += pkl_ast_sizeof_integral_type (ftype);
> + {
> + int fsize = pkl_ast_sizeof_integral_type (ftype);
> +
> + if (is_union_p)
> + {
> + if (fsize != PKL_AST_TYPE_I_SIZE (struct_type_itype))
> + {
> + PKL_ERROR (PKL_AST_LOC (field),
> + "invalid field size in integral union
> type\n"
> + "expected %" PRIu64 " bits, got %" PRId32
> " bits",
> + (uint64_t) PKL_AST_TYPE_I_SIZE
> (struct_type_itype),
> + fsize);
> + PKL_TYPIFY_PAYLOAD->errors++;
> + PKL_PASS_ERROR;
> + }
> + if (fields_int_size == 0)
> + fields_int_size = fsize;
> + }
> + else
> + fields_int_size += fsize;
> + }
> }
> }
>
> if (fields_int_size != PKL_AST_TYPE_I_SIZE (struct_type_itype))
> {
> PKL_ERROR (PKL_AST_LOC (struct_type_itype),
> - "invalid total size in integral struct type\n"
> + "invalid total size in integral %s type\n"
> "expected %" PRIu64 " bits, got %" PRId32 " bits",
> + is_union_p ? "union" : "struct",
> (uint64_t) PKL_AST_TYPE_I_SIZE (struct_type_itype),
> fields_int_size);
> PKL_TYPIFY_PAYLOAD->errors++;
> @@ -1798,8 +1814,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
> }
> }
>
> - if (PKL_AST_TYPE_S_PINNED_P (struct_type)
> - && PKL_AST_TYPE_S_UNION_P (struct_type))
> + if (PKL_AST_TYPE_S_PINNED_P (struct_type) && is_union_p)
> {
> PKL_ERROR (PKL_AST_LOC (struct_type),
> "unions are not allowed to be pinned");
> @@ -1807,8 +1822,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
> PKL_PASS_ERROR;
> }
>
> - if (PKL_AST_TYPE_S_PINNED_P (struct_type)
> - || PKL_AST_TYPE_S_UNION_P (struct_type))
> + if (PKL_AST_TYPE_S_PINNED_P (struct_type) || is_union_p)
> {
> for (field = PKL_AST_TYPE_S_ELEMS (struct_type);
> field;
> diff --git a/libpoke/pvm.jitter b/libpoke/pvm.jitter
> index 7c2bc821..dc28f101 100644
> --- a/libpoke/pvm.jitter
> +++ b/libpoke/pvm.jitter
> @@ -6631,3 +6631,13 @@ rule push-drop-to-nop rewrite
> push $a; drop
> into
> end
> +
> +rule dup-drop rewrite
> + dup; drop
> +into
> +end
> +
> +rule dup-nip rewrite
> + dup; nip
> +into
> +end
> diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
> index 3089bcc3..d1b5b9e9 100644
> --- a/testsuite/Makefile.am
> +++ b/testsuite/Makefile.am
> @@ -285,6 +285,11 @@ EXTRA_DIST = \
> poke.map/maps-int-structs-27.pk \
> poke.map/maps-int-structs-28.pk \
> poke.map/maps-int-structs-29.pk \
> + poke.map/maps-int-union-1.pk \
> + poke.map/maps-int-union-2.pk \
> + poke.map/maps-int-union-4.pk \
> + poke.map/maps-int-union-3.pk \
> + poke.map/maps-int-union-5.pk \
> poke.map/maps-ios-1.pk \
> poke.map/maps-ios-2.pk \
> poke.map/maps-ios-3.pk \
> @@ -1434,11 +1439,56 @@ EXTRA_DIST = \
> poke.pkl/int-struct-type-diag-13.pk \
> poke.pkl/int-struct-type-diag-14.pk \
> poke.pkl/int-struct-type-diag-15.pk \
> - poke.pkl/int-struct-type-diag-16.pk \
> - poke.pkl/int-struct-type-diag-17.pk \
> poke.pkl/int-type-diag-1.pk \
> poke.pkl/int-type-diag-2.pk \
> poke.pkl/int-type.pk \
> + poke.pkl/int-union-1.pk \
> + poke.pkl/int-union-2.pk \
> + poke.pkl/int-union-3.pk \
> + poke.pkl/int-union-4.pk \
> + poke.pkl/int-union-5.pk \
> + poke.pkl/int-union-6.pk \
> + poke.pkl/int-union-7.pk \
> + poke.pkl/int-union-8.pk \
> + poke.pkl/int-union-9.pk \
> + poke.pkl/int-union-10.pk \
> + poke.pkl/int-union-11.pk \
> + poke.pkl/int-union-12.pk \
> + poke.pkl/int-union-13.pk \
> + poke.pkl/int-union-14.pk \
> + poke.pkl/int-union-15.pk \
> + poke.pkl/int-union-16.pk \
> + poke.pkl/int-union-17.pk \
> + poke.pkl/int-union-18.pk \
> + poke.pkl/int-union-19.pk \
> + poke.pkl/int-union-20.pk \
> + poke.pkl/int-union-21.pk \
> + poke.pkl/int-union-22.pk \
> + poke.pkl/int-union-23.pk \
> + poke.pkl/int-union-24.pk \
> + poke.pkl/int-union-25.pk \
> + poke.pkl/int-union-26.pk \
> + poke.pkl/int-union-27.pk \
> + poke.pkl/int-union-28.pk \
> + poke.pkl/int-union-29.pk \
> + poke.pkl/int-union-30.pk \
> + poke.pkl/int-union-type-diag-1.pk \
> + poke.pkl/int-union-type-diag-2.pk \
> + poke.pkl/int-union-type-diag-3.pk \
> + poke.pkl/int-union-type-diag-4.pk \
> + poke.pkl/int-union-type-diag-5.pk \
> + poke.pkl/int-union-type-diag-6.pk \
> + poke.pkl/int-union-type-diag-7.pk \
> + poke.pkl/int-union-type-diag-8.pk \
> + poke.pkl/int-union-type-diag-9.pk \
> + poke.pkl/int-union-type-diag-10.pk \
> + poke.pkl/int-union-type-diag-11.pk \
> + poke.pkl/int-union-type-diag-12.pk \
> + poke.pkl/int-union-type-diag-13.pk \
> + poke.pkl/int-union-type-diag-14.pk \
> + poke.pkl/int-union-type-diag-15.pk \
> + poke.pkl/int-union-type-diag-16.pk \
> + poke.pkl/int-union-type-diag-17.pk \
> poke.pkl/integers-1.pk \
> poke.pkl/integers-2.pk \
> poke.pkl/integers-3.pk \
> diff --git a/testsuite/poke.map/maps-int-union-1.pk
> b/testsuite/poke.map/maps-int-union-1.pk
> new file mode 100644
> index 00000000..2ec32f28
> --- /dev/null
> +++ b/testsuite/poke.map/maps-int-union-1.pk
> @@ -0,0 +1,17 @@
> +/* { dg-do run } */
> +/* { dg-data {c*} {0x10 0x20 0x30} } */
> +
> +type U = union uint<16>
> + {
> + int<16> a : a < 0;
> + uint<16> b;
> + };
> +
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set endian big} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {U @ 1#B } } */
> +/* { dg-output "U {b=0x2030UH}" } */
> +/* { dg-command {+(U @ 1#B)} } */
> +/* { dg-output "\\n0x2030UH" } */
> diff --git a/testsuite/poke.map/maps-int-union-2.pk
> b/testsuite/poke.map/maps-int-union-2.pk
> new file mode 100644
> index 00000000..2f52b0a3
> --- /dev/null
> +++ b/testsuite/poke.map/maps-int-union-2.pk
> @@ -0,0 +1,17 @@
> +/* { dg-do run } */
> +/* { dg-data {c*} {0x10 0xde 0xba 0xbe} } */
> +
> +type U = union uint<16>
> + {
> + int<16> a : a < 0;
> + uint<16> b;
> + };
> +
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set endian big} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {U @ 2#B } } */
> +/* { dg-output "U {a=0xbabeH}" } */
> +/* { dg-command {+(U @ 2#B)} } */
> +/* { dg-output "\\n0xbabeUH" } */
> diff --git a/testsuite/poke.map/maps-int-union-3.pk
> b/testsuite/poke.map/maps-int-union-3.pk
> new file mode 100644
> index 00000000..22a6334a
> --- /dev/null
> +++ b/testsuite/poke.map/maps-int-union-3.pk
> @@ -0,0 +1,23 @@
> +/* { dg-do run } */
> +/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50} } */
> +
> +type S = struct uint<32>
> + {
> + bit sign;
> + uint<31> mag;
> + };
> +
> +type U = union uint<32>
> + {
> + S a : a.sign == 1;
> + S b;
> + };
> +
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set endian big} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {U @ 1#B } } */
> +/* { dg-output "U {b=S {sign=\\(uint<1>\\) 0x0,mag=\\(uint<31>\\)
> 0x20304050}}" } */
> +/* { dg-command {+(U @ 1#B)} } */
> +/* { dg-output "\\n0x20304050U" } */
> diff --git a/testsuite/poke.map/maps-int-union-4.pk
> b/testsuite/poke.map/maps-int-union-4.pk
> new file mode 100644
> index 00000000..401fef79
> --- /dev/null
> +++ b/testsuite/poke.map/maps-int-union-4.pk
> @@ -0,0 +1,23 @@
> +/* { dg-do run } */
> +/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50} } */
> +
> +type S = struct uint<32>
> + {
> + bit sign;
> + uint<31> mag;
> + };
> +
> +type U = union int<32>
> + {
> + S a : a.sign == 1;
> + S b;
> + };
> +
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set endian big} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {U @ 1#B } } */
> +/* { dg-output "U {b=S {sign=\\(uint<1>\\) 0x0,mag=\\(uint<31>\\)
> 0x20304050}}" } */
> +/* { dg-command {+(U @ 1#B)} } */
> +/* { dg-output "\\n0x20304050" } */
> diff --git a/testsuite/poke.map/maps-int-union-5.pk
> b/testsuite/poke.map/maps-int-union-5.pk
> new file mode 100644
> index 00000000..666825e8
> --- /dev/null
> +++ b/testsuite/poke.map/maps-int-union-5.pk
> @@ -0,0 +1,23 @@
> +/* { dg-do run } */
> +/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50} } */
> +
> +type S = struct uint<32>
> + {
> + bit sign;
> + uint<31>;
> + };
> +
> +type U = union int<32>
> + {
> + S a : a.sign == 1;
> + S b;
> + };
> +
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set endian big} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {U @ 1#B } } */
> +/* { dg-output "U {b=S {sign=\\(uint<1>\\) 0x0,\\(uint<31>\\) 0x20304050}}"
> } */
> +/* { dg-command {+(U @ 1#B)} } */
> +/* { dg-output "\\n0x20304050" } */
> diff --git a/testsuite/poke.pkl/int-struct-type-diag-11.pk
> b/testsuite/poke.pkl/int-struct-type-diag-11.pk
> index 497e53b1..60e52c69 100644
> --- a/testsuite/poke.pkl/int-struct-type-diag-11.pk
> +++ b/testsuite/poke.pkl/int-struct-type-diag-11.pk
> @@ -1,6 +1,8 @@
> /* { dg-do compile } */
>
> -type Foo = /* { dg-error "integral" } */
> - union int<32>
> +type Foo =
> + struct int<32>
> {
> + int a;
> + string s; /* { dg-error "invalid field.*\n.*expected integral, offset or
> integral struct" } */
> };
> diff --git a/testsuite/poke.pkl/int-struct-type-diag-16.pk
> b/testsuite/poke.pkl/int-struct-type-diag-16.pk
> deleted file mode 100644
> index 7ea3f43e..00000000
> --- a/testsuite/poke.pkl/int-struct-type-diag-16.pk
> +++ /dev/null
> @@ -1,7 +0,0 @@
> -/* { dg-do compile } */
> -
> -type Foo = /* { dg-error "unions can't be integral" } */
> - union int<32>
> - {
> - int a;
> - };
> diff --git a/testsuite/poke.pkl/int-struct-type-diag-17.pk
> b/testsuite/poke.pkl/int-struct-type-diag-17.pk
> deleted file mode 100644
> index 60e52c69..00000000
> --- a/testsuite/poke.pkl/int-struct-type-diag-17.pk
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -/* { dg-do compile } */
> -
> -type Foo =
> - struct int<32>
> - {
> - int a;
> - string s; /* { dg-error "invalid field.*\n.*expected integral, offset or
> integral struct" } */
> - };
> diff --git a/testsuite/poke.pkl/int-union-1.pk
> b/testsuite/poke.pkl/int-union-1.pk
> new file mode 100644
> index 00000000..a6ef6639
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-1.pk
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union uint<32>
> + {
> + int<32> a : a > 0;
> + uint<32> b : b < 128;
> + struct int<32>
> + {
> + uint<16> hi;
> + uint<16> lo;
> + } c;
> + };
> diff --git a/testsuite/poke.pkl/int-union-10.pk
> b/testsuite/poke.pkl/int-union-10.pk
> new file mode 100644
> index 00000000..87461e00
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-10.pk
> @@ -0,0 +1,12 @@
> +/* { dg-do run } */
> +
> +type U = union uint
> + {
> + offset<int,B> a : a < 0#B;
> + uint b : b < 10;
> + };
> +
> +/* { dg-command {.set obase 10} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {1 as U} } */
> +/* { dg-output "U {b=1U}" } */
> diff --git a/testsuite/poke.pkl/int-union-11.pk
> b/testsuite/poke.pkl/int-union-11.pk
> new file mode 100644
> index 00000000..2b2072d7
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-11.pk
> @@ -0,0 +1,12 @@
> +/* { dg-do run } */
> +
> +type U = union uint
> + {
> + offset<int,B> a : a < 0#B;
> + uint b : b < 10;
> + };
> +
> +/* { dg-command {.set obase 10} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {(-1) as U} } */
> +/* { dg-output "U {a=-1#B}" } */
> diff --git a/testsuite/poke.pkl/int-union-12.pk
> b/testsuite/poke.pkl/int-union-12.pk
> new file mode 100644
> index 00000000..0fcedf27
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-12.pk
> @@ -0,0 +1,13 @@
> +/* { dg-do run } */
> +
> +type U = union uint
> + {
> + offset<int,B> a : a < 0#B;
> + uint b : b < 10;
> + };
> +
> +/* { dg-command {.set obase 10} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {var x = -1} } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "U {a=-1#B}" } */
> diff --git a/testsuite/poke.pkl/int-union-13.pk
> b/testsuite/poke.pkl/int-union-13.pk
> new file mode 100644
> index 00000000..84bc24f0
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-13.pk
> @@ -0,0 +1,24 @@
> +/* { dg-do run } */
> +
> +type U = union uint
> + {
> + offset<int,B> a : a < 0#B;
> + uint b : b < 10;
> + };
> +
> +var s = "bad",
> + x = 10;
> +try
> + {
> + x as U;
> + s = "ugly";
> + }
> +catch if E_constraint
> + {
> + s = "good";
> + }
> +
> +/* { dg-command {.set obase 10} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {s} } */
> +/* { dg-output "good" } */
> diff --git a/testsuite/poke.pkl/int-union-14.pk
> b/testsuite/poke.pkl/int-union-14.pk
> new file mode 100644
> index 00000000..c51a2030
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-14.pk
> @@ -0,0 +1,20 @@
> +/* { dg-do run } */
> +
> +type T = struct uint
> + {
> + int16 a;
> + int16 b;
> + };
> +
> +type U = union int
> + {
> + T a : a.a < 0;
> + uint b : b < 10;
> + };
> +
> +var x = -1;
> +
> +/* { dg-command {.set obase 10} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "U {a=T {a=-1H,b=-1H}}" } */
> diff --git a/testsuite/poke.pkl/int-union-15.pk
> b/testsuite/poke.pkl/int-union-15.pk
> new file mode 100644
> index 00000000..06cadf2b
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-15.pk
> @@ -0,0 +1,21 @@
> +/* { dg-do run } */
> +
> +type T = struct uint
> + {
> + int16 a;
> + int16 b;
> + };
> +
> +type U = union int
> + {
> + T a : a.a < 0;
> + uint b : b < 10;
> + };
> +
> +var x = 0xabcdef12;
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {.set endian little} } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "U {a=T {a=0xabcdH,b=0xef12H}}" } */
> diff --git a/testsuite/poke.pkl/int-union-16.pk
> b/testsuite/poke.pkl/int-union-16.pk
> new file mode 100644
> index 00000000..b7da110a
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-16.pk
> @@ -0,0 +1,20 @@
> +/* { dg-do run } */
> +
> +type T = struct uint
> + {
> + int16 a;
> + int16 b;
> + };
> +
> +type U = union int
> + {
> + T a : a.a < 0;
> + uint b : b < 10;
> + };
> +
> +var x = 1;
> +
> +/* { dg-command {.set obase 10} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "U {b=1U}" } */
> diff --git a/testsuite/poke.pkl/int-union-17.pk
> b/testsuite/poke.pkl/int-union-17.pk
> new file mode 100644
> index 00000000..e88fbb34
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-17.pk
> @@ -0,0 +1,29 @@
> +/* { dg-do run } */
> +
> +type T = struct uint
> + {
> + int16 a;
> + int16 b;
> + };
> +
> +type U = union int
> + {
> + T a : a.a < 0;
> + uint b : b < 10;
> + };
> +
> +var s = "bad",
> + x = 10;
> +try
> + {
> + x as U;
> + s = "ugly";
> + }
> +catch if E_constraint
> + {
> + s = "good";
> + }
> +
> +/* { dg-command {.set obase 10} } */
> +/* { dg-command {s} } */
> +/* { dg-output "good" } */
> diff --git a/testsuite/poke.pkl/int-union-18.pk
> b/testsuite/poke.pkl/int-union-18.pk
> new file mode 100644
> index 00000000..dd490c4d
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-18.pk
> @@ -0,0 +1,20 @@
> +/* { dg-do run } */
> +
> +type U = union int
> + {
> + struct int
> + {
> + struct int
> + {
> + uint<16> a : a != 0;
> + uint<16> b;
> + } x;
> + } y;
> + };
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {.set endian little} } */
> +/* { dg-command {var x = 0xdeadbeef} } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "U {y=struct {x=struct {a=0xdeadUH,b=0xbeefUH}}}" } */
> diff --git a/testsuite/poke.pkl/int-union-19.pk
> b/testsuite/poke.pkl/int-union-19.pk
> new file mode 100644
> index 00000000..fcb8a050
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-19.pk
> @@ -0,0 +1,20 @@
> +/* { dg-do run } */
> +
> +type U = union int
> + {
> + struct int
> + {
> + struct int
> + {
> + uint<16> a : a == 0;
> + offset<int<16>,KB> b;
> + } x;
> + } y;
> + };
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {.set endian little} } */
> +/* { dg-command {var x = 0xdead} } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "U {y=struct {x=struct {a=0x0UH,b=0xdeadH#KB}}}" } */
> diff --git a/testsuite/poke.pkl/int-union-2.pk
> b/testsuite/poke.pkl/int-union-2.pk
> new file mode 100644
> index 00000000..192132b3
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-2.pk
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +
> +type MyInt = uint<41>;
> +
> +type Foo =
> + union MyInt
> + {
> + int<41> a : a > 0;
> + uint<41> b;
> + };
> diff --git a/testsuite/poke.pkl/int-union-20.pk
> b/testsuite/poke.pkl/int-union-20.pk
> new file mode 100644
> index 00000000..96aad6f4
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-20.pk
> @@ -0,0 +1,16 @@
> +/* { dg-do run } */
> +
> +type U = union int
> + {
> + int a : a < 0;
> + uint b;
> + };
> +
> +/* { dg-command {.set obase 10} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {var x = 1} } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "U {b=1U}" } */
> +/* { dg-command {var x = -1} } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "\\nU {a=-1}" } */
> diff --git a/testsuite/poke.pkl/int-union-21.pk
> b/testsuite/poke.pkl/int-union-21.pk
> new file mode 100644
> index 00000000..042d164a
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-21.pk
> @@ -0,0 +1,16 @@
> +/* { dg-do run } */
> +
> +type U = union int
> + {
> + int a : a < 0;
> + uint b;
> + };
> +
> +/* { dg-command {.set obase 10} } */
> +/* { dg-command {.set omode flat} } */
> +/* { dg-command {var x = 1UL} } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "U {b=1U}" } */
> +/* { dg-command {var x = 0xffff_ffffUL} } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "\\nU {a=-1}" } */
> diff --git a/testsuite/poke.pkl/int-union-22.pk
> b/testsuite/poke.pkl/int-union-22.pk
> new file mode 100644
> index 00000000..e1431e12
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-22.pk
> @@ -0,0 +1,14 @@
> +/* { dg-do run } */
> +
> +type U = union uint
> + {
> + offset<int,B> a : a < 0#B;
> + uint b : b < 10;
> + };
> +
> +/* { dg-command {.set obase 10} } */
> +/* { dg-command {var x = U {b=5}} } */
> +/* { dg-command {+x} } */
> +/* { dg-output "5U" } */
> +/* { dg-command {x as int} } */
> +/* { dg-output "\\n5" } */
> diff --git a/testsuite/poke.pkl/int-union-23.pk
> b/testsuite/poke.pkl/int-union-23.pk
> new file mode 100644
> index 00000000..ff520714
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-23.pk
> @@ -0,0 +1,14 @@
> +/* { dg-do run } */
> +
> +type U = union uint
> + {
> + offset<int,B> a : a < 0#B;
> + uint b : b < 10;
> + };
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {var x = U {a=-20#B}} } */
> +/* { dg-command {+x} } */
> +/* { dg-output "0xffffffecU" } */
> +/* { dg-command {x as ulong} } */
> +/* { dg-output "\\n0xffffffecUL" } */
> diff --git a/testsuite/poke.pkl/int-union-24.pk
> b/testsuite/poke.pkl/int-union-24.pk
> new file mode 100644
> index 00000000..204d9b0f
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-24.pk
> @@ -0,0 +1,14 @@
> +/* { dg-do run } */
> +
> +type U = union int
> + {
> + offset<int,B> a : a < 0#B;
> + uint b : b < 10;
> + };
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {var x = U {a=-20#B}} } */
> +/* { dg-command {+x} } */
> +/* { dg-output "0xffffffec" } */
> +/* { dg-command {x as ulong} } */
> +/* { dg-output "\\n0xffffffffffffffecUL" } */
> diff --git a/testsuite/poke.pkl/int-union-25.pk
> b/testsuite/poke.pkl/int-union-25.pk
> new file mode 100644
> index 00000000..47ec64f5
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-25.pk
> @@ -0,0 +1,23 @@
> +/* { dg-do run } */
> +
> +type S = struct long
> + {
> + int16 x;
> + int32 y : y < 0;
> + int16 z;
> + };
> +
> +type U = union long
> + {
> + S a;
> + ulong b;
> + };
> +
> +var s = S{ x=0xdead, y=0x87654321U as int, z=0xbeef };
> +var u = U { a=s };
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {+s} } */
> +/* { dg-output "0xdead87654321beefL" } */
> +/* { dg-command {+u} } */
> +/* { dg-output "\\n0xdead87654321beefL" } */
> diff --git a/testsuite/poke.pkl/int-union-26.pk
> b/testsuite/poke.pkl/int-union-26.pk
> new file mode 100644
> index 00000000..b34eee1a
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-26.pk
> @@ -0,0 +1,20 @@
> +/* { dg-do run } */
> +
> +type S = struct long
> + {
> + int16 x;
> + int32 y : y < 0;
> + int16 z;
> + };
> +
> +type U = union long
> + {
> + S a;
> + ulong b;
> + };
> +
> +var u = U { b=0xdead12345678beefUL };
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {+u} } */
> +/* { dg-output "0xdead12345678beefL" } */
> diff --git a/testsuite/poke.pkl/int-union-27.pk
> b/testsuite/poke.pkl/int-union-27.pk
> new file mode 100644
> index 00000000..d4c8ac9f
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-27.pk
> @@ -0,0 +1,23 @@
> +/* { dg-do run } */
> +
> +type S = struct uint
> + {
> + int16 a;
> + int16 b;
> + };
> +
> +type U = union int
> + {
> + S a : a.a < 0;
> + uint b : b < 10;
> + };
> +
> +var s = S { a=0xabcd, b=0xef12 };
> +var u = U { a = s };
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set endian little} } */
> +/* { dg-command {+s} } */
> +/* { dg-output "0xabcdef12U" } */
> +/* { dg-command {+u} } */
> +/* { dg-output "\\n0xabcdef12" } */
> diff --git a/testsuite/poke.pkl/int-union-28.pk
> b/testsuite/poke.pkl/int-union-28.pk
> new file mode 100644
> index 00000000..83d204a3
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-28.pk
> @@ -0,0 +1,23 @@
> +/* { dg-do run } */
> +
> +type S = struct uint
> + {
> + int16 a;
> + offset<int16,b> b;
> + };
> +
> +type U = union int
> + {
> + S a : a.a < 0;
> + uint b : b < 10;
> + };
> +
> +var s = S { a=0xabcd, b=0xef12H#b };
> +var u = U { a = s };
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set endian little} } */
> +/* { dg-command {+s} } */
> +/* { dg-output "0xabcdef12U" } */
> +/* { dg-command {+u} } */
> +/* { dg-output "\\n0xabcdef12" } */
> diff --git a/testsuite/poke.pkl/int-union-29.pk
> b/testsuite/poke.pkl/int-union-29.pk
> new file mode 100644
> index 00000000..ed5503db
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-29.pk
> @@ -0,0 +1,24 @@
> +/* { dg-do run } */
> +
> +type U = union int
> + {
> + struct uint
> + {
> + struct int
> + {
> + uint<16> a : a == 0;
> + offset<int<16>,KB> b;
> + } x;
> + } y;
> + };
> +
> +var x = 0xdead;
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set endian little} } */
> +/* { dg-command {+U{}} } */
> +/* { dg-output "0x0" } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "\\nU {y=struct {x=struct {a=0x0UH,b=0xdeadH#KB}}}" } */
> +/* { dg-command {+(x as U)} } */
> +/* { dg-output "\\n0xdead" } */
> diff --git a/testsuite/poke.pkl/int-union-3.pk
> b/testsuite/poke.pkl/int-union-3.pk
> new file mode 100644
> index 00000000..1b66d27e
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-3.pk
> @@ -0,0 +1,4 @@
> +/* { dg-do compile } */
> +
> +type Bar = union int<8> { int<8> a : a > 10; int<8> b; };
> +type Foo = union int<8> { Bar la; struct int<8> { int<6> c; int<2> d; } e; };
> diff --git a/testsuite/poke.pkl/int-union-30.pk
> b/testsuite/poke.pkl/int-union-30.pk
> new file mode 100644
> index 00000000..5908da9a
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-30.pk
> @@ -0,0 +1,26 @@
> +/* { dg-do run } */
> +
> +type U = union int
> + {
> + struct int
> + {
> + uint<16> a : a == 0;
> + offset<int<16>,KB> b;
> + } x;
> + struct uint
> + {
> + uint<16> a : a != 0;
> + offset<int<16>,KB> b;
> + } y;
> + };
> +
> +var x = 0xdeadbeef;
> +
> +/* { dg-command {.set obase 16} } */
> +/* { dg-command {.set endian little} } */
> +/* { dg-command {+U{}} } */
> +/* { dg-output "0x0" } */
> +/* { dg-command {x as U} } */
> +/* { dg-output "\\nU {y=struct {a=0xdeadUH,b=0xbeefH#KB}}" } */
> +/* { dg-command {+(x as U)} } */
> +/* { dg-output "\\n0xdeadbeef" } */
> diff --git a/testsuite/poke.pkl/int-union-4.pk
> b/testsuite/poke.pkl/int-union-4.pk
> new file mode 100644
> index 00000000..3f8fbc2d
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-4.pk
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +
> +
> +type Foo =
> + union int<16>
> + {
> + union int<16> { int<16> a : a < 0; uint<16> b; } la;
> + int<16> c;
> + };
> diff --git a/testsuite/poke.pkl/int-union-5.pk
> b/testsuite/poke.pkl/int-union-5.pk
> new file mode 100644
> index 00000000..11f00fc1
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-5.pk
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union uint<32>
> + {
> + int<32> a : a > 0;
> + offset<uint<32>,B> b : b < 128#B;
> + struct int<32>
> + {
> + offset<uint<16>,KiB> hi;
> + uint<16> lo;
> + } c;
> + };
> diff --git a/testsuite/poke.pkl/int-union-6.pk
> b/testsuite/poke.pkl/int-union-6.pk
> new file mode 100644
> index 00000000..7457b638
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-6.pk
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +
> +type MyInt = uint<41>;
> +
> +type Foo =
> + union MyInt
> + {
> + int<41> a : a > 0;
> + offset<uint<41>,b> b;
> + };
> diff --git a/testsuite/poke.pkl/int-union-7.pk
> b/testsuite/poke.pkl/int-union-7.pk
> new file mode 100644
> index 00000000..ed6e3086
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-7.pk
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +
> +type Bar = union int<8>
> + { offset<int<8>,b> a : a > 10#B; offset<int<8>,B> b; };
> +type Foo = union int<8>
> + { Bar la; struct int<8> { int<6> c; offset<int<2>,KB> d; } e; };
> diff --git a/testsuite/poke.pkl/int-union-8.pk
> b/testsuite/poke.pkl/int-union-8.pk
> new file mode 100644
> index 00000000..eef1cba8
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-8.pk
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +
> +
> +type Foo =
> + union int<16>
> + {
> + union int<16> { int<16> a : a < 0; offset<uint<16>,B> b; } la;
> + offset<int<16>,MiB> c;
> + };
> diff --git a/testsuite/poke.pkl/int-union-9.pk
> b/testsuite/poke.pkl/int-union-9.pk
> new file mode 100644
> index 00000000..4b500064
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-9.pk
> @@ -0,0 +1,19 @@
> +/* { dg-do compile } */
> +
> +
> +type Foo =
> + union int<16>
> + {
> + union int<16> { int<16> a : a < 0; offset<uint<16>,B> b; } la;
> + offset<int<16>,MiB> c;
> +
> + method _print = void:
> + {
> + if (!(la.a ?! E_elem))
> + printf "%v", la.a;
> + if (!(la.b ?! E_elem))
> + printf "%v\n", la.b;
> + if (!(c ?! E_elem))
> + printf "%v\n", c;
> + }
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-1.pk
> b/testsuite/poke.pkl/int-union-type-diag-1.pk
> new file mode 100644
> index 00000000..ea35a167
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-1.pk
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union int<0> /* { dg-error "" } */
> + {
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-10.pk
> b/testsuite/poke.pkl/int-union-type-diag-10.pk
> new file mode 100644
> index 00000000..a3e75a20
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-10.pk
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union uint<33>
> + {
> + struct int<33>
> + {
> + int<17> x;
> + int<16> y;
> + } b;
> + int<33> c @ 0#B; /* { dg-error "labels are not allowed" } */
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-11.pk
> b/testsuite/poke.pkl/int-union-type-diag-11.pk
> new file mode 100644
> index 00000000..1d1f10e5
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-11.pk
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union int<32> /* { dg-error "invalid total size.*\n.*expected 32.*got 0" }
> */
> + {
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-12.pk
> b/testsuite/poke.pkl/int-union-type-diag-12.pk
> new file mode 100644
> index 00000000..ff665746
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-12.pk
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union uint<32>
> + {
> + int<32> a;
> + offset<int<31>,B> b; /* { dg-error "invalid field size.*\n.*expected 32"
> } */
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-13.pk
> b/testsuite/poke.pkl/int-union-type-diag-13.pk
> new file mode 100644
> index 00000000..8b713067
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-13.pk
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union uint<32>
> + {
> + int<32> a;
> + offset<int<32>,B> b if a == 2; /* { dg-error "optional.*allowed" } */
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-14.pk
> b/testsuite/poke.pkl/int-union-type-diag-14.pk
> new file mode 100644
> index 00000000..cc702688
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-14.pk
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union string /* { dg-error "invalid type.*\n.*expected integral" } */
> + {
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-15.pk
> b/testsuite/poke.pkl/int-union-type-diag-15.pk
> new file mode 100644
> index 00000000..d344230b
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-15.pk
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union int<16>
> + {
> + struct int<10> /* { dg-error "invalid total size.*\n.*expected 10" } */
> + {
> + byte a;
> + byte b;
> + } la;
> +
> + uint<16> le;
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-16.pk
> b/testsuite/poke.pkl/int-union-type-diag-16.pk
> new file mode 100644
> index 00000000..7b364024
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-16.pk
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union uint<32>
> + {
> + int<16> a : a > 0; /* { dg-error "invalid field size.*\n.*expected 32" }
> */
> + uint<8> b : b < 128;
> + uint<4> c : a + b > 255;
> + int<32> d;
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-17.pk
> b/testsuite/poke.pkl/int-union-type-diag-17.pk
> new file mode 100644
> index 00000000..e28460c7
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-17.pk
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union int<32>
> + {
> + int a;
> + byte[4] b; /* { dg-error "invalid field.*\n.*expected integral, offset
> or integral struct/union" } */
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-2.pk
> b/testsuite/poke.pkl/int-union-type-diag-2.pk
> new file mode 100644
> index 00000000..09335dcd
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-2.pk
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union int<65> /* { dg-error "" } */
> + {
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-3.pk
> b/testsuite/poke.pkl/int-union-type-diag-3.pk
> new file mode 100644
> index 00000000..4d002336
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-3.pk
> @@ -0,0 +1,7 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union int<32>
> + {
> + string je; /* { dg-error "invalid field.*\n.*expected integral, offset
> or integral struct/union" } */
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-4.pk
> b/testsuite/poke.pkl/int-union-type-diag-4.pk
> new file mode 100644
> index 00000000..5a38bd1b
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-4.pk
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union int<32>
> + {
> + int<32> i;
> + int<32>[] je; /* { dg-error "invalid field.*\n.*expected integral,
> offset or integral struct/union" } */
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-5.pk
> b/testsuite/poke.pkl/int-union-type-diag-5.pk
> new file mode 100644
> index 00000000..fdd3d9fd
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-5.pk
> @@ -0,0 +1,7 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union int<32>
> + {
> + int<32> foo; union {} bar; /* { dg-error "invalid field.*\n.*expected
> integral, offset or integral struct/union" } */
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-6.pk
> b/testsuite/poke.pkl/int-union-type-diag-6.pk
> new file mode 100644
> index 00000000..784dcdd3
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-6.pk
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union uint<32> /* { dg-error "invalid total size.*\n.*expected 32" } */
> + {
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-7.pk
> b/testsuite/poke.pkl/int-union-type-diag-7.pk
> new file mode 100644
> index 00000000..abddffba
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-7.pk
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union uint<32>
> + {
> + int<32> a;
> + int<17> b; /* { dg-error "invalid field size.*\n.*expected 32" } */
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-8.pk
> b/testsuite/poke.pkl/int-union-type-diag-8.pk
> new file mode 100644
> index 00000000..6daa94fd
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-8.pk
> @@ -0,0 +1,7 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union uint<32>
> + {
> + int<33> a; /* { dg-error "invalid field size.*\n.*expected 32" } */
> + };
> diff --git a/testsuite/poke.pkl/int-union-type-diag-9.pk
> b/testsuite/poke.pkl/int-union-type-diag-9.pk
> new file mode 100644
> index 00000000..4ff576b2
> --- /dev/null
> +++ b/testsuite/poke.pkl/int-union-type-diag-9.pk
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +
> +type Foo =
> + union int<33>
> + {
> + /* FIXME due to a bug in parser, I have to put the dg error thing in
> + previous line. */
> + uint<33> le;/* { dg-error "invalid field size.*\n.*expected 33" } */
> + struct int<32>
> + {
> + int16 a;
> + int16 b;
> + } la;
> + };
[PATCH v2 1/2] pkl: codegen: make struct_{constructor, deintegrator} exception-safe, Mohammad-Reza Nabipoor, 2022/09/25