Patchwork [Ada] Fix compilation error on constant passed as memory operand to Asm

login
register
mail settings
Submitter Eric Botcazou
Date June 18, 2011, 10:11 a.m.
Message ID <201106181211.34380.ebotcazou@adacore.com>
Download mbox | patch
Permalink /patch/100910/
State New
Headers show

Comments

Eric Botcazou - June 18, 2011, 10:11 a.m.
This prevents the compiler from rejecting a constant passed as memory operand
to an Asm statement.  While this may seem to be a questionable construct, it
can be generated by the front-end in specific cases.

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


2011-06-18  Eric Botcazou  <ebotcazou@adacore.com>

	* einfo.ads (Address_Taken): Document use for the second argument of
	Asm_Input and Asm_Output attributes.
	* sem_attr.adb (Analyze_Attribute) <Attribute_Asm_Input>: If the second
	argument is an entity name, then set Address_Taken on it.
	<Attribute_Asm_Output>: Likewise.
	* gcc-interface/trans.c (lvalue_required_for_attribute_p): Handle the
	Attr_Asm_Input and Attr_Asm_Output attributes explicitly.
	(gnat_to_gnu) <N_Code_Statement>: If an operand is going to end up in
	memory and is a CONST_DECL, retrieve its corresponding VAR_DECL.


2011-06-18  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/constant3.adb: New test.

Patch

Index: einfo.ads
===================================================================
--- einfo.ads	(revision 175136)
+++ einfo.ads	(working copy)
@@ -380,9 +380,11 @@  package Einfo is
 --    Address_Taken (Flag104)
 --       Present in all entities. Set if the Address or Unrestricted_Access
 --       attribute is applied directly to the entity, i.e. the entity is the
---       entity of the prefix of the attribute reference. Used by Gigi to
---       make sure that the address can be meaningfully taken, and also in
---       the case of subprograms to control output of certain warnings.
+--       entity of the prefix of the attribute reference. Also set if the
+--       entity is the second argument of an Asm_Input or Asm_Output attribute,
+--       as the construct may entail taking its address. Used by Gigi to make
+--       sure that the address can be meaningfully taken, and also in the case
+--       of subprograms to control output of certain warnings.
 
 --    Aft_Value (synthesized)
 --       Applies to fixed and decimal types. Computes a universal integer
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 175136)
+++ gcc-interface/trans.c	(working copy)
@@ -706,6 +706,8 @@  lvalue_required_for_attribute_p (Node_Id
     case Attr_First_Bit:
     case Attr_Last_Bit:
     case Attr_Bit:
+    case Attr_Asm_Input:
+    case Attr_Asm_Output:
     default:
       return 1;
     }
@@ -5489,9 +5491,15 @@  gnat_to_gnu (Node_Id gnat_node)
 		     mark it addressable.  Note that we don't test
 		     allows_mem like in the input case below; this
 		     is modelled on the C front-end.  */
-		  if (!allows_reg
-		      && !gnat_mark_addressable (output))
-		    output = error_mark_node;
+		  if (!allows_reg)
+		    {
+		      STRIP_NOPS (output);
+		      if (TREE_CODE (output) == CONST_DECL
+			  && DECL_CONST_CORRESPONDING_VAR (output))
+			output = DECL_CONST_CORRESPONDING_VAR (output);
+		      if (!gnat_mark_addressable (output))
+			output = error_mark_node;
+		    }
 		}
 	      else
 		output = error_mark_node;
@@ -5511,9 +5519,15 @@  gnat_to_gnu (Node_Id gnat_node)
 		{
 		  /* If the operand is going to end up in memory,
 		     mark it addressable.  */
-		  if (!allows_reg && allows_mem
-		      && !gnat_mark_addressable (input))
-		    input = error_mark_node;
+		  if (!allows_reg && allows_mem)
+		    {
+		      STRIP_NOPS (input);
+		      if (TREE_CODE (input) == CONST_DECL
+			  && DECL_CONST_CORRESPONDING_VAR (input))
+			input = DECL_CONST_CORRESPONDING_VAR (input);
+		      if (!gnat_mark_addressable (input))
+			input = error_mark_node;
+		    }
 		}
 	      else
 		input = error_mark_node;
Index: sem_attr.adb
===================================================================
--- sem_attr.adb	(revision 175136)
+++ sem_attr.adb	(working copy)
@@ -2243,6 +2243,13 @@  package body Sem_Attr is
 
       when Attribute_Asm_Input =>
          Check_Asm_Attribute;
+
+         --  The back-end may need to take the address of E2
+
+         if Is_Entity_Name (E2) then
+            Set_Address_Taken (Entity (E2));
+         end if;
+
          Set_Etype (N, RTE (RE_Asm_Input_Operand));
 
       ----------------
@@ -2263,6 +2270,13 @@  package body Sem_Attr is
          end if;
 
          Note_Possible_Modification (E2, Sure => True);
+
+         --  The back-end may need to take the address of E2
+
+         if Is_Entity_Name (E2) then
+            Set_Address_Taken (Entity (E2));
+         end if;
+
          Set_Etype (N, RTE (RE_Asm_Output_Operand));
 
       ---------------