[COMMITTED] a68: avoid indirect calls to publicized C functions
Jose E. Marchesi
jemarch@gnu.org
Sun Feb 1 22:12:36 GMT 2026
Publicized identifiers of proc modes with the form:
pub proc(int)int fclose = nest C "_libga68_posixclose"
currently results in a export like:
iden extract: POSIX_fclose [*.LMD11] variable=0 inproc=0
Note how the "inproc" export flag is not set. This causes the
resulting applied identifier in calls to fclose to be lowered to a
VAR_DECL rather than a FUNCTION_DECL, resulting in an indirect call.
This patch makes the parser to mark identity declarations of proc
modes whose actual parameters are formal holes as "inproc".
Signed-off-by: Jose E. Marchesi <jemarch@gnu.org>
gcc/algol68/ChangeLog
* a68.h: Prototype for a68_make_proc_formal_hole_decl.
* a68-parser-extract.cc (extract_identities): Mark identity
declarations of proc modes whose actual parameter is a formal hole
as "inproc".
* a68-low.cc (a68_make_proc_formal_hole_decl): New function.
* a68-low-units.cc (a68_lower_formal_hole): Call
a68_make_proc_formal_hole_decl whenever necessary.
---
gcc/algol68/a68-low-units.cc | 7 ++++++-
gcc/algol68/a68-low.cc | 27 +++++++++++++++++++++++++++
gcc/algol68/a68-parser-extract.cc | 7 +++++++
gcc/algol68/a68.h | 1 +
4 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/gcc/algol68/a68-low-units.cc b/gcc/algol68/a68-low-units.cc
index 4584ff10933..4002a4b608a 100644
--- a/gcc/algol68/a68-low-units.cc
+++ b/gcc/algol68/a68-low-units.cc
@@ -1256,7 +1256,12 @@ a68_lower_formal_hole (NODE_T *p, LOW_CTX_T ctx ATTRIBUTE_UNUSED)
gcc_assert (IS (str, ROW_CHAR_DENOTATION));
char *symbol = a68_string_process_breaks (p, NSYMBOL (str));
- tree decl = a68_make_formal_hole_decl (p, symbol);
+
+ tree decl;
+ if (IS (MOID (p), PROC_SYMBOL))
+ decl = a68_make_proc_formal_hole_decl (p, symbol);
+ else
+ decl = a68_make_formal_hole_decl (p, symbol);
return decl;
}
diff --git a/gcc/algol68/a68-low.cc b/gcc/algol68/a68-low.cc
index dee1a6d26c5..1f341aaa977 100644
--- a/gcc/algol68/a68-low.cc
+++ b/gcc/algol68/a68-low.cc
@@ -660,6 +660,33 @@ a68_make_formal_hole_decl (NODE_T *p, const char *extern_symbol)
return decl;
}
+/* Make an extern declaration for a formal hole that is a function. */
+
+tree
+a68_make_proc_formal_hole_decl (NODE_T *p, const char *extern_symbol)
+{
+ /* The CTYPE of MODE is a pointer to a function. We need the pointed
+ function type for the FUNCTION_DECL. */
+ tree type = TREE_TYPE (CTYPE (MOID (p)));
+
+ gcc_assert (strlen (extern_symbol) > 0);
+ const char *sym = (extern_symbol[0] == '&'
+ ? extern_symbol + 1
+ : extern_symbol);
+
+ tree decl = build_decl (a68_get_node_location (p),
+ FUNCTION_DECL,
+ get_identifier (sym),
+ type);
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ DECL_INITIAL (decl) = a68_get_skip_tree (MOID (p));
+
+ if (extern_symbol[0] == '&')
+ decl = fold_build1 (ADDR_EXPR, type, decl);
+ return decl;
+}
+
/* Do a checked indirection.
P is a tree node used for its location information.
diff --git a/gcc/algol68/a68-parser-extract.cc b/gcc/algol68/a68-parser-extract.cc
index 4779d3915f4..32a9933bd72 100644
--- a/gcc/algol68/a68-parser-extract.cc
+++ b/gcc/algol68/a68-parser-extract.cc
@@ -758,6 +758,7 @@ extract_identities (NODE_T *p)
FORWARD (q);
}
+ NODE_T *declarer = q;
do
{
if (a68_whether ((FORWARD (q)), IDENTIFIER, EQUALS_SYMBOL, STOP))
@@ -767,6 +768,12 @@ extract_identities (NODE_T *p)
gcc_unreachable ();
ATTRIBUTE (q) = DEFINING_IDENTIFIER;
PUBLICIZED (q) = is_public;
+ if (IS (SUB (declarer), PROC_SYMBOL))
+ {
+ NODE_T *actual_param = NEXT (NEXT (q));
+ if (actual_param != NO_NODE && IS (actual_param, FORMAL_NEST_SYMBOL))
+ IN_PROC (tag) = true;
+ }
FORWARD (q);
ATTRIBUTE (q) = ALT_EQUALS_SYMBOL;
q = skip_unit (q);
diff --git a/gcc/algol68/a68.h b/gcc/algol68/a68.h
index cb8bcef4950..c0fc8bedb94 100644
--- a/gcc/algol68/a68.h
+++ b/gcc/algol68/a68.h
@@ -815,6 +815,7 @@ tree a68_make_proc_identity_declaration_decl (NODE_T *identifier, const char *mo
bool indicant = false, bool external = false,
const char *extern_symbol = NULL);
tree a68_make_formal_hole_decl (NODE_T *p, const char *extern_symbol);
+tree a68_make_proc_formal_hole_decl (NODE_T *p, const char *extern_symbol);
tree a68_make_anonymous_routine_decl (MOID_T *mode);
tree a68_get_skip_tree (MOID_T *m);
tree a68_get_empty (void);
--
2.39.5
More information about the Algol68
mailing list