poke-devel
[Top][All Lists]
Advanced

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

[COMMITTED] pkl: consider struct types as complete if all labels are lit


From: Jose E. Marchesi
Subject: [COMMITTED] pkl: consider struct types as complete if all labels are literal
Date: Thu, 23 Dec 2021 00:22:13 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Field labes that are literal should not result in the containing
struct type to be considered not completed, i.e. this struct type:

struct
{
  int a;
  byte[16] data @ 18#B;
}

Is now considered complete and can therefore be used as an offset
unit.
---
 ChangeLog                            | 14 +++++++++++
 etc/poke.rec                         | 17 -------------
 libpoke/pkl-ast.c                    | 47 ++++++++++++++++++++++++++++++------
 testsuite/Makefile.am                |  3 +++
 testsuite/poke.pkl/offsets-14.pk     |  6 +++++
 testsuite/poke.pkl/offsets-15.pk     |  6 +++++
 testsuite/poke.pkl/offsets-16.pk     |  6 +++++
 testsuite/poke.pkl/offsets-diag-1.pk |  3 ++-
 8 files changed, 77 insertions(+), 25 deletions(-)
 create mode 100644 testsuite/poke.pkl/offsets-14.pk
 create mode 100644 testsuite/poke.pkl/offsets-15.pk
 create mode 100644 testsuite/poke.pkl/offsets-16.pk

diff --git a/ChangeLog b/ChangeLog
index f558a9ed..547403ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2021-12-23  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * libpoke/pkl-ast.c (pkl_ast_type_is_complete): Support constant
+       labels in completed structs.
+       (pkl_ast_sizeof_type): Take into account constant labels in
+       structs.
+       * testsuite/poke.pkl/offsets-14.pk: New test.
+       * testsuite/poke.pkl/offsets-15.pk: Likewise.
+       * testsuite/poke.pkl/offsets-16.pk: Likewise.
+       * testsuite/poke.pkl/offsets-diag-1.pk: Adjust.
+       * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
+       * etc/poke.rec (Consider struct types as complete if all labels
+       are literal): Remove as done.
+
 2021-12-22  Jose E. Marchesi  <jemarch@gnu.org>
 
        * pickles/elf-common.pk (elf_pretty_print_section_flags): New
diff --git a/etc/poke.rec b/etc/poke.rec
index c180fbb5..58768265 100644
--- a/etc/poke.rec
+++ b/etc/poke.rec
@@ -868,23 +868,6 @@ Description:
 + non-strict values.
 RFC: yes
 
-Summary: Consider struct types as complete if all labels are literal
-Component: Compiler
-Kind: OPT
-Priority: 3
-Description:
-+ Field labes that are literal should not result in the containing
-+ struct type to be considered not completed, i.e. this struct type:
-+
-+   struct
-+   {
-+     int a;
-+     byte[16] data @ 18#B;
-+   }
-+
-+ Should be considered complete.
-Target: 2.0
-
 Summary: Unions can be completed
 Component: Compiler
 Kind: OPT
diff --git a/libpoke/pkl-ast.c b/libpoke/pkl-ast.c
index 63deaf7e..69f5a053 100644
--- a/libpoke/pkl-ast.c
+++ b/libpoke/pkl-ast.c
@@ -996,20 +996,49 @@ pkl_ast_sizeof_type (pkl_ast ast, pkl_ast_node type)
             if (PKL_AST_CODE (t) == PKL_AST_STRUCT_TYPE_FIELD)
               {
                 pkl_ast_node elem_type;
+                pkl_ast_node field_label = PKL_AST_STRUCT_TYPE_FIELD_LABEL (t);
 
-                /* Struct fields with labels are not expected, as these
-                   cannot appear in complete struct types.  Ditto for
-                   optional fields.  */
-                assert (PKL_AST_STRUCT_TYPE_FIELD_LABEL (t) == NULL);
+                /* Struct fields with non-constant labels are not
+                   expected, as these cannot appear in complete struct
+                   types.  Ditto for optional fields.  */
+                assert (field_label == NULL
+                        || PKL_AST_CODE (field_label) == PKL_AST_OFFSET);
                 assert (PKL_AST_STRUCT_TYPE_FIELD_OPTCOND (t) == NULL);
 
+                /* If the field has a constant label and the label is
+                   bigger than the current accumulated size, replace
+                   the accumulated size with the label.  */
+                if (field_label)
+                  {
+                    pkl_ast_node label_magnitude, label_in_bits, cond;
+
+                    label_magnitude
+                      = pkl_ast_make_cast (ast, res_type,
+                                           PKL_AST_OFFSET_MAGNITUDE 
(field_label));
+                    PKL_AST_TYPE (label_magnitude) = ASTREF (res_type);
+
+                    label_in_bits = pkl_ast_make_binary_exp (ast,
+                                                             PKL_AST_OP_MUL,
+                                                             label_magnitude,
+                                                             
PKL_AST_OFFSET_UNIT (field_label));
+                    PKL_AST_TYPE (label_in_bits) = ASTREF (res_type);
+
+                    cond = pkl_ast_make_binary_exp (ast, PKL_AST_OP_GT,
+                                                    label_in_bits, res);
+                    PKL_AST_TYPE (cond) = ASTREF (res_type);
+
+                    res = pkl_ast_make_cond_exp (ast, cond, label_in_bits, 
res);
+                    PKL_AST_TYPE (res) = ASTREF (res_type);
+                  }
+
+                /* Add the size of the field to the accumulated
+                   size.  */
                 elem_type = PKL_AST_STRUCT_TYPE_FIELD_TYPE (t);
                 res = pkl_ast_make_binary_exp (ast, PKL_AST_OP_ADD,
                                                res,
                                                pkl_ast_sizeof_type (ast,
                                                                     
elem_type));
                 PKL_AST_TYPE (res) = ASTREF (res_type);
-                PKL_AST_LOC (res) = PKL_AST_LOC (type);
               }
           }
 
