[COMMITTED] a68: guard execution of top-level module preludes and postludes
Jose E. Marchesi
jemarch@gnu.org
Thu Nov 20 13:28:08 GMT 2025
---
gcc/algol68/a68-low.cc | 88 ++++++++++++++++---
.../algol68/execute/modules/module16.a68 | 8 ++
.../algol68/execute/modules/program-16.a68 | 8 ++
3 files changed, 90 insertions(+), 14 deletions(-)
create mode 100644 gcc/testsuite/algol68/execute/modules/module16.a68
create mode 100644 gcc/testsuite/algol68/execute/modules/program-16.a68
diff --git a/gcc/algol68/a68-low.cc b/gcc/algol68/a68-low.cc
index 7d2b5e97472..859d873c28e 100644
--- a/gcc/algol68/a68-low.cc
+++ b/gcc/algol68/a68-low.cc
@@ -1240,6 +1240,19 @@ lower_module_text (NODE_T *p, LOW_CTX_T ctx)
: NEXT (def_part));
NODE_T *prelude_enquiry = NEXT_SUB (def_part);
+ /* The global sentinel of the module, initialized to 0. */
+ tree sentinel_decl = build_decl (UNKNOWN_LOCATION,
+ VAR_DECL, NULL /* name */,
+ sizetype);
+ char *sentinel_name = xasprintf ("%s__sentinel", ctx.module_definition_name);
+ DECL_NAME (sentinel_decl) = get_identifier (sentinel_name);
+ free (sentinel_name);
+ TREE_PUBLIC (sentinel_decl) = 0;
+ TREE_STATIC (sentinel_decl) = 1;
+ DECL_CONTEXT (sentinel_decl) = NULL_TREE; /* File scope. */
+ make_decl_rtl (sentinel_decl);
+ varpool_node::finalize_decl (sentinel_decl);
+
/* Create the prelude function. */
tree prelude_decl = build_decl (a68_get_node_location (def_part),
FUNCTION_DECL,
@@ -1255,10 +1268,34 @@ lower_module_text (NODE_T *p, LOW_CTX_T ctx)
a68_push_function_range (prelude_decl,
void_type_node /* result_type */, true /* top_level */);
- /* Add calls to preludes of modules in REVELATION_PART. */
- lower_revelations (revelation_part, ctx, true /* prelude */);
- tree prelude_body_expr = a68_lower_tree (prelude_enquiry, ctx);
- a68_pop_function_range (prelude_body_expr);
+ {
+ /* Increase sentinel. */
+ a68_add_stmt (fold_build2 (POSTINCREMENT_EXPR,
+ sizetype,
+ sentinel_decl, size_one_node));
+
+ a68_push_stmt_list (M_VOID);
+ {
+ a68_push_stmt_list (M_VOID);
+ {
+ /* Add calls to preludes of modules in REVELATION_PART. */
+ lower_revelations (revelation_part, ctx, true /* prelude */);
+ a68_add_stmt (a68_lower_tree (prelude_enquiry, ctx));
+ }
+ tree do_prelude = a68_pop_stmt_list ();
+
+ a68_push_stmt_list (M_VOID);
+ tree do_nothing = a68_pop_stmt_list ();
+
+ /* Do the prelude work only if sentinel is 1. */
+ a68_add_stmt (fold_build3 (COND_EXPR, void_type_node,
+ fold_build2 (EQ_EXPR, sizetype,
+ sentinel_decl, size_one_node),
+ do_prelude, do_nothing));
+ }
+ tree prelude_body = a68_pop_stmt_list ();
+ a68_pop_function_range (prelude_body);
+ }
/* Create the postlude function. This is done even if the module definition
has no postlude in the source code. */
@@ -1277,19 +1314,42 @@ lower_module_text (NODE_T *p, LOW_CTX_T ctx)
DECL_EXTERNAL (postlude_decl) = 0;
TREE_PUBLIC (postlude_decl) = 1;
TREE_STATIC (postlude_decl) = 1;
-
+
a68_push_function_range (postlude_decl,
void_type_node /* result_type */, true /* top_level */);
+ {
+ /* Decrease sentinel. */
+ a68_add_stmt (fold_build2 (POSTINCREMENT_EXPR,
+ sizetype,
+ sentinel_decl, size_one_node));
- NODE_T *postlude_serial = NO_NODE;
- if (postlude_part != NO_NODE)
- postlude_serial = NEXT_SUB (postlude_part);
- /* Add calls to postludes of modules in REVELATION_PART. */
- lower_revelations (revelation_part, ctx, false /* prelude */);
- tree postlude_body_expr = NULL_TREE;
- if (postlude_serial != NO_NODE)
- postlude_body_expr = a68_lower_tree (postlude_serial, ctx);
- a68_pop_function_range (postlude_body_expr);
+ a68_push_stmt_list (M_VOID);
+ {
+ a68_push_stmt_list (M_VOID);
+ {
+ /* Add calls to postludes of modules in REVELATION_PART. */
+ lower_revelations (revelation_part, ctx, false /* prelude */);
+ /* Perhaps the postlude code, if there is one. */
+ NODE_T *postlude_serial = NO_NODE;
+ if (postlude_part != NO_NODE)
+ postlude_serial = NEXT_SUB (postlude_part);
+ if (postlude_serial != NO_NODE)
+ a68_add_stmt (a68_lower_tree (postlude_serial, ctx));
+ }
+ tree do_postlude = a68_pop_stmt_list ();
+
+ a68_push_stmt_list (M_VOID);
+ tree do_nothing = a68_pop_stmt_list ();
+
+ /* Do the postlude work only if sentinel is 0. */
+ a68_add_stmt (fold_build3 (COND_EXPR, void_type_node,
+ fold_build2 (EQ_EXPR, sizetype,
+ sentinel_decl, size_zero_node),
+ do_postlude, do_nothing));
+ }
+ tree postlude_body = a68_pop_stmt_list ();
+ a68_pop_function_range (postlude_body);
+ }
return NULL_TREE;
}
diff --git a/gcc/testsuite/algol68/execute/modules/module16.a68 b/gcc/testsuite/algol68/execute/modules/module16.a68
new file mode 100644
index 00000000000..d798d4ff874
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/modules/module16.a68
@@ -0,0 +1,8 @@
+module Module_16 =
+def
+ pub int counter;
+ skip
+postlude
+ assert (counter = 666);
+ skip
+fed
diff --git a/gcc/testsuite/algol68/execute/modules/program-16.a68 b/gcc/testsuite/algol68/execute/modules/program-16.a68
new file mode 100644
index 00000000000..dd6ddb6b941
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/modules/program-16.a68
@@ -0,0 +1,8 @@
+{ dg-modules module16 }
+
+access Module_16
+begin assert (counter = 0);
+ counter := 20;
+ access Module_16 (assert (counter = 20));
+ counter := 666
+end
--
2.30.2
More information about the Algol68
mailing list