Bug 67205 - eliminate No_Implicit_Dynamic_Code restriction violations
Summary: eliminate No_Implicit_Dynamic_Code restriction violations
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: ada (show other bugs)
Version: 5.1.1
: P3 enhancement
Target Milestone: 7.0
Assignee: Eric Botcazou
URL:
Keywords:
Depends on: 80146
Blocks: 79421
  Show dependency treegraph
 
Reported: 2015-08-13 11:31 UTC by Florian Weimer
Modified: 2017-03-23 11:56 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-08-13 00:00:00


Attachments
trampoline.adb (118 bytes, text/plain)
2015-08-13 11:31 UTC, Florian Weimer
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Florian Weimer 2015-08-13 11:31:37 UTC
Created attachment 36179 [details]
trampoline.adb

The attached example requires generation of trampolines.  This may be due to bug 57999, but I think a front-end fix would be more reliable.

As an additional surprise, pragma Restrictions (No_Implicit_Dynamic_Code) does not cause compilation to fail.  The error is only detected at binding time, and -Wtrampolines is needed to find the culprit.
Comment 1 Marek Polacek 2015-08-13 11:34:34 UTC
Confirmed.
Comment 2 Eric Botcazou 2015-09-10 08:17:54 UTC
> The attached example requires generation of trampolines.  This may be due to
> bug 57999, but I think a front-end fix would be more reliable.

Please clarify "front-end fix".  The language requires pointers to nested functions in this case and you cannot reasonably change that, nested functions being first-class citizens in Ada.

More generally, trampolines can indeed be eliminated, but you need changes in the entire compiler to do it.

> As an additional surprise, pragma Restrictions (No_Implicit_Dynamic_Code)
> does not cause compilation to fail.  The error is only detected at binding
> time, and -Wtrampolines is needed to find the culprit.

