From 5fe48b3df8d1e27d2348ee66dfef7fc7b9e42553 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 27 Oct 2014 11:33:21 +0000 Subject: [PATCH] utils.c (create_var_decl_1): For a variable declared in the unit... * gcc-interface/utils.c (create_var_decl_1): For a variable declared in the unit, set TREE_PUBLIC only if it has static storage duration. From-SVN: r216729 --- gcc/ada/ChangeLog | 5 ++ gcc/ada/gcc-interface/utils.c | 63 ++++++++++++--------- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gnat.dg/specs/concat1.ads | 10 ++++ gcc/testsuite/gnat.dg/specs/concat1_pkg.ads | 9 +++ 5 files changed, 64 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/specs/concat1.ads create mode 100644 gcc/testsuite/gnat.dg/specs/concat1_pkg.ads diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index f8bcb2e97ea..8e0c881ebd9 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2014-10-27 Eric Botcazou + + * gcc-interface/utils.c (create_var_decl_1): For a variable declared + in the unit, set TREE_PUBLIC only if it has static storage duration. + 2014-10-27 Eric Botcazou * gcc-interface/decl.c (gnat_to_gnu_entity): Apply special treatment diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 79b0039bf32..ef1798e54ce 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -2309,25 +2309,30 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init, bool static_flag, bool const_decl_allowed_p, struct attrib *attr_list, Node_Id gnat_node) { - /* Whether the initializer is a constant initializer. At the global level - or for an external object or an object to be allocated in static memory, - we check that it is a valid constant expression for use in initializing - a static variable; otherwise, we only check that it is constant. */ - bool init_const - = (var_init != 0 + /* Whether the object has static storage duration, either explicitly or by + virtue of being declared at the global level. */ + const bool static_storage = static_flag || global_bindings_p (); + + /* Whether the initializer is constant: for an external object or an object + with static storage duration, we check that the initializer is a valid + constant expression for initializing a static variable; otherwise, we + only check that it is constant. */ + const bool init_const + = (var_init && gnat_types_compatible_p (type, TREE_TYPE (var_init)) - && (global_bindings_p () || extern_flag || static_flag - ? initializer_constant_valid_p (var_init, TREE_TYPE (var_init)) != 0 + && (extern_flag || static_storage + ? initializer_constant_valid_p (var_init, TREE_TYPE (var_init)) + != NULL_TREE : TREE_CONSTANT (var_init))); /* Whether we will make TREE_CONSTANT the DECL we produce here, in which - case the initializer may be used in-lieu of the DECL node (as done in + case the initializer may be used in lieu of the DECL node (as done in Identifier_to_gnu). This is useful to prevent the need of elaboration - code when an identifier for which such a decl is made is in turn used as - an initializer. We used to rely on CONST vs VAR_DECL for this purpose, - but extra constraints apply to this choice (see below) and are not - relevant to the distinction we wish to make. */ - bool constant_p = const_flag && init_const; + code when an identifier for which such a DECL is made is in turn used + as an initializer. We used to rely on CONST_DECL vs VAR_DECL for this, + but extra constraints apply to this choice (see below) and they are not + relevant to the distinction we wish to make. */ + const bool constant_p = const_flag && init_const; /* The actual DECL node. CONST_DECL was initially intended for enumerals and may be used for scalars in general but not for aggregates. */ @@ -2347,19 +2352,24 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init, || (type_annotate_only && var_init && !TREE_CONSTANT (var_init))) var_init = NULL_TREE; - /* At the global level, an initializer requiring code to be generated - produces elaboration statements. Check that such statements are allowed, - that is, not violating a No_Elaboration_Code restriction. */ - if (global_bindings_p () && var_init != 0 && !init_const) + /* At the global level, a non-constant initializer generates elaboration + statements. Check that such statements are allowed, that is to say, + not violating a No_Elaboration_Code restriction. */ + if (var_init && !init_const && global_bindings_p ()) Check_Elaboration_Code_Allowed (gnat_node); DECL_INITIAL (var_decl) = var_init; TREE_READONLY (var_decl) = const_flag; DECL_EXTERNAL (var_decl) = extern_flag; - TREE_PUBLIC (var_decl) = public_flag || extern_flag; TREE_CONSTANT (var_decl) = constant_p; - TREE_THIS_VOLATILE (var_decl) = TREE_SIDE_EFFECTS (var_decl) - = TYPE_VOLATILE (type); + + /* We need to allocate static storage for an object with static storage + duration if it isn't external. */ + TREE_STATIC (var_decl) = !extern_flag && static_storage; + + /* The object is public if it is external or if it is declared public + and has static storage duration. */ + TREE_PUBLIC (var_decl) = extern_flag || (public_flag && static_storage); /* Ada doesn't feature Fortran-like COMMON variables so we shouldn't try to fiddle with DECL_COMMON. However, on platforms that don't @@ -2371,12 +2381,6 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init, && !have_global_bss_p ()) DECL_COMMON (var_decl) = 1; - /* At the global binding level, we need to allocate static storage for the - variable if it isn't external. Otherwise, we allocate automatic storage - unless requested not to. */ - TREE_STATIC (var_decl) - = !extern_flag && (static_flag || global_bindings_p ()); - /* For an external constant whose initializer is not absolute, do not emit debug info. In DWARF this would mean a global relocation in a read-only section which runs afoul of the PE-COFF run-time relocation mechanism. */ @@ -2384,9 +2388,12 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init, && constant_p && var_init && initializer_constant_valid_p (var_init, TREE_TYPE (var_init)) - != null_pointer_node) + != null_pointer_node) DECL_IGNORED_P (var_decl) = 1; + if (TYPE_VOLATILE (type)) + TREE_SIDE_EFFECTS (var_decl) = TREE_THIS_VOLATILE (var_decl) = 1; + if (TREE_SIDE_EFFECTS (var_decl)) TREE_ADDRESSABLE (var_decl) = 1; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2f8efef32c2..786b051bb6d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-10-27 Eric Botcazou + + * gnat.dg/specs/concat1.ads: New test. + * gnat.dg/specs/concat1_pkg.ads: New helper. + 2014-10-27 Richard Biener * gcc.dg/tree-ssa/forwprop-6.c: Scan ccp1 dump instead. diff --git a/gcc/testsuite/gnat.dg/specs/concat1.ads b/gcc/testsuite/gnat.dg/specs/concat1.ads new file mode 100644 index 00000000000..fcfeacbd4b0 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/concat1.ads @@ -0,0 +1,10 @@ +-- { dg-do compile } +-- { dg-options "-gnatd.h" } + +with Concat1_Pkg; use Concat1_Pkg; + +package Concat1 is + + C : constant Natural := Id_For ("_" & Image_Of); + +end Concat1; diff --git a/gcc/testsuite/gnat.dg/specs/concat1_pkg.ads b/gcc/testsuite/gnat.dg/specs/concat1_pkg.ads new file mode 100644 index 00000000000..d8863c74a1b --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/concat1_pkg.ads @@ -0,0 +1,9 @@ +-- { dg-excess-errors "cannot generate code" } + +package Concat1_Pkg is + + function Id_For (Name : String) return Natural; + + function Image_Of return String; + +end Concat1_Pkg; -- 2.30.2