The executable cannot be linked because of a duplicated symbol in the object 
files, which comes from a conditional expression used to initialize a constant 
that is the upper bound of an index type in an array.

Tested on i586-suse-linux, applied on the mainline.


2012-06-11  Eric Botcazou  <ebotca...@adacore.com>

        * gcc-interface/decl.c (gnat_to_gnu_entity): Do not specifically deal
        with external constants wrt force_global here...
        <E_Constant>: ...but here instead.
        * gcc-interface/utils.c (gnat_pushdecl): Do not put external DECLs onto
        the list of global DECLs.


2012-06-11  Eric Botcazou  <ebotca...@adacore.com>

        * gnat.dg/constant4.adb: New test.
        * gnat.dg/constant4_pkg.ads: New helper.


-- 
Eric Botcazou
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 188377)
+++ gcc-interface/utils.c	(working copy)
@@ -572,14 +572,14 @@ gnat_pushdecl (tree decl, Node_Id gnat_n
   if (!(TREE_CODE (decl) == TYPE_DECL
         && TREE_CODE (TREE_TYPE (decl)) == UNCONSTRAINED_ARRAY_TYPE))
     {
-      if (global_bindings_p ())
+      if (DECL_EXTERNAL (decl))
 	{
-	  VEC_safe_push (tree, gc, global_decls, decl);
-
 	  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
 	    VEC_safe_push (tree, gc, builtin_decls, decl);
 	}
-      else if (!DECL_EXTERNAL (decl))
+      else if (global_bindings_p ())
+	VEC_safe_push (tree, gc, global_decls, decl);
+      else
 	{
 	  DECL_CHAIN (decl) = BLOCK_VARS (current_binding_level->block);
 	  BLOCK_VARS (current_binding_level->block) = decl;
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 188378)
+++ gcc-interface/decl.c	(working copy)
@@ -348,12 +348,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
      another compilation unit) public entities, show we are at global level
      for the purpose of computing scopes.  Don't do this for components or
      discriminants since the relevant test is whether or not the record is
-     being defined.  Don't do this for constants either as we'll look into
-     their defining expression in the local context.  */
+     being defined.  */
   if (!definition
       && kind != E_Component
       && kind != E_Discriminant
-      && kind != E_Constant
       && Is_Public (gnat_entity)
       && !Is_Statically_Allocated (gnat_entity))
     force_global++, this_global = true;
@@ -424,6 +422,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 	     != N_Allocator)
 	{
 	  bool went_into_elab_proc = false;
+	  int save_force_global = force_global;
 
 	  /* The expression may contain N_Expression_With_Actions nodes and
 	     thus object declarations from other units.  In this case, even
@@ -436,11 +435,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 	      current_function_decl = get_elaboration_procedure ();
 	      went_into_elab_proc = true;
 	    }
+	  force_global = 0;
 	  gnat_pushlevel ();
 
 	  gnu_expr = gnat_to_gnu (Expression (Declaration_Node (gnat_entity)));
 
 	  gnat_zaplevel ();
+	  force_global = save_force_global;
 	  if (went_into_elab_proc)
 	    current_function_decl = NULL_TREE;
 	}
-- { dg-do link }
-- { dg-options "-gnat12" }

with Constant4_Pkg; use Constant4_Pkg;

procedure Constant4 is
   Sum : Counter := 0;
begin
   for Count of Steals loop
      Sum := Sum + Count;
   end loop;
end;
with Ada.Command_Line;       use Ada.Command_Line;
with System.Multiprocessors; use System.Multiprocessors;

package Constant4_Pkg is

   Max_CPUs : constant CPU := (if Argument_Count < 2 then Number_Of_CPUs
                               else CPU'Value (Argument (2)));

   subtype Worker_Id is CPU range 1 .. Max_CPUs;

   type Counter is range 0 .. 10**18;

   Steals : array (Worker_Id) of Counter := (others => 0);

end Constant4_Pkg;

Reply via email to