Yes, the violation is detected but the error is not issued, probably because it's the instantiation of a run-time unit.
Comment 3 Florian Weimer 2015-09-10 11:09:58 UTC
(In reply to Eric Botcazou from comment #2)
> > The attached example requires generation of trampolines.  This may be due to
> > bug 57999, but I think a front-end fix would be more reliable.
> 
> Please clarify "front-end fix".  The language requires pointers to nested
> functions in this case and you cannot reasonably change that, nested
> functions being first-class citizens in Ada.
> 
> More generally, trampolines can indeed be eliminated, but you need changes
> in the entire compiler to do it.

Couldn't you put the static chain for the dispatching subprograms into the vtable of the tagged type?

In some examples (including this one, and those I recently submitted as a GNAT tools patch), it seems rather straightforward to float the generic instantiation out of the nested subprogram.  Some care is necessary to make sure the transformation is in fact valid, but I had hoped this would be a more localized change in the compiler.
Comment 4 Eric Botcazou 2015-09-10 11:28:12 UTC
> Couldn't you put the static chain for the dispatching subprograms into the
> vtable of the tagged type?

Presumably not, the vtable layout is constrained by the C++ compatibility and this extends to local tagged types since Ada 2005.  In any case, see below.

> In some examples (including this one, and those I recently submitted as a
> GNAT tools patch), it seems rather straightforward to float the generic
> instantiation out of the nested subprogram.  Some care is necessary to make
> sure the transformation is in fact valid, but I had hoped this would be a
> more localized change in the compiler.

The truth is, the versions of GNAT released by AdaCore use a general scheme to eliminate (almost) all trampolines, at least on native platforms, so there is no incentive for small tricks like this.  We could submit the scheme if there is some interest from the community.
Comment 5 Florian Weimer 2015-09-10 11:33:47 UTC
(In reply to Eric Botcazou from comment #4)
> The truth is, the versions of GNAT released by AdaCore use a general scheme
> to eliminate (almost) all trampolines, at least on native platforms, so
> there is no incentive for small tricks like this.  We could submit the
> scheme if there is some interest from the community.

Fedora has policies against executable stack, and fewer off them are always welcome.  Are your changes restricted to gcc/ada, or would you need reviewers frm other parts of GCC?
Comment 6 Eric Botcazou 2015-09-10 12:29:08 UTC
> Fedora has policies against executable stack, and fewer off them are always
> welcome.  Are your changes restricted to gcc/ada, or would you need
> reviewers frm other parts of GCC?

The latter, although the changes are localized (nested functions decomposition pass, RTL expander and bits in a few back-ends).  Mostly straightforward, but only helps Ada and we already have a slew of such patches pending review, so we have started to prioritize.  I'll give it a try though.
Comment 7 simon 2016-01-25 12:40:05 UTC
As far as I can see 5.1.0 (and 5.2.0) are happy that the trampolines should be *generated* in the presence of pragma Restrictions (No_Implicit_Dynamic_Code); trampoline.adb compiles and builds without problem.

The problem arises when the trampolines are invoked; 

with Ada.Containers.Vectors;
procedure Trampoline is
   package Vectors is new Ada.Containers.Vectors (Positive, Integer);
   type Capacity_P is
     access function (Container : Vectors.Vector)
                     return Ada.Containers.Count_Type;
   P : Capacity_P;
begin
   P := Vectors.Capacity'Access;
end Trampoline;

results in the expected 'violation of restriction “No_Implicit_Dynamic_Code”’ error at compile time.
Comment 8 Eric Botcazou 2016-01-28 11:41:08 UTC
Let's reclassify this PR as an enhancement to eliminate trampolines.
Comment 9 Eric Botcazou 2016-01-28 11:42:04 UTC
I'll submit the AdaCore patch for GCC 7.
Comment 10 Eric Botcazou 2016-10-16 20:14:04 UTC
Author: ebotcazou
Date: Sun Oct 16 20:13:32 2016
New Revision: 241222

URL: https://gcc.gnu.org/viewcvs?rev=241222&root=gcc&view=rev
Log:
	PR ada/37139
	PR ada/67205
	* common.opt (-ftrampolines): New option.
	* doc/invoke.texi (Code Gen Options): Document it.
	* doc/tm.texi.in (Trampolines): Add TARGET_CUSTOM_FUNCTION_DESCRIPTORS.
	* doc/tm.texi: Regenerate.
	* builtins.def: Add init_descriptor and adjust_descriptor.
	* builtins.c (expand_builtin_init_trampoline): Do not issue a warning
	on platforms with descriptors.
	(expand_builtin_init_descriptor): New function.
	(expand_builtin_adjust_descriptor): Likewise.
	(expand_builtin) <BUILT_IN_INIT_DESCRIPTOR>: New case.
	<BUILT_IN_ADJUST_DESCRIPTOR>: Likewise.
	* calls.c (prepare_call_address): Remove SIBCALLP parameter and add
	FLAGS parameter.  Deal with indirect calls by descriptor and adjust.
	Set STATIC_CHAIN_REG_P on the static chain register, if any.
	(call_expr_flags): Set ECF_BY_DESCRIPTOR for calls by descriptor.
	(expand_call): Likewise.  Move around call to prepare_call_address
	and pass all flags to it.
	* cfgexpand.c (expand_call_stmt): Reinstate CALL_EXPR_BY_DESCRIPTOR.
	* gimple.h (enum gf_mask): New GF_CALL_BY_DESCRIPTOR value.
	(gimple_call_set_by_descriptor): New setter.
	(gimple_call_by_descriptor_p): New getter.
	* gimple.c (gimple_build_call_from_tree): SetCALL_EXPR_BY_DESCRIPTOR.
	(gimple_call_flags): Deal with GF_CALL_BY_DESCRIPTOR.
	* langhooks.h (struct lang_hooks): Add custom_function_descriptors.
	* langhooks-def.h (LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS): Define.
	(LANG_HOOKS_INITIALIZER): Add LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS.
	* rtl.h (STATIC_CHAIN_REG_P): New macro.
	* rtlanal.c (find_first_parameter_load): Skip static chain registers.
	* target.def (custom_function_descriptors): New POD hook.
	* tree.h (FUNC_ADDR_BY_DESCRIPTOR): New flag on ADDR_EXPR.
	(CALL_EXPR_BY_DESCRIPTOR): New flag on CALL_EXPR.
	* tree-core.h (ECF_BY_DESCRIPTOR): New mask.
	Document FUNC_ADDR_BY_DESCRIPTOR and CALL_EXPR_BY_DESCRIPTOR.
	* tree.c (make_node_stat) <tcc_declaration>: Use FUNCTION_ALIGNMENT.
	(build_common_builtin_nodes): Initialize init_descriptor and
	adjust_descriptor.
	* tree-nested.c: Include target.h.
	(struct nesting_info): Add 'any_descr_created' field.
	(get_descriptor_type): New function.
	(lookup_element_for_decl): New function extracted from...
	(create_field_for_decl): Likewise.
	(lookup_tramp_for_decl): ...here.  Adjust.
	(lookup_descr_for_decl): New function.
	(convert_tramp_reference_op): Deal with descriptors.
	(build_init_call_stmt): New function extracted from...
	(finalize_nesting_tree_1): ...here.  Adjust and deal withdescriptors.
	* defaults.h (FUNCTION_ALIGNMENT): Define.
	(TRAMPOLINE_ALIGNMENT): Set to above instead of FUNCTION_BOUNDARY.
	* config/i386/i386.h (TARGET_CUSTOM_FUNCTION_DESCRIPTORS): Define.
	* config/ia64/ia64.h (TARGET_CUSTOM_FUNCTION_DESCRIPTORS): Likewise.
	* config/rs6000/rs6000.h (TARGET_CUSTOM_FUNCTION_DESCRIPTORS):Likewise.
	* config/sparc/sparc.h (TARGET_CUSTOM_FUNCTION_DESCRIPTORS): Likewise.
ada/
	* gcc-interface/misc.c (LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS):Define.
	* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Access>: Deal with
	a zero TARGET_CUSTOM_FUNCTION_DESCRIPTORS specially for Code_Address.
	Otherwise, if TARGET_CUSTOM_FUNCTION_DESCRIPTORS is positive, set
	FUNC_ADDR_BY_DESCRIPTOR for 'Access/'Unrestricted_Access of nested
	subprograms if the type can use an internal representation.
	(call_to_gnu): Likewise, but set CALL_EXPR_BY_DESCRIPTOR on indirect
	calls if the type can use an internal representation.

Added:
    trunk/gcc/testsuite/gnat.dg/trampoline3.adb
    trunk/gcc/testsuite/gnat.dg/trampoline4.adb
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/ada/ChangeLog
    trunk/gcc/ada/gcc-interface/misc.c
    trunk/gcc/ada/gcc-interface/trans.c
    trunk/gcc/builtins.c
    trunk/gcc/builtins.def
    trunk/gcc/calls.c
    trunk/gcc/cfgexpand.c
    trunk/gcc/common.opt
    trunk/gcc/config/i386/i386.h
    trunk/gcc/config/ia64/ia64.h
    trunk/gcc/config/rs6000/rs6000.h
    trunk/gcc/config/sparc/sparc.h
    trunk/gcc/defaults.h
    trunk/gcc/doc/invoke.texi
    trunk/gcc/doc/tm.texi
    trunk/gcc/doc/tm.texi.in
    trunk/gcc/gimple.c
    trunk/gcc/gimple.h
    trunk/gcc/langhooks-def.h
    trunk/gcc/langhooks.h
    trunk/gcc/rtl.h
    trunk/gcc/rtlanal.c
    trunk/gcc/target.def
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-core.h
    trunk/gcc/tree-nested.c
    trunk/gcc/tree.c
    trunk/gcc/tree.h
Comment 11 Eric Botcazou 2016-10-16 20:32:04 UTC
Trampolines are gone on x86, PowerPC and SPARC.  AArch64 and ARM are the next ones on the list.
Comment 12 Eric Botcazou 2016-11-25 10:00:19 UTC
Author: ebotcazou
Date: Fri Nov 25 09:59:45 2016
New Revision: 242868

URL: https://gcc.gnu.org/viewcvs?rev=242868&root=gcc&view=rev
Log:
	PR ada/67205
	* config/mips/mips.c (TARGET_CUSTOM_FUNCTION_DESCRIPTORS): Define.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/mips/mips.c
Comment 13 Eric Botcazou 2017-01-17 18:03:26 UTC
Author: ebotcazou
Date: Tue Jan 17 18:02:55 2017
New Revision: 244543

URL: https://gcc.gnu.org/viewcvs?rev=244543&root=gcc&view=rev
Log:
	PR ada/67205
	* config/aarch64/aarch64.c (TARGET_CUSTOM_FUNCTION_DESCRIPTORS): Define

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/aarch64/aarch64.c
Comment 14 Eric Botcazou 2017-01-17 18:04:29 UTC
The ARM patch is waiting for approval at:
  https://gcc.gnu.org/ml/gcc-patches/2016-11/msg01254.html
Comment 15 Eric Botcazou 2017-02-21 08:43:26 UTC
Author: ebotcazou
Date: Tue Feb 21 08:42:54 2017
New Revision: 245621

URL: https://gcc.gnu.org/viewcvs?rev=245621&root=gcc&view=rev
Log:
	PR ada/67205
	* config/arm/arm.c (TARGET_CUSTOM_FUNCTION_DESCRIPTORS): Define.
	(arm_function_ok_for_sibcall): Return false for an indirect call by
	descriptor if all the argument registers are used.
	(arm_relayout_function): Use FUNCTION_ALIGNMENT macro to adjust the
	alignment of the function.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/arm/arm.c
Comment 16 Eric Botcazou 2017-02-21 08:45:18 UTC
Trampolines are gone on ARM, Aarch64 and MIPS too.
Comment 17 Eric Botcazou 2017-02-21 08:47:37 UTC
And s390 as per PR ada/79421.