This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] fix tasking problems on ia64-linux and handling of Machine_Attribute


Tested on ia64-linux, committed on mainline.

Fix tasking problems on ia64-linux:
Exception handler choices have to be materialized in the GCC EH tables,
and the GCC model for that is a pointer to some exception type information
or 0 for C++ catch all statements. In Ada, plain exception choices such as
Constraint_Error are materialized by a pointer to the corresponding exception
Id, and special values are used for "others" and "all others" choices because
they don't behave quite like "catch all" in C++. Those special values used to
be harcoded dummy addresses: (void *)0 for "others" and (void *)1 for "all
others", which was not very clean to start with. Besides, this scheme turned
out to be problematic when exposed to some of the various possible EH pointer
encoding policies, as demonstrated by the testcase on ia64-linux, in which
an "all others" handler was just bypassed, causing a rendez-vous not to be
terminated as it should have, in turn resulting in an unexpected hang.
The fix is to use the address of a dummy object for "others" and "all others"
(one object for each case) instead of the hardcoded dummy addresses, which is
much cleaner and more flexible with respect to the possible pointer encoding
policies.

Testcase:
--  $ gnatmake p.adb
--  $ p
--  ... is expected to terminate and output nothing.
--  The front-end expanded code involves a "when all others" choice to
--  deal with the rendez-vous exceptional completion in the task. This
--  choice would be missed if the address stored in the exception table
--  was not suited for some cases of underlying EH pointer encoding,
--  resulting in a not executed rendez-vous termination and then a hang.

with Ada.Text_IO; use Ada.Text_IO;
procedure P is

   task T is entry E; end T;

   task body T is
   begin
      accept E do raise Constraint_Error; end;
   exception
      when Constraint_Error => raise;
      when others => Put_Line ("Wrong exception propagated");
   end;
begin
   T.E;
exception
   when Constraint_Error => null;
end;

Also fix problems with pragma Machine_Attribute:
GCC expects attribute arguments to be provided as a TREE_LIST of entries
with TREE_VALUES filled. For an attribute argument in a Machine_Attribute
pragma, gigi was passing a bare IDENTIFIER node as the GCC attribute
"args", which clearly did not match the back-end expectations. This is
fixed by constructing the appropriate TREE_LIST in build_attr_list, and
the "arg" component of the gigi "attrib" structure has been renamed "args"
along the way, and by propagating Machine_Attributes to subtypes.

Testcase:
--  $ gcc -c p.adb
--  Expected output:
--  p.ads:1: warning: `regparm' attribute requires an integer constant argument
--  It used to ICE before this change.

procedure P (X : Integer);                                                 
pragma Machine_Attribute (P, "regparm", "1");                                
procedure P (X : Integer) is
begin null; end;

2004-11-18  Olivier Hainque  <hainque@adacore.com>

	* a-exexpr.adb (Others_Value, All_Others_Value): New variables, the
	address of which may be used to represent "others" and "all others"
	choices in exception tables, instead of the current harcoded
	(void *)0 and (void *)1.
	(Setup_Exception): Do nothing in the GNAT SJLJ case.

	* gigi.h (others_decl, all_others_decl): New decls representing the
	new Others_Value and All_Others_Value objects.
	(struct attrib): Rename "arg" component as "args", since GCC expects a
	list of arguments in there.

	* raise.c (GNAT_OTHERS, GNAT_ALL_OTHERS): Are now the address of the
	corresponding objects exported by a-exexpr, instead of hardcoded dummy
	addresses.

	* trans.c (Exception_Handler_to_gnu_zcx): Use the address of
	others_decl and all_others_decl instead of hardcoded dummy addresses
	to represent "others" and "all others" choices, which is cleaner and
	more flexible with respect to the possible eh pointer encoding policies.

	* utils.c (init_gigi_decls): Initialize others_decl and all_others_decl.
	(process_attributes): Account for the naming change of the "args"
	attribute list entry component.

	* decl.c (build_attr_list): Rename into prepend_attributes to allow
	cumulating attributes for different entities into a single list.
	(gnat_to_gnu_entity): Use prepend_attributes to build the list of
	attributes for the current entity and propagate first subtype
	attributes to other subtypes.
	<E_Procedure>: Attribute arguments are attr->args and not
	attr->arg any more.
	(build_attr_list): Ditto. Make attr->args a TREE_LIST when there is an
	argument provided, as this is what GCC expects. Use NULL_TREE instead
	of 0 for trees.

Attachment: difs.2
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]