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 inlining bugs


Tested on i686-linux, committed on trunk.

When inlining a subprogram body, the actuals are captured in local
declarations so they are evaluated only once. If an actual is a tagged
type, it is a reference parameter, and the program is allowed to depend on
this mechanism, so that making a local copy of it in a constant declaration
is in fact illegal (if hard to detect in most cases). if the actual is not
an entity name, the proper way to capture its value is with a renaming
declaration, as with other by-reference types, chiefly limited ones.
See gnat.dg/inline_tagged.adb

Fix Ada 2005 AI 416: a function with an anonymous access result dispatches on
result. A call to such a function can be tag-indeterminate, and a
dereference of such a function is also tag indeterminate, in which case
its tag, and that of the call, must be determined from context, such as
the left-hand side of an assignment, or the signature of an enclosing
subprogram call.

In build-in-place function calls, the access to the caller's return object
passed as an implicit actual was failing type checking in cases where the
return object is an allocator of a class-wide access type or an object
declared with a class-wide type. This is addressed by forcing an unchecked
conversion of the object's name to the result subtype of the build-in-place
function (prior to applying 'Unchecked_Access). In the class-wide object
declaration case, the type of the object entity is changed to the specific
type of the function result since the function-call initialization is
separated from the object and we don't want to declare a class-wide object
without explicit initialization.

Also, if there is a transient scope for a call node to be inlined, this will
be the scope of the actions for that node, and the statements in the inlined
body need to be within this scope. For example, they need to have visibility on
the constant declarations created for the actuals.

If no transient scope is required, and if there are no declarations in
the inlined body, we can do a little optimization and insert the statements
for the body directly after N, and rewrite N to a null statement, instead of
rewriting N into a full-blown block statement.

This change adds the necessary guard against doing the optimization when
there is a transient scope. It was previously missing, and that caused
references to the formals within the inlined body to reference constants
past the end of their scope.

gnat.dg/inline_scope.adb now compiles properly with -gnatN

The management of actuals of in-mode parameters that are type conversions
was missing. After this patch gnat.dg/in_mode_conv.adb compiles without
errors.

2006-10-31  Robert Dewar  <dewar@adacore.com>
	    Ed Schonberg  <schonberg@adacore.com>
	    Bob Duff  <duff@adacore.com>
	    Gary Dismukes  <dismukes@adacore.com>

	* exp_ch6.ads, exp_ch6.adb: Use new Validity_Check suppression
	capability.
	(Expand_Inlined_Call): Tagged types are by-reference types, and
	therefore should be replaced by a renaming declaration in the expanded
	body, as is done for limited types.
	(Expand_Call): If this is a call to a function with dispatching access
	result, propagate tag from context.
	(Freeze_Subprogram): Enable full ABI compatibility for interfacing with
	CPP by default.
	(Make_Build_In_Place_Call_In_Assignment): New procedure to do
	build-in-place when the right-hand side of an assignment is a
	build-in-place function call.
	(Make_Build_In_Place_Call_In_Allocator): Apply an unchecked conversion
	of the explicit dereference of the allocator to the result subtype of
	the build-in-place function. This is needed to satisfy type checking
	in cases where the caller's return object is created by an allocator for
	a class-wide access type and the type named in the allocator is a
	specific type.
	(Make_Build_In_Place_Call_In_Object_Declaration): Apply an unchecked
	conversion of the reference to the declared object to the result subtype
	of the build-in-place function. This is needed to satisfy type checking
	in cases where the declared object has a class-wide type. Also, in the
	class-wide case, change the type of the object entity to the specific
	result subtype of the function, to avoid passing a class-wide object
	without explicit initialization to the back end.
	(Register_Interface_DT_Entry): Moved outside the body of
	Freeze_Subprogram because this routine is now public; it is called from
	Check_Dispatching_Overriding to handle late overriding of abstract
	interface primitives.
	(Add_Access_Actual_To_Build_In_Place_Call): New utility procedure for
	adding an implicit access actual on a call to a build-in-place function.
	(Expand_Actuals): Test for an actual parameter that is a call to a
	build-in-place function and apply
	Make_Build_In_Place_Call_In_Anonymous_Context to the call.
	(Is_Build_In_Place_Function): New function to determine whether an
	entity is a function whose calls should be handled as build-in-place.
	(Is_Build_In_Place_Function_Call): New function to determine whether an
	expression is a function call that should handled as build-in-place.
	(Make_Build_In_Place_Call_In_Allocator): New procedure for handling
	calls to build-in-place functions as the initialization of an allocator.
	(Make_Build_In_Place_Call_In_Anonymous_Context): New procedure for
	handling calls to build-in-place functions in contexts that do not
	involve init of a separate object (for example, actuals of subprogram
	calls).
	(Make_Build_In_Place_Call_In_Object_Declaration): New procedure for
	handling calls to build-in-place functions as the initialization of an
	object declaration.
	(Detect_Infinite_Recursion): Add explicit parameter Process to
	instantiation of Traverse_Body to avoid unreferenced warning.
	(Check_Overriding_Inherited_Interfaces): Removed.
	(Register_Interface_DT_Entry): Code cleanup.
	(Register_Predefined_DT_Entry): Code cleanup.
	(Expand_Inlined_Call.Rewrite_Procedure_Call): Do not omit block around
	inlined statements if within a transient scope.
	(Expand_Inlined_Call.Process_Formals): When replacing occurrences of
	formal parameters with occurrences of actuals in inlined body, establish
	visibility on the proper view of the actual's subtype for the body's
	context.
	(Freeze_Subprogram): Do nothing if we are compiling under full ABI
	compatibility mode and we have an imported CPP subprogram because
	for now we assume that imported CPP primitives correspond with
	objects whose constructor is in the CPP side (and therefore we
	don't need to generate code to register them in the dispatch table).
	(Expand_Actuals): Introduce copy of actual, only if it might be a bit-
	aligned selected component.
	(Add_Call_By_Copy_Node): Add missing code to handle the case in which
	the actual of an in-mode parameter is a type conversion.
	(Expand_Actuals): If the call does not come from source and the actual
	is potentially misaligned, let gigi handle it rather than rejecting the
	(Expand_N_Subprogram_Body, Freeze_Subprogram): set subprograms returning
	Class Wide types as returning by reference independantly of their
	controlled status since with HIE runtimes class wide types are not
	potentially controlled anymore.

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]