[Ada] Plug hole with constants used by reference

Message ID 201206111050.57165.ebotcazou@adacore.com
State New
Headers show

Commit Message

Eric Botcazou June 11, 2012, 8:50 a.m.
This aligns the processing of constants used by reference in Identifier_to_gnu 
with that of regular constants; in particular we stop returning the underlying 
constant if this is the address of a constant and an lvalue is required.

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

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

	* gcc-interface/trans.c (Identifier_to_gnu): Test Is_Elementary_Type
	instead of Is_Scalar_Type for a constant with an address clause.
	Do not return the underlying constant for a constant used by reference
	if it holds the address of a constant and an lvalue is required.


Index: gcc-interface/trans.c
--- gcc-interface/trans.c	(revision 188377)
+++ gcc-interface/trans.c	(working copy)
@@ -1019,7 +1019,7 @@  Identifier_to_gnu (Node_Id gnat_node, tr
      order-of-elaboration issue here.  */
   gnu_result_type = get_unpadded_type (gnat_temp_type);
-  /* If this is a non-imported scalar constant with an address clause,
+  /* If this is a non-imported elementary constant with an address clause,
      retrieve the value instead of a pointer to be dereferenced unless
      an lvalue is required.  This is generally more efficient and actually
      required if this is a static expression because it might be used
@@ -1028,7 +1028,7 @@  Identifier_to_gnu (Node_Id gnat_node, tr
      volatile-ness short-circuit here since Volatile constants must be
      imported per C.6.  */
   if (Ekind (gnat_temp) == E_Constant
-      && Is_Scalar_Type (gnat_temp_type)
+      && Is_Elementary_Type (gnat_temp_type)
       && !Is_Imported (gnat_temp)
       && Present (Address_Clause (gnat_temp)))
@@ -1080,7 +1080,10 @@  Identifier_to_gnu (Node_Id gnat_node, tr
 	  = convert (build_pointer_type (gnu_result_type), gnu_result);
       /* If it's a CONST_DECL, return the underlying constant like below.  */
-      else if (TREE_CODE (gnu_result) == CONST_DECL)
+      else if (TREE_CODE (gnu_result) == CONST_DECL
+	       && !(DECL_CONST_ADDRESS_P (gnu_result)
+		    && lvalue_required_p (gnat_node, gnu_result_type, true,
+					  true, false)))
 	gnu_result = DECL_INITIAL (gnu_result);
       /* If it's a renaming pointer and we are at the right binding level,