This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Fix unrestricted access to value conversion to boolean


The Unrestricted_Access attribute is the equivalent for GNAT of the & operator 
for the C compiler, in particular it will easily create dangling pointers, as 
it can be applied to pretty much anything.  This fixes a case for which such 
a dangling pointer is gratuitously created by Unrestricted_Access.

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


2010-11-10  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/trans.c (lvalue_required_p) <N_Type_Conversion>): Look
	through it for elementary types as well.
	<N_Unchecked_Type_Conversion>: Adjust to above change.
	<N_Allocator>: Likewise.
	(gnat_to_gnu): Do not attempt to rewrite boolean literals.


2010-11-10  Eric Botcazou  <ebotcazou@adacore.com>

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


-- 
Eric Botcazou
-- { dg-do run }

with System; use System;

procedure Boolean_Conv is
  subtype B1 is Boolean;
  subtype B2 is Boolean;
  A0, A1, A2 : Address;

  B : aliased B1;

  procedure P2 (X2 : access B2) is
  begin
     A2 := X2.all'Address;
  end P2;

  procedure P1 (X1 : access B1) is
  begin
     A1 := X1.all'Address;
     P2 (B2 (X1.all)'Unrestricted_Access);
  end P1;

begin
   A0 := B'Address;
   P1 (B'Access);

   if A1 /= A0 then
      raise Program_Error;
   end if;

   if A2 /= A0 then
      raise Program_Error;
   end if;
end;
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 166490)
+++ gcc-interface/trans.c	(working copy)
@@ -829,29 +829,25 @@ lvalue_required_p (Node_Id gnat_node, tr
 	      || (Is_Composite_Type (Underlying_Type (Etype (gnat_node)))
 		  && Is_Atomic (Entity (Name (gnat_parent)))));
 
-    case N_Type_Conversion:
-    case N_Qualified_Expression:
-      /* We must look through all conversions for composite types because we
-	 may need to bypass an intermediate conversion to a narrower record
-	 type that is generated for a formal conversion, e.g. the conversion
-	 to the root type of a hierarchy of tagged types generated for the
-	 formal conversion to the class-wide type.  */
-      if (!Is_Composite_Type (Underlying_Type (Etype (gnat_node))))
-	return 0;
+    case N_Unchecked_Type_Conversion:
+	if (!constant)
+	  return 1;
 
       /* ... fall through ... */
 
-    case N_Unchecked_Type_Conversion:
-      return (!constant
-	      || lvalue_required_p (gnat_parent,
-				    get_unpadded_type (Etype (gnat_parent)),
-				    constant, address_of_constant, aliased));
+    case N_Type_Conversion:
+    case N_Qualified_Expression:
+      /* We must look through all conversions because we may need to bypass
+	 an intermediate conversion that is meant to be purely formal.  */
+     return lvalue_required_p (gnat_parent,
+			       get_unpadded_type (Etype (gnat_parent)),
+			       constant, address_of_constant, aliased);
 
     case N_Allocator:
-      /* We should only reach here through the N_Qualified_Expression case
-	 and, therefore, only for composite types.  Force an lvalue since
-	 a block-copy to the newly allocated area of memory is made.  */
-      return 1;
+      /* We should only reach here through the N_Qualified_Expression case.
+	 Force an lvalue for composite types since a block-copy to the newly
+	 allocated area of memory is made.  */
+      return Is_Composite_Type (Underlying_Type (Etype (gnat_node)));
 
    case N_Explicit_Dereference:
       /* We look through dereferences for address of constant because we need
@@ -5781,6 +5777,7 @@ gnat_to_gnu (Node_Id gnat_node)
      so that the code just below can put the location information of the
      reference to B on the inequality operator for better debug info.  */
   if (!optimize
+      && TREE_CODE (gnu_result) != INTEGER_CST
       && (kind == N_Identifier
 	  || kind == N_Expanded_Name
 	  || kind == N_Explicit_Dereference

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]