poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 2/2] pkl: add support for integral unions


From: Jose E. Marchesi
Subject: Re: [PATCH v2 2/2] pkl: add support for integral unions
Date: Mon, 26 Sep 2022 13:26:43 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

> 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'")

What.  How could that work before? :)

> 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.  */

Spurious change there.

>  /* 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.

"integral struct or union".

>  
> -   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

Ditto.

>     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

Ditto.

>     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.

Ditto.

>     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

I belive this belongs to a different patch.

> 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;
> +  };



reply via email to

[Prev in Thread] Current Thread [Next in Thread]