This is the mail archive of the 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] gigi fixes

Tested on i686-linux, committed on trunk.

PR ada/27776.
This is a reimplementation of Gigi support for the Ada 2005 "limited with".
This implementation has Gigi more closely match the Ada semantics in the
handling of when types are to be treated as incomplete.  When using that
feature in Ada 2005, it is possible for a type in the main unit to be "demand
elaborated" just like a type in a withed unit and that confuses the current
code.  This change adds checks to see if a "demand elaborated" entity is
actually in the current unit and has a freeze node and handles it in a manner
consistent with all other incomplete types if it is.

Fix also some glitches in the generation of debug info for Ada constructs,
in particular when creating an Ada Character or Wide_Character type, set the
TYPE_NAME accordingly. This is used by the dwarf-2 writer to set the name of the
base type.
This patch allows the debuggers to know the name of the base character types
(and fixes the command "ptype character" in gdb, for instance).
Similarly, use TYPE_STRING_FLAG to differentiate trees representing Ada
Character types from standard Integer types.
This allows debuggers to know the types of Ada Characters by reading
standard dwarf-2, instead of having to rely on the names of the types.
Fills also a gap in the writing of debug information, which
caused all global Ada declarations to be absent from the debug information.

For a pointer-to-protected-subprogram type, there is an additional hurdle:
its elaboration involves elaborating an associated record type that holds
pointers to the operation and to the protected object.  This type can be
elaborated on its first occurence but its potentially multiple elaboration
must be account for in Gigi.

The testcase gnat.dg/pointer_protected must silently compile.

Functions modelled on the Standard C library function "malloc" are treated
specially by the compiler, in particular by the alias analysis engine which
assumes that the objects pointed to by the returned pointers cannot alias.

This makes it possible to conduct accurate point-to alias analysis for objects
allocated on the heap, disregarding type aliasing violation.
gnat.dg/gnat_malloc.adb should compile and run silently at -O2

The patch converts the global lists static_ctors and static_dtors to vector
of trees and moves the calls to build_global_cdtor to the newly added hook
gnat_write_global_declarations.  It also moves the call to cgraph_optimize
from gnat_parse_file to the new hook.

Both changes are modelled on the C front-end.  They make it possible to keep
the constructor/destructor stuff private to utils.c and give a more accurate
timing for the parsing phase.

When gigi processes an explicit freeze node for an entity, it asserts
that the entity has not been elaborated already on the grounds that the
freeze node was supposed to delay the elaboration until it's occurrence
point. Exceptions to this general rule are accepted for cases in which
it is known that such early elaborations might legitimately happen.

gnat.dg/{s,b} exposes a situation where early elaboration is
legitimate but not anticipated by gigi, triggering a spurious assertion failure
at compile time.

The specific factors here are
   1/ the presence of a freeze node triggering the elaboration of the
   Task_Object type, a Concurrent_Type node, followed by a freeze node for
   the attached internal Corresponding_Record_Type entity,
   2/ the fact that the Concurrent_Type elaboration entails the elaboration
   of the internal Corresponding_Record_Type node.

Gigi aborts while processing the second freeze node, because the entity
has been elaborated already, as part of the processing of the first freeze
node. The fix applied consists of extending the set of legitimate early
elaboration cases expected by gigi in the freeze node processing code, to
cover exactly the situation exposed here.

When a view conversion is used as the actual for a copy-in/copy-out parameter,
the real destination of the copy-out is the variable denoted by the conversion
argument. The type of this real destination is different from the procedure
output type, so the output has to be converted to the destination type and
the GCC node representing the copy-out lhs needs to be properly typed as well.

The GCC node used as the copy-out lhs is retrieved from a list of actuals
constructed for the call. For view conversion arguments of non composite
types, the GCC actual node corresponds to the GNAT conversion node and
was reused as-is for the copy-out assignment.  In addition to the type being
incorrect, a spurious conversion operation remained on the assignment lhs,
triggering gimplification failures (invalid lvalue) if the conversion happened
not to be considered useless.

The fix applied here is to convert the gnu node for the lhs to the inner
expression type when need be, which actually lifts the outer conversion op
introduced for the copy-in.

See gnat.dg/ice_type.adb test case.

While the alignment is counted in bits in the middle-end, it is counted
in bytes (storage units) in the Ada front-end.  The conversion is done
in Gigi correctly for types, but not for components of records.

gnat.dg/alignment1.adb should run silently

The gimplifier marks memory operands of inline asms as
addressable.  Now it is too late to simply do that in the gimplifier because
gimplification of earlier expressions might have had a different outcome,
had the addressability flag been set on a variable.  In particular, loads from
memory variables are made explicit so is_gimple_val may suddenly become false
as the result of toggling the addressability flag.

The fix is to toggle the addressability flag in Gigi, as the C and C++
compilers do in their respective front-end, using support code from stmt.c.

gnat.dg/machine_code1.adb should now flawlessly compile.

When an abstract function that is a tagged primitive has an anonymous access
result type, then dispatching calls to the function cause Gigi abort 122
because the itype associated with the result of the indirect call has not
been elaborated by Gigi. We now process such itypes when the abstract function
declaration is translated.

gnat.dg/abstract_with_anonymous_result.adb must compile and execute quietly

Finally, with a subtype like this:

   type T is (a, b, c, d, e);
   S is T range b .. d;
   subtype S1 is S range a .. d;

S1 has a low bound out of range. The translation of this code by gigi is
the creation of a variable for the lower bound of S1. Therefore, when we
use S1 in a "when" of a case statement, we insert a variable in the list
of cased values. Unfortunately, gcc 4.1 gimplifier requires now to have
only null or integer constant nodes there, and crash when it reads the
variable. This patch removes the whole "when" block when its only choice is
wrong, or removes only the problematic choice if there are other valid ones.

See gnat.dg/case_null.adb test

2006-10-31  Eric Botcazou  <>
	    Nicolas Setton  <>
	    Olivier Hainque  <>
	    Gary Dismukes  <>

	* gigi.h: (tree_code_for_record_type): Declare.
	(add_global_renaming_pointer): Rename to record_global_renaming_pointer.
	(get_global_renaming_pointers): Rename to
	(static_ctors): Delete.
	(static_dtors): Likewise.
	(gnat_write_global_declarations): Declare.
	(create_var_decl): Adjust descriptive comment to indicate that the
	subprogram may return a CONST_DECL node.
	(create_true_var_decl): Declare new function, similar to
	create_var_decl but forcing the creation of a VAR_DECL node.
	(get_global_renaming_pointers): Declare.
	(add_global_renaming_pointer): Likewise.

	* ada-tree.h (DECL_READONLY_ONCE_ELAB): New macro.

	* decl.c (gnat_to_gnu_entity) <case E_Function>: Don't copy the type
	tree before setting TREE_ADDRESSABLE for by-reference return mechanism
	(gnat_to_gnu_entity): Remove From_With_Type from computation for
	<E_Access_Type>: Use the Non_Limited_View as the full view of the
	designated type if the pointer comes from a limited_with clause.  Make
	incomplete designated type if it is in the main unit and has a freeze
	<E_Incomplete_Type>: Rework to treat Non_Limited_View, Full_View, and
	Underlying_Full_View similarly.  Return earlier if the full view already
	has an associated tree.
	(gnat_to_gnu_entity) <E_Record_Type>: Restore comment.
	(gnat_to_gnu_entity) <E_Record_Type>: Do not use a dummy type.
	(gnat_to_gnu_entity) <E_Variable>: Set TYPE_REF_CAN_ALIAS_ALL on the
	reference type built for objects with an address clause.
	Use create_true_var_decl with const_flag set for
	DECL_CONST_CORRESPONDING_VARs, ensuring a VAR_DECL is created with
	(gnat_to_gnu_entity, case E_Enumeration_Type): Set TYPE_NAME
	for Character and Wide_Character types. This info is read by the
	dwarf-2 writer, and is needed to be able to use the command "ptype
	character" in the debugger.
	(gnat_to_gnu_entity): When generating a type representing
	a Character or Wide_Character type, set the flag TYPE_STRING_FLAG,
	so that debug writers can distinguish it from ordinary integers.
	(elaborate_expression_1): Test the DECL_READONLY_ONCE_ELAB flag in
	addition to TREE_READONLY to assert the constantness of variables for
	elaboration purposes.
	(gnat_to_gnu_entity, subprogram cases): Change loops on formal
	parameters to call new Einfo function First_Formal_With_Extras.
	(gnat_to_gnu_entity): In type_annotate mode, replace a discriminant of a
	protected type with its corresponding discriminant, to obtain a usable
	(gnat_to_gnu_entity) <E_Access_Protected_Subprogram_Type>: Be prepared
	for a multiple elaboration of the "equivalent" type.
	(gnat_to_gnu_entity): Adjust for renaming of add_global_renaming_pointer
	into record_global_renaming_pointer.
	(gnat_to_gnu_entity) <E_Array_Type>: Do not force
	TYPE_NONALIASED_COMPONENT to 0 if the element type is an aggregate.
	<E_Array_Subtype>: Likewise.
	(gnat_to_gnu_entity) <E_Incomplete_Subtype>: Add support for regular
	incomplete subtypes and incomplete subtypes of incomplete types visible
	through a limited with clause.
	(gnat_to_gnu_entity) <E_Array_Subtype>: Take into account the bounds of
	the base index type for the maximum size of the array only if they are
	(gnat_to_gnu_entity, renaming object case): Do not wrap up the
	expression into a SAVE_EXPR if stabilization failed.

	* utils.c (create_subprog_decl): Turn TREE_ADDRESSABLE on the type of
	a result decl into DECL_BY_REFERENCE on this decl, now what is expected
	by lower level compilation passes.
	(gnat_genericize): New function, lowering a function body to GENERIC.
	Turn the type of RESULT_DECL into a real reference type if the decl
	has been marked DECL_BY_REFERENCE, and adjust references to the latter
	(gnat_genericize_r): New function. Tree walking callback for
	(convert_from_reference, is_byref_result): New functions. Helpers for
	(create_type_decl): Call gnat_pushdecl before calling
	rest_of_decl_compilation, to make sure that field TYPE_NAME of
	type_decl is properly set before calling the debug information writers.
	(write_record_type_debug_info): The heuristics which compute the
	alignment of a field in a variant record might not be accurate. Add a
	safety test to make sure no alignment is set to a smaller value than
	the alignment of the field type.
	(make_dummy_type): Use the Non_Limited_View as the underlying type if
	the type comes from a limited_with clause. Do not loop on the full view.
	(dummy_node_table): New global variable, moved from decl.c.
	(save_gnu_tree): Use above macros.
	(get_gnu_tree): Likewise.
	(present_gnu_tree): Likewise.
	(init_dummy_type): New function, moved from decl.c. Use above macros.
	(make_dummy_type): Likewise.
	(tree_code_for_record_type): New function extracted from make_dummy_type
	(init_gigi_decls): Set DECL_IS_MALLOC on gnat_malloc.
	(static_ctors): Change it to a vector, make static.
	(static_dtors): Likewise.
	(end_subprog_body): Adjust for above change.
	(build_global_cdtor): Moved from trans.c.
	(gnat_write_global_declarations): Emit global constructor and
	destructor, and call cgraph_optimize before emitting debug info for
	global declarations.
	(global_decls): New global variable.
	(gnat_pushdecl): Store the global declarations in global_decls, for
	later use.
	(gnat_write_global_declarations): Emit debug information for global
	(create_var_decl_1): Former create_var_decl, with an extra argument to
	 state whether the creation of a CONST_DECL is allowed.
	(create_var_decl): Behavior unchanged. Now a wrapper around
	create_var_decl_1 allowing CONST_DECL creation.
	(create_true_var_decl): New function, similar to create_var_decl but
	forcing the creation of a VAR_DECL node (CONST_DECL not allowed).
	(create_field_decl): Do not always mark the field as addressable
	if its type is an aggregate.
	(global_renaming_pointers): New static variable.
	(add_global_renaming_pointer): New function.
	(get_global_renaming_pointers): Likewise.

	* misc.c (gnat_dwarf_name): New function.
	(LANG_HOOKS_DWARF_NAME): Define to gnat_dwarf_name.
	(gnat_post_options): Add comment about structural alias analysis.
	(gnat_parse_file): Do not call cgraph_optimize here.
	(LANG_HOOKS_WRITE_GLOBALS): Define to gnat_write_global_declarations.

	* trans.c (process_freeze_entity): Don't abort if we already have a
	non dummy GCC tree for a Concurrent_Record_Type, as it might
	legitimately have been elaborated while processing the associated
	Concurrent_Type prior to this explicit freeze node.
	(Identifier_to_gnu): Do not make a variable referenced in a SJLJ
	exception handler volatile if it is of variable size.
	(process_type): Remove bypass for types coming from a limited_with
	(call_to_gnu): When processing the copy-out of a N_Type_Conversion GNAT
	actual, convert the corresponding gnu_actual to the real destination
	type when necessary.
	(add_decl_expr): Set the DECL_READONLY_ONCE_ELAB flag on variables
	originally TREE_READONLY but whose elaboration cannot be performed
	Part of fix for F504-021.
	(tree_transform, subprogram cases): Change loops on formal parameters to
	call new Einfo function First_Formal_With_Extras.
	(gnat_to_gnu) <N_Op_Shift_Right_Arithmetic>: Ignore constant overflow
	stemming from type conversion for the lhs.
	(Attribute_to_gnu) <Attr_Alignment>: Also divide the alignment by the
	number of bits per unit for components of records.
	(gnat_to_gnu) <N_Code_Statement>: Mark operands addressable if needed.
	(Handled_Sequence_Of_Statements_to_gnu): Register the cleanup associated
	with At_End_Proc after the SJLJ EH cleanup.
	(Compilation_Unit_to_gnu): Call elaborate_all_entities only on the main
	compilation unit.
	(elaborate_all_entities): Do not retest type_annotate_only.
	(tree_transform) <N_Abstract_Subprogram_Declaration>: Process the
	result type of an abstract subprogram, which may be an itype associated
	with an anonymous access result (related to AI-318-02).
	(build_global_cdtor): Move to utils.c.
	(Case_Statement_to_gnu): Avoid adding the choice of a when statement if
	this choice is not a null tree nor an integer constant.
	(gigi): Run unshare_save_expr via walk_tree_without_duplicates
	on the body of elaboration routines instead of mark_unvisited.
	(add_stmt): Do not mark the tree.
	(add_decl_expr): Tweak comment.
	(mark_unvisited): Delete.
	(unshare_save_expr): New static function.
	(call_to_gnu): Issue an error when making a temporary around a
	procedure call because of non-addressable actual parameter if the
	type of the formal is by_reference.
	(Compilation_Unit_to_gnu): Invalidate the global renaming pointers
	after building the elaboration routine.

Attachment: difs
Description: Text document

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