@@ -1099,7 +1128,8 @@ pkl_ast_type_is_complete (pkl_ast_node type)
       complete = PKL_AST_TYPE_COMPLETE_NO;
       break;
       /* Struct types are complete if their fields are also of
-         complete types and there are no labels nor optconds.  */
+         complete types and there are non-constant labels nor
+         optconds.  */
     case PKL_TYPE_STRUCT:
       {
         pkl_ast_node elem;
@@ -1109,8 +1139,11 @@ pkl_ast_type_is_complete (pkl_ast_node type)
              elem;
              elem = PKL_AST_CHAIN (elem))
           {
+            pkl_ast_node elem_label
+              = PKL_AST_STRUCT_TYPE_FIELD_LABEL (elem);
+
             if (PKL_AST_CODE (elem) == PKL_AST_STRUCT_TYPE_FIELD
-                && (PKL_AST_STRUCT_TYPE_FIELD_LABEL (elem)
+                && ((elem_label && PKL_AST_CODE (elem_label) != PKL_AST_OFFSET)
                     || PKL_AST_STRUCT_TYPE_FIELD_OPTCOND (elem)
                     || (pkl_ast_type_is_complete 
(PKL_AST_STRUCT_TYPE_FIELD_TYPE (elem))
                         == PKL_AST_TYPE_COMPLETE_NO)))
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index add9f58c..73bcef89 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -1402,6 +1402,9 @@ EXTRA_DIST = \
   poke.pkl/offsets-11.pk \
   poke.pkl/offsets-12.pk \
   poke.pkl/offsets-13.pk \
+  poke.pkl/offsets-14.pk \
+  poke.pkl/offsets-15.pk \
+  poke.pkl/offsets-16.pk \
   poke.pkl/offsets-53.pk \
   poke.pkl/offsets-diag-1.pk \
   poke.pkl/offsets-diag-2.pk \
diff --git a/testsuite/poke.pkl/offsets-14.pk b/testsuite/poke.pkl/offsets-14.pk
new file mode 100644
index 00000000..00688314
--- /dev/null
+++ b/testsuite/poke.pkl/offsets-14.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+type Foo = struct { byte a; byte b @ 2#B; };
+
+/* { dg-command { 1#Foo / #B } } */
+/* { dg-output "3" } */
diff --git a/testsuite/poke.pkl/offsets-15.pk b/testsuite/poke.pkl/offsets-15.pk
new file mode 100644
index 00000000..f39f77cf
--- /dev/null
+++ b/testsuite/poke.pkl/offsets-15.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+type Foo = struct { byte a; byte b @ 1#B + 8#b; };
+
+/* { dg-command { 1#Foo / #B } } */
+/* { dg-output "3" } */
diff --git a/testsuite/poke.pkl/offsets-16.pk b/testsuite/poke.pkl/offsets-16.pk
new file mode 100644
index 00000000..cd9c5fe4
--- /dev/null
+++ b/testsuite/poke.pkl/offsets-16.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+type Foo = struct { byte a @ 1#B; byte b @ 3#B; };
+
+/* { dg-command { 1#Foo / #B } } */
+/* { dg-output "4" } */
diff --git a/testsuite/poke.pkl/offsets-diag-1.pk 
b/testsuite/poke.pkl/offsets-diag-1.pk
index f1f2586c..c69fad7b 100644
--- a/testsuite/poke.pkl/offsets-diag-1.pk
+++ b/testsuite/poke.pkl/offsets-diag-1.pk
@@ -1,5 +1,6 @@
 /* { dg-do compile } */
 
-type Foo = struct { int i @ 0#B; };
+var a = 0;
+type Foo = struct { int i @ a#B; };
 
 var o = 23#Foo; /* { dg-error "complete types" } */
-- 
2.11.0




reply via email to

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