[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 2/2] pkl: add support for integral unions
From: |
Mohammad-Reza Nabipoor |
Subject: |
[PATCH v2 2/2] pkl: add support for integral unions |
Date: |
Mon, 26 Sep 2022 02:49:25 +0330 |
2022-09-26 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* libpoke/pkl-tab.y (tokens): s/token/%token/.
* libpoke/pkl-typify.c (pkl_typify1_ps_cast): Handle integral
unions.
(pkl_typify1_ps_type_struct): Likewise.
* 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.
---
ChangeLog | 72 +++++++
doc/poke.texi | 45 +++++
libpoke/pkl-gen.c | 39 +++-
libpoke/pkl-gen.pks | 190 ++++++++++++++++++
libpoke/pkl-tab.y | 2 +-
libpoke/pkl-typify.c | 73 ++++---
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, 1190 insertions(+), 56 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 62a67838..a8fd753a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,75 @@
+2022-09-26 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
+
+ * libpoke/pkl-tab.y (tokens): s/token/%token/.
+ * libpoke/pkl-typify.c (pkl_typify1_ps_cast): Handle integral
+ unions.
+ (pkl_typify1_ps_type_struct): Likewise.
+ * 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-26 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* libpoke/pkl-gen.pks (function struct_constructor): Do not alter
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 f3c163b8..f1e0c8a0 100644
--- a/libpoke/pkl-gen.pks
+++ b/libpoke/pkl-gen.pks
@@ -2108,6 +2108,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
+ 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)
+ ;; Create the integral value based on the type of field.
+ ;; Due to simplicity of integration of unions (there's only one
+ ;; active field, no anonymous/absent field, etc.), I'm not
+ ;; re-using any code from struct_integrator to keep things
+ ;; simpler and more efficient.
+ .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 }
+ ; 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 )
;;;
@@ -2285,6 +2356,125 @@
raise
.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
+ 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 .constraint_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 {
+ ; IVAL IVAL
+ push PVM_E_CONSTRAINT
+ pushe .constraint_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_CONSTRAINT
+ pushe .constraint_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
+.constraint_failed:
+ nip ; IVAL EXC
+.alternative_failed:
+ 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..516255d2 100644
--- a/libpoke/pkl-typify.c
+++ b/libpoke/pkl-typify.c
@@ -1,4 +1,4 @@
-/* pkl-typify.c - Type handling phases for the poke compiler. */
+/* Pkl-typify.c - Type handling phases for the poke compiler. */
/* Copyright (C) 2019, 2020, 2021, 2022 Jose E. Marchesi */
@@ -477,8 +477,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_cast)
INVALID_CAST ("invalid cast to string");
break;
case PKL_TYPE_STRUCT:
- /* We are not supporting casts to unions yet. */
- if (PKL_AST_TYPE_S_UNION_P (to_type))
+ /* We are not supporting casts to non-integral unions yet. */
+ if (PKL_AST_TYPE_S_UNION_P (to_type)
+ && !PKL_AST_TYPE_S_ITYPE (to_type))
INVALID_CAST ("invalid cast to union");
/* Only structs can be casted to regular structs. Integral
@@ -1688,19 +1689,19 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_integral)
}
PKL_PHASE_END_HANDLER
-/* The type associated with an integral struct shall be integral.
+/* The type associated with an integral struct/union shall be integral.
- The fields in an integral struct type shall be all of integral or
+ The fields in an integral struct/union type shall be all of integral or
offset types (including other integral structs) and the total int
size shall match the sum of the sizes of all the fields.
- The total size declared in the integral struct should exactly match
+ The total size declared in the integral struct/union should exactly match
the size of all the contained fields.
Pinned unions are not allowed.
- Labels are not allowed in integral structs, pinned structs and unions.
- Optional fields are not allowed in integral structs.
+ Labels are not allowed in integral structs/unions, pinned structs and
+ unions. Optional fields are not allowed in integral structs/unions.
Computed fields should have getter and setter methods defined for
them, and they should handle values of the right type. */
@@ -1710,6 +1711,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 +1726,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 +1752,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 +1763,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 +1772,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 +1815,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 +1823,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;
+ };
--
2.37.3
[PATCH v2 1/2] pkl: codegen: make struct_{constructor, deintegrator} exception-safe, Mohammad-Reza Nabipoor, 2022/09/25