poke-devel
[Top][All Lists]
Advanced

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

[COMMITTED 2/3] pkl: support for struct field indirection -> operator


From: Jose E. Marchesi
Subject: [COMMITTED 2/3] pkl: support for struct field indirection -> operator
Date: Sun, 23 Apr 2023 15:28:26 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

---
 ChangeLog                               |  25 +++++
 libpoke/pkl-ast.c                       |   3 +
 libpoke/pkl-ast.h                       |  10 +-
 libpoke/pkl-gen.c                       | 123 ++++++++++++++++++++++--
 libpoke/pkl-lex.l                       |   1 +
 libpoke/pkl-tab.y                       |  10 +-
 libpoke/pkl-trans.c                     |   3 +-
 libpoke/pkl-typify.c                    |  23 ++++-
 testsuite/Makefile.am                   |  10 ++
 testsuite/poke.pkl/ass-ind-1.pk         |   7 ++
 testsuite/poke.pkl/ass-ind-2.pk         |   9 ++
 testsuite/poke.pkl/struct-ind-1.pk      |   6 ++
 testsuite/poke.pkl/struct-ind-2.pk      |   9 ++
 testsuite/poke.pkl/struct-ind-3.pk      |  10 ++
 testsuite/poke.pkl/struct-ind-4.pk      |   9 ++
 testsuite/poke.pkl/struct-ind-diag-1.pk |   9 ++
 testsuite/poke.pkl/struct-ind-diag-2.pk |   9 ++
 testsuite/poke.pkl/struct-ind-diag-3.pk |   9 ++
 testsuite/poke.pkl/struct-ind-diag-4.pk |   9 ++
 19 files changed, 283 insertions(+), 11 deletions(-)
 create mode 100644 testsuite/poke.pkl/ass-ind-1.pk
 create mode 100644 testsuite/poke.pkl/ass-ind-2.pk
 create mode 100644 testsuite/poke.pkl/struct-ind-1.pk
 create mode 100644 testsuite/poke.pkl/struct-ind-2.pk
 create mode 100644 testsuite/poke.pkl/struct-ind-3.pk
 create mode 100644 testsuite/poke.pkl/struct-ind-4.pk
 create mode 100644 testsuite/poke.pkl/struct-ind-diag-1.pk
 create mode 100644 testsuite/poke.pkl/struct-ind-diag-2.pk
 create mode 100644 testsuite/poke.pkl/struct-ind-diag-3.pk
 create mode 100644 testsuite/poke.pkl/struct-ind-diag-4.pk

diff --git a/ChangeLog b/ChangeLog
index c7da75de..2a777004 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2023-03-05  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * libpoke/pkl-ast.h (PKL_AST_STRUCT_REF_INDIRECTION_P): Define.
+       (struct pkl_ast_struct_ref): New field indirection_p.
+       * libpoke/pkl-tab.y: New token IND.
+       (primary): New rule for indirecting struct fields.
+       * libpoke/pkl-lex.l: Recognize token IND.
+       * libpoke/pkl-typify.c (pkl_typify1_ps_struct_ref): Handle
+       indirected struct references.
+       * libpoke/pkl-trans.c (pkl_trans2_ps_struct_ref): Transform
+       indirected struct references into mapping operations.
+       * libpoke/pkl-gen.c (pkl_gen_ps_struct_ref): Support indirections.
+       (pkl_gen_pr_ass_stmt): Likewise.
+       * testsuite/poke.pkl/struct-ind-diag-1.pk: New test.
+       * testsuite/poke.pkl/struct-ind-diag-2.pk: Likewise.
+       * testsuite/poke.pkl/struct-ind-diag-3.pk: Likewise.
+       * testsuite/poke.pkl/struct-ind-diag-4.pk: Likewise.
+       * testsuite/poke.pkl/struct-ind-1.pk: Likewise.
+       * testsuite/poke.pkl/struct-ind-2.pk: Likewise.
+       * testsuite/poke.pkl/struct-ind-3.pk: Likewise.
+       * testsuite/poke.pkl/struct-ind-4.pk: Likewise.
+       * testsuite/poke.pkl/ass-ind-1.pk: Likewise.
+       * testsuite/poke.pkl/ass-ind-2.pk: Likewise.
+       * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
+
 2023-02-12  Jose E. Marchesi  <jemarch@gnu.org>
 
        * libpoke/pkl-ast.h (struct pkl_ast_type): New field ref_type in
diff --git a/libpoke/pkl-ast.c b/libpoke/pkl-ast.c
index 16133544..4ec0f564 100644
--- a/libpoke/pkl-ast.c
+++ b/libpoke/pkl-ast.c
@@ -2489,6 +2489,7 @@ pkl_ast_node_free_1 (gl_set_t visitations, pkl_ast_node 
ast)
 
       PKL_AST_NODE_FREE (PKL_AST_STRUCT_REF_STRUCT (ast));
       PKL_AST_NODE_FREE (PKL_AST_STRUCT_REF_IDENTIFIER (ast));
+      PKL_AST_NODE_FREE (PKL_AST_STRUCT_REF_ORIG_TYPE (ast));
       break;
 
     case PKL_AST_STRUCT_FIELD:
@@ -3393,6 +3394,8 @@ pkl_ast_print_1 (FILE *fp, pkl_ast_node ast, int indent)
       PRINT_AST_SUBAST (type, TYPE);
       PRINT_AST_SUBAST (struct, STRUCT_REF_STRUCT);
       PRINT_AST_SUBAST (identifier, STRUCT_REF_IDENTIFIER);
+      if (PKL_AST_STRUCT_REF_ORIG_TYPE (ast))
+        PRINT_AST_SUBAST (orig_type, STRUCT_REF_ORIG_TYPE);
       break;
 
     case PKL_AST_DECL:
diff --git a/libpoke/pkl-ast.h b/libpoke/pkl-ast.h
index 41c5b317..e5c06be4 100644
--- a/libpoke/pkl-ast.h
+++ b/libpoke/pkl-ast.h
@@ -744,11 +744,17 @@ pkl_ast_node pkl_ast_make_indexer (pkl_ast ast,
                                      pkl_ast_node index);
 
 /* PKL_AST_STRUCT_REF nodes represent references to a struct
-   element.  */
+   element.
+
+   If INDIRECTION_P is nonzero, then this node represents the indirection
+   of the struct element instead of a reference to the field itself.  In
+   these cases, the element must be of type referring offset.  */
 
 #define PKL_AST_STRUCT_REF_STRUCT(AST) ((AST)->sref.sct)
 #define PKL_AST_STRUCT_REF_IDENTIFIER(AST) ((AST)->sref.identifier)
 #define PKL_AST_STRUCT_REF_IS_PARENTHESIZED(AST) ((AST)->sref.is_parenthesized)
+#define PKL_AST_STRUCT_REF_INDIRECTION_P(AST) ((AST)->sref.indirection_p)
+#define PKL_AST_STRUCT_REF_ORIG_TYPE(AST) ((AST)->sref.orig_type)
 
 struct pkl_ast_struct_ref
 {
@@ -756,7 +762,9 @@ struct pkl_ast_struct_ref
 
   union pkl_ast_node *sct;
   union pkl_ast_node *identifier;
+  union pkl_ast_node *orig_type;
   int is_parenthesized;
+  int indirection_p;
 };
 
 pkl_ast_node pkl_ast_make_struct_ref (pkl_ast ast,
diff --git a/libpoke/pkl-gen.c b/libpoke/pkl-gen.c
index 8ed59586..ac4928af 100644
--- a/libpoke/pkl-gen.c
+++ b/libpoke/pkl-gen.c
@@ -835,6 +835,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_ass_stmt)
   pkl_ast_node exp = PKL_AST_ASS_STMT_EXP (ass_stmt);
   pvm_program_label done = pkl_asm_fresh_label (PKL_GEN_ASM);
   int assigning_computed_field_p = 0;
+  int assigning_to_indirection_p = 0;
   const char *computed_field_name = NULL;
 
   if (exp)
@@ -847,6 +848,10 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_ass_stmt)
   /* At this point the r-value, generated from executing EXP, is in
      the stack.  */
 
+  /* Determine whether we are assigning to an indirection.  */
+  assigning_to_indirection_p = (PKL_AST_CODE (lvalue) == PKL_AST_STRUCT_REF
+                                && PKL_AST_STRUCT_REF_INDIRECTION_P (lvalue));
+
   /* Determine whether we are assigning to a computed field in a
      struct.  */
   if (PKL_AST_CODE (lvalue) == PKL_AST_STRUCT_REF)
@@ -883,6 +888,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_ass_stmt)
      to reflect the effect of the assignment in the corresponding IO
      space.  */
   if (!assigning_computed_field_p
+      && !assigning_to_indirection_p
       && (PKL_AST_CODE (lvalue) == PKL_AST_INDEXER
           || PKL_AST_CODE (lvalue) == PKL_AST_STRUCT_REF)
       && (PKL_AST_TYPE_CODE (lvalue_type) == PKL_TYPE_ARRAY
@@ -1045,6 +1051,56 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_ass_stmt)
 
             free (setter);
           }
+        else if (assigning_to_indirection_p)
+          {
+            /* SCT->ID = VAL */
+            /* Stack: VAL SCT ID */
+
+            pvm_program_label mapped = pkl_asm_fresh_label (PKL_GEN_ASM);
+
+            /* The referred field contains the offset where to write
+               VAL.  */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_SREF);
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP); /* VAL SCT OFF */
+
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_SWAP); /* VAL OFF SCT */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MM);   /* VAL OFF SCT MAPPED_P 
*/
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_BNZI, mapped);
+
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                          pvm_make_exception (PVM_E_MAP, PVM_E_MAP_NAME,
+                                              PVM_E_MAP_ESTATUS, NULL, NULL));
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_RAISE);
+
+            pkl_asm_label (PKL_GEN_ASM, mapped);
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP); /* VAL OFF SCT */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MGETIOS); /* VAL OFF SCT IOS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP); /* VAL OFF IOS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_SWAP); /* VAL IOS OFF */
+
+            /* We need a bit-offset.  */
+            {
+              pkl_ast_node ref_orig_type = PKL_AST_STRUCT_REF_ORIG_TYPE 
(lvalue);
+              pkl_ast_node u64t = pkl_ast_make_integral_type (PKL_PASS_AST, 
64, 0);
+
+              assert (PKL_AST_TYPE_CODE (ref_orig_type) == PKL_TYPE_OFFSET);
+
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_OGETM); /* ... OFF MAGNITUDE 
*/
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NTON,
+                            PKL_AST_TYPE_O_BASE_TYPE (ref_orig_type),
+                            u64t);
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP); /* ... OFF NMAGNITUDE 
*/
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_SWAP); /* ... NMAGNITUDE OFF 
*/
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_OGETU);
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP); /* ... NMAGNITUDE UNIT 
*/
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MULLU);
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP2); /* (NMAGNITUDE*UNIT) 
*/
+              u64t = ASTREF (u64t); pkl_ast_node_free (u64t);
+            }
+
+            /* VAL IOS BOFF */
+            LMAP (PKL_AST_TYPE (lvalue)); /* _ */
+          }
         else
           {
             /* Assigning to a regular struct field.  */
@@ -2940,13 +2996,68 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_struct_ref)
         {
           /* This is either a field or a method.  */
           pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_SREF);
-          /* If the parent is a funcall and the referred field is a struct
-             method, then leave both the struct and the closure.  */
-          if (PKL_GEN_IN_CTX_P (PKL_GEN_CTX_IN_FUNCALL)
-              && !PKL_PASS_PARENT && !is_field_p)
-            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP);
+          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP); /* STRUCT ELEM */
+
+          /* If this is an indirecting struct_ref, now we have to map
+             the value using the offset that is on top of the stack,
+             using the mapping attributes of the containing struct.
+             If the struct value is not mapped, then we raise
+             E_no_map.  */
+          if (PKL_AST_STRUCT_REF_INDIRECTION_P (struct_ref))
+            {
+              pvm_program_label mapped = pkl_asm_fresh_label (PKL_GEN_ASM);
+
+                                                         /* STRUCT ELEM */
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_TOR);  /* STRUCT [ELEM] */
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MM);   /* STRUCT MAPPED_P 
[ELEM] */
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_BNZI, mapped);
+
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                            pvm_make_exception (PVM_E_MAP, PVM_E_MAP_NAME,
+                                                PVM_E_MAP_ESTATUS, NULL, 
NULL));
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_RAISE);
+
+              pkl_asm_label (PKL_GEN_ASM, mapped);
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP); /* STRUCT [ELEM] */
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MGETS); /* STRUCT STRICT 
[ELEM] */
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_SWAP);  /* STRICT STRUCT 
[ELEM] */
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MGETIOS); /* STRICT STRUCT 
IOS [ELEM] */
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP); /* STRICT IOS [ELEM] */
+              pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_FROMR); /* STRICT IOS ELEM */
+              /* We need a bit offset.  */
+              {
+                pkl_ast_node ref_orig_type = PKL_AST_STRUCT_REF_ORIG_TYPE 
(struct_ref);
+                pkl_ast_node u64t = pkl_ast_make_integral_type (PKL_PASS_AST, 
64, 0);
+
+                assert (PKL_AST_TYPE_CODE (ref_orig_type) == PKL_TYPE_OFFSET);
+
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_OGETM); /* STRICT IOS ELEM 
MAGNITUDE */
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NTON,
+                              PKL_AST_TYPE_O_BASE_TYPE (ref_orig_type),
+                              u64t);
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP); /* STRICT IOS ELEM 
NMAGNITUDE */
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_SWAP); /* STRICT IOS 
NMAGNITUDE ELEM */
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_OGETU);
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP); /* STRICT IOS 
NMAGNITUDE UNIT */
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MULLU);
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP2); /* STRICT IOS 
(NMAGNITUDE*UNIT) */
+                u64t = ASTREF (u64t); pkl_ast_node_free (u64t);
+              }
+              /* Ok, map.  */
+              PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_MAPPER);
+              PKL_PASS_SUBPASS (struct_ref_type);
+              PKL_GEN_POP_CONTEXT;
+            }
           else
-            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP2);
+            {
+                                                   /* STRUCT ELEM */
+              /* If the parent is a funcall and the referred field was
+                 a struct method, then leave both the struct and the
+                 closure.  */
+              if (!(PKL_GEN_IN_CTX_P (PKL_GEN_CTX_IN_FUNCALL)
+                    && !PKL_PASS_PARENT && !is_field_p))
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP);
+            }
         }
 
       /* To cover cases where the referenced struct is not mapped, but
diff --git a/libpoke/pkl-lex.l b/libpoke/pkl-lex.l
index e64462c3..a1e051f6 100644
--- a/libpoke/pkl-lex.l
+++ b/libpoke/pkl-lex.l
@@ -336,6 +336,7 @@ S ::
 ".>>"                { return SR; }
 "++"                { return INC; }
 "--"                { return DEC; }
+"->"                { return IND; }
 
 "["                { return '['; }
 "]"                { return ']'; }
diff --git a/libpoke/pkl-tab.y b/libpoke/pkl-tab.y
index 2fe17b65..89951957 100644
--- a/libpoke/pkl-tab.y
+++ b/libpoke/pkl-tab.y
@@ -513,6 +513,7 @@ load_module (struct pkl_parser *parser,
 %token AS               _("cast operator")
 %token ISA              _("type identification operator")
 %token '.'              _("dot operator")
+%token IND              _("indirection operator")
 %token <ast> ATTR       _("attribute")
 %token UNMAP            _("unmap operator")
 %token REMAP            _("remap operator")
@@ -551,7 +552,7 @@ load_module (struct pkl_parser *parser,
 %right AS ISA
 %right UNARY
 %left HYPERUNARY
-%left '.'
+%left '.' IND
 %left ATTR
 
 %type <opcode> unary_operator
@@ -1152,6 +1153,13 @@ primary:
                     PKL_AST_LOC ($3) = @3;
                     PKL_AST_LOC ($$) = @$;
                 }
+        | primary IND identifier
+                {
+                    $$ = pkl_ast_make_struct_ref (pkl_parser->ast, $1, $3);
+                    PKL_AST_STRUCT_REF_INDIRECTION_P ($$) = 1;
+                    PKL_AST_LOC ($3) = @3;
+                    PKL_AST_LOC ($$) = @$;
+                }
         | primary '[' expression ']' %prec '.'
                 {
                   $$ = pkl_ast_make_indexer (pkl_parser->ast, $1, $3);
diff --git a/libpoke/pkl-trans.c b/libpoke/pkl-trans.c
index b8184557..fe483695 100644
--- a/libpoke/pkl-trans.c
+++ b/libpoke/pkl-trans.c
@@ -1689,8 +1689,7 @@ PKL_PHASE_END_HANDLER
    Also, struct references that refer to parameterless methods are
    transformed into funcalls to these methods, but only if the struct
    references are not part of funcall themselves.  This is similar to
-   what is done with variable nodes. */
-
+   what is done with variable nodes.  */
 
 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_struct_ref)
 {
diff --git a/libpoke/pkl-typify.c b/libpoke/pkl-typify.c
index d81dfdc8..61a45dbf 100644
--- a/libpoke/pkl-typify.c
+++ b/libpoke/pkl-typify.c
@@ -1649,7 +1649,11 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_struct_field)
 PKL_PHASE_END_HANDLER
 
 /* The type of a STRUCT_REF is the type of the referred element in the
-   struct.  */
+   struct.
+
+   But if the STRUCT_REF is an indirection, then the type of the
+   indirected field should be a referring offset, and the type of
+   the STRUCT_REF is the type of the referred value.  */
 
 PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_struct_ref)
 {
@@ -1711,6 +1715,23 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_struct_ref)
       PKL_PASS_ERROR;
     }
 
+  if (PKL_AST_STRUCT_REF_INDIRECTION_P (struct_ref))
+    {
+      if (PKL_AST_TYPE_CODE (type) != PKL_TYPE_OFFSET
+          || !PKL_AST_TYPE_O_REF_TYPE (type))
+        {
+          PKL_ERROR (PKL_AST_LOC (field_name),
+                     "field `%s' should be a referring offset",
+                     PKL_AST_IDENTIFIER_POINTER (field_name));
+          PKL_TYPIFY_PAYLOAD->errors++;
+          PKL_PASS_ERROR;
+        }
+
+      PKL_AST_STRUCT_REF_ORIG_TYPE (struct_ref)
+        = ASTREF (type);
+      type = PKL_AST_TYPE_O_REF_TYPE (type);
+    }
+
   PKL_AST_TYPE (struct_ref) = ASTREF (type);
 }
 PKL_PHASE_END_HANDLER
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 99d28d8d..2b1b8bcd 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -884,6 +884,8 @@ EXTRA_DIST = \
   poke.pkl/ass-diag-9.pk \
   poke.pkl/ass-diag-10.pk \
   poke.pkl/ass-function-1.pk \
+  poke.pkl/ass-ind-1.pk \
+  poke.pkl/ass-ind-2.pk \
   poke.pkl/ass-offset-1.pk \
   poke.pkl/ass-struct-int-1.pk \
   poke.pkl/ass-struct-int-2.pk \
@@ -2449,6 +2451,14 @@ EXTRA_DIST = \
   poke.pkl/struct-field-pretty-print-1.pk \
   poke.pkl/struct-field-pretty-print-diag-1.pk \
   poke.pkl/struct-field-pretty-print-diag-2.pk \
+  poke.pkl/struct-ind-1.pk \
+  poke.pkl/struct-ind-2.pk \
+  poke.pkl/struct-ind-3.pk \
+  poke.pkl/struct-ind-4.pk \
+  poke.pkl/struct-ind-diag-1.pk \
+  poke.pkl/struct-ind-diag-2.pk \
+  poke.pkl/struct-ind-diag-3.pk \
+  poke.pkl/struct-ind-diag-4.pk \
   poke.pkl/struct-method-1.pk \
   poke.pkl/struct-method-2.pk \
   poke.pkl/struct-method-3.pk \
diff --git a/testsuite/poke.pkl/ass-ind-1.pk b/testsuite/poke.pkl/ass-ind-1.pk
new file mode 100644
index 00000000..4c4f6bf3
--- /dev/null
+++ b/testsuite/poke.pkl/ass-ind-1.pk
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+
+type Foo = struct { offset<int<32>,B,uint<8>> ptr; };
+
+/* { dg-command { var foo = Foo{}; } } */
+/* { dg-command { try foo->ptr = 3; catch if E_map { print "caught\n"; } } } */
+/* { dg-output "caught" } */
diff --git a/testsuite/poke.pkl/ass-ind-2.pk b/testsuite/poke.pkl/ass-ind-2.pk
new file mode 100644
index 00000000..1d016355
--- /dev/null
+++ b/testsuite/poke.pkl/ass-ind-2.pk
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x04 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} } */
+
+type Foo = struct { offset<uint<8>,4,uint<8>> ptr; };
+
+/* { dg-command { .set obase 16 } } */
+/* { dg-command { (Foo @ 0#B)->ptr = 0xff } } */
+/* { dg-command { uint<8> @ 2#B } } */
+/* { dg-output "0xffUB" } */
diff --git a/testsuite/poke.pkl/struct-ind-1.pk 
b/testsuite/poke.pkl/struct-ind-1.pk
new file mode 100644
index 00000000..1df8cc82
--- /dev/null
+++ b/testsuite/poke.pkl/struct-ind-1.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+type Foo = struct { offset<uint<64>,B,int> ptr; };
+
+/* { dg-command { try Foo{}->ptr; catch if E_map { print "caught\n"; } } } */
+/* { dg-output "caught" } */
diff --git a/testsuite/poke.pkl/struct-ind-2.pk 
b/testsuite/poke.pkl/struct-ind-2.pk
new file mode 100644
index 00000000..45a7dae7
--- /dev/null
+++ b/testsuite/poke.pkl/struct-ind-2.pk
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x04 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} } */
+
+type Foo = struct { offset<uint<8>,B,uint<8>> ptr; };
+
+/* { dg-command { .set endian big } } */
+/* { dg-command {.set obase 16} } */
+/* { dg-command { (Foo @ 0#B)->ptr } } */
+/* { dg-output "0x50UB" } */
diff --git a/testsuite/poke.pkl/struct-ind-3.pk 
b/testsuite/poke.pkl/struct-ind-3.pk
new file mode 100644
index 00000000..ef307a3b
--- /dev/null
+++ b/testsuite/poke.pkl/struct-ind-3.pk
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x00 0x00 0x09  0x00 0x00 0x00 0x00   0x90 0xa0 0xb0 
0xc0} } */
+
+type Foo = struct { offset<int<32>,B,uint<8>> ptr; };
+
+/* { dg-command { .set endian big } } */
+/* { dg-command {.set obase 16} } */
+/* { dg-command { var f = Foo @ 0#B; } } */
+/* { dg-command { f->ptr } } */
+/* { dg-output "0xa0UB" } */
diff --git a/testsuite/poke.pkl/struct-ind-4.pk 
b/testsuite/poke.pkl/struct-ind-4.pk
new file mode 100644
index 00000000..1824175c
--- /dev/null
+++ b/testsuite/poke.pkl/struct-ind-4.pk
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x04 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} } */
+
+type Foo = struct { offset<uint<8>,4,uint<8>> ptr; };
+
+/* { dg-command { .set endian big } } */
+/* { dg-command {.set obase 16} } */
+/* { dg-command { (Foo @ 0#B)->ptr } } */
+/* { dg-output "0x30UB" } */
diff --git a/testsuite/poke.pkl/struct-ind-diag-1.pk 
b/testsuite/poke.pkl/struct-ind-diag-1.pk
new file mode 100644
index 00000000..19b991d5
--- /dev/null
+++ b/testsuite/poke.pkl/struct-ind-diag-1.pk
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+type Foo =
+  struct
+  {
+    int foo;
+  };
+
+(Foo {})->bar; /* { dg-error "" } */
diff --git a/testsuite/poke.pkl/struct-ind-diag-2.pk 
b/testsuite/poke.pkl/struct-ind-diag-2.pk
new file mode 100644
index 00000000..e4ccd43d
--- /dev/null
+++ b/testsuite/poke.pkl/struct-ind-diag-2.pk
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+type Foo =
+  struct
+  {
+    int foo;
+  };
+
+(Foo {})->foo; /* { dg-error "referring offset" } */
diff --git a/testsuite/poke.pkl/struct-ind-diag-3.pk 
b/testsuite/poke.pkl/struct-ind-diag-3.pk
new file mode 100644
index 00000000..60ebfd4c
--- /dev/null
+++ b/testsuite/poke.pkl/struct-ind-diag-3.pk
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+type Foo =
+  struct
+  {
+    offset<uint<32>,B> foo;
+  };
+
+(Foo {})->foo; /* { dg-error "referring offset" } */
diff --git a/testsuite/poke.pkl/struct-ind-diag-4.pk 
b/testsuite/poke.pkl/struct-ind-diag-4.pk
new file mode 100644
index 00000000..63c7210a
--- /dev/null
+++ b/testsuite/poke.pkl/struct-ind-diag-4.pk
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+type Foo =
+  struct
+  {
+    offset<int<32>,B,int> foo;
+  };
+
+(Foo {})->foo + 2#B; /* { dg-error "invalid operand.*\n.*expected integral" } 
*/
-- 
2.30.2




reply via email to

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