]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada-tree.h (DECL_CAN_NEVER_BE_NULL_P): New macro.
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 26 Sep 2011 08:26:37 +0000 (08:26 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 26 Sep 2011 08:26:37 +0000 (08:26 +0000)
* gcc-interface/ada-tree.h (DECL_CAN_NEVER_BE_NULL_P): New macro.
* gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Set the flag.
(gnat_to_gnu_param): Likewise.
* gcc-interface/utils.c (convert) <UNCONSTRAINED_ARRAY_REF>: Invoke
maybe_unconstrained_array instead of doing the work manually.
(maybe_unconstrained_array): Propagate the TREE_THIS_NOTRAP flag.
* gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: If operand
is a DECL with the flag, set TREE_THIS_NOTRAP on the reference.
(gnat_stabilize_reference_1): Propagate the TREE_THIS_NOTRAP flag.
(gnat_stabilize_reference): Likewise.

From-SVN: r179182

gcc/ada/ChangeLog
gcc/ada/gcc-interface/ada-tree.h
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/utils.c
gcc/ada/gcc-interface/utils2.c

index b114542ff52d5389c5b6dbe21cac227102b13e04..47842198be60e8d4c62251a588c0da0617e726ea 100644 (file)
@@ -1,3 +1,16 @@
+2011-09-26  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/ada-tree.h (DECL_CAN_NEVER_BE_NULL_P): New macro.
+       * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Set the flag.
+       (gnat_to_gnu_param): Likewise.
+       * gcc-interface/utils.c (convert) <UNCONSTRAINED_ARRAY_REF>: Invoke
+       maybe_unconstrained_array instead of doing the work manually.
+       (maybe_unconstrained_array): Propagate the TREE_THIS_NOTRAP flag.
+       * gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: If operand
+       is a DECL with the flag, set TREE_THIS_NOTRAP on the reference.
+       (gnat_stabilize_reference_1): Propagate the TREE_THIS_NOTRAP flag.
+       (gnat_stabilize_reference): Likewise.
+
 2011-09-26  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/ada-tree.h (TYPE_NULL_BOUNDS): New macro.
index 4a0981d44d0fc254d1f995f4732d34d0f4b667bd..d10fcf0ad928f5a7acfe67b1a071c5121284db1c 100644 (file)
@@ -352,6 +352,9 @@ do {                                                   \
    is needed to access the object.  */
 #define DECL_BY_REF_P(NODE) DECL_LANG_FLAG_1 (NODE)
 
+/* Nonzero in a DECL if it is made for a pointer that can never be null.  */
+#define DECL_CAN_NEVER_BE_NULL_P(NODE) DECL_LANG_FLAG_2 (NODE)
+
 /* Nonzero in a FIELD_DECL that is a dummy built for some internal reason.  */
 #define DECL_INTERNAL_P(NODE) DECL_LANG_FLAG_3 (FIELD_DECL_CHECK (NODE))
 
@@ -364,7 +367,7 @@ do {                                                   \
   DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (NODE))
 
 /* Nonzero in a DECL if it is made for a pointer that points to something which
-   is readonly.  Used mostly for fat pointers.  */
+   is readonly.  */
 #define DECL_POINTS_TO_READONLY_P(NODE) DECL_LANG_FLAG_4 (NODE)
 
 /* Nonzero in a PARM_DECL if we are to pass by descriptor.  */
index ea8eb914877d6ed9ac3aa16e6eb64df5696374a3..98d68fe01a67e0f463f9a5e037c07ae9eae06cd8 100644 (file)
@@ -1417,6 +1417,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
                             gnat_entity);
        DECL_BY_REF_P (gnu_decl) = used_by_ref;
        DECL_POINTS_TO_READONLY_P (gnu_decl) = used_by_ref && inner_const_flag;
+       DECL_CAN_NEVER_BE_NULL_P (gnu_decl) = Can_Never_Be_Null (gnat_entity);
 
        /* If we are defining an Out parameter and optimization isn't enabled,
           create a fake PARM_DECL for debugging purposes and make it point to
@@ -5568,6 +5569,7 @@ gnat_to_gnu_param (Entity_Id gnat_param, Mechanism_Type mech,
                                       mech == By_Short_Descriptor);
   DECL_POINTS_TO_READONLY_P (gnu_param)
     = (ro_param && (by_ref || by_component_ptr));
+  DECL_CAN_NEVER_BE_NULL_P (gnu_param) = Can_Never_Be_Null (gnat_param);
 
   /* Save the alternate descriptor type, if any.  */
   if (gnu_param_type_alt)
index 4d95845bd3c5ac045390f994f35573d19b275341..baa4ca1983b1e7043e3901f476504dbdf0ce78fa 100644 (file)
@@ -3819,8 +3819,7 @@ convert (tree type, tree expr)
       return gnat_build_constructor (type, v);
     }
 
-  /* There are some special cases of expressions that we process
-     specially.  */
+  /* There are some cases of expressions that we process specially.  */
   switch (TREE_CODE (expr))
     {
     case ERROR_MARK:
@@ -3976,21 +3975,11 @@ convert (tree type, tree expr)
       break;
 
     case UNCONSTRAINED_ARRAY_REF:
-      {
-       /* Convert this to the type of the inner array by getting the address
-          of the array from the template.  */
-       const bool no_trap = TREE_THIS_NOTRAP (expr);
-       expr = TREE_OPERAND (expr, 0);
-       expr = build_unary_op (INDIRECT_REF, NULL_TREE,
-                              build_component_ref (expr, NULL_TREE,
-                                                   TYPE_FIELDS
-                                                   (TREE_TYPE (expr)),
-                                                   false));
-       TREE_THIS_NOTRAP (expr) = no_trap;
-       etype = TREE_TYPE (expr);
-       ecode = TREE_CODE (etype);
-       break;
-      }
+      /* First retrieve the underlying array.  */
+      expr = maybe_unconstrained_array (expr);
+      etype = TREE_TYPE (expr);
+      ecode = TREE_CODE (etype);
+      break;
 
     case VIEW_CONVERT_EXPR:
       {
@@ -4282,6 +4271,8 @@ maybe_unconstrained_array (tree exp)
       if (code == UNCONSTRAINED_ARRAY_REF)
        {
          const bool read_only = TREE_READONLY (exp);
+         const bool no_trap = TREE_THIS_NOTRAP (exp);
+
          exp = TREE_OPERAND (exp, 0);
          if (TREE_CODE (exp) == COND_EXPR)
            {
@@ -4306,12 +4297,16 @@ maybe_unconstrained_array (tree exp)
                            TREE_OPERAND (exp, 0), op1, op2);
            }
          else
-           exp = build_unary_op (INDIRECT_REF, NULL_TREE,
-                                 build_component_ref (exp, NULL_TREE,
-                                                      TYPE_FIELDS
-                                                      (TREE_TYPE (exp)),
-                                                      false));
-         TREE_READONLY (exp) = read_only;
+           {
+             exp = build_unary_op (INDIRECT_REF, NULL_TREE,
+                                   build_component_ref (exp, NULL_TREE,
+                                                        TYPE_FIELDS
+                                                        (TREE_TYPE (exp)),
+                                                        false));
+             TREE_READONLY (exp) = read_only;
+             TREE_THIS_NOTRAP (exp) = no_trap;
+           }
+
          return exp;
        }
 
index 0cc554d345da50b2f7d41fe0d25325d9f551ff32..12c517c5c4a098edbe1cdeeca80ee4f78ce292ea 100644 (file)
@@ -1276,44 +1276,60 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
       break;
 
     case INDIRECT_REF:
-      /* If we want to refer to an unconstrained array, use the appropriate
-        expression to do so.  This will never survive down to the back-end.
-        But if TYPE is a thin pointer, first convert to a fat pointer.  */
-      if (TYPE_IS_THIN_POINTER_P (type)
-         && TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type)))
-       {
-         operand
-           = convert (TREE_TYPE (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))),
+      {
+       bool can_never_be_null;
+       tree t = operand;
+
+       while (CONVERT_EXPR_P (t) || TREE_CODE (t) == VIEW_CONVERT_EXPR)
+         t = TREE_OPERAND (t, 0);
+
+       can_never_be_null = DECL_P (t) && DECL_CAN_NEVER_BE_NULL_P (t);
+
+       /* If TYPE is a thin pointer, first convert to the fat pointer.  */
+       if (TYPE_IS_THIN_POINTER_P (type)
+           && TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type)))
+         {
+           operand = convert
+                     (TREE_TYPE (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))),
                       operand);
-         type = TREE_TYPE (operand);
-       }
+           type = TREE_TYPE (operand);
+         }
 
-      if (TYPE_IS_FAT_POINTER_P (type))
-       {
-         result = build1 (UNCONSTRAINED_ARRAY_REF,
-                          TYPE_UNCONSTRAINED_ARRAY (type), operand);
-         TREE_READONLY (result)
-           = TYPE_READONLY (TYPE_UNCONSTRAINED_ARRAY (type));
-       }
+       /* If we want to refer to an unconstrained array, use the appropriate
+          expression.  But this will never survive down to the back-end.  */
+       if (TYPE_IS_FAT_POINTER_P (type))
+         {
+           result = build1 (UNCONSTRAINED_ARRAY_REF,
+                            TYPE_UNCONSTRAINED_ARRAY (type), operand);
+           TREE_READONLY (result)
+             = TYPE_READONLY (TYPE_UNCONSTRAINED_ARRAY (type));
+         }
 
-      /* If we are dereferencing an ADDR_EXPR, return its operand.  */
-      else if (TREE_CODE (operand) == ADDR_EXPR)
-       result = TREE_OPERAND (operand, 0);
+       /* If we are dereferencing an ADDR_EXPR, return its operand.  */
+       else if (TREE_CODE (operand) == ADDR_EXPR)
+         result = TREE_OPERAND (operand, 0);
 
-      /* Otherwise, build and fold the indirect reference.  */
-      else
-       {
-         result = build_fold_indirect_ref (operand);
-         TREE_READONLY (result) = TYPE_READONLY (TREE_TYPE (type));
-       }
+       /* Otherwise, build and fold the indirect reference.  */
+       else
+         {
+           result = build_fold_indirect_ref (operand);
+           TREE_READONLY (result) = TYPE_READONLY (TREE_TYPE (type));
+         }
 
-      if (!TYPE_IS_FAT_POINTER_P (type) && TYPE_VOLATILE (TREE_TYPE (type)))
-       {
-         TREE_SIDE_EFFECTS (result) = 1;
-         if (TREE_CODE (result) == INDIRECT_REF)
-           TREE_THIS_VOLATILE (result) = TYPE_VOLATILE (TREE_TYPE (result));
-       }
-      break;
+       if (!TYPE_IS_FAT_POINTER_P (type) && TYPE_VOLATILE (TREE_TYPE (type)))
+         {
+           TREE_SIDE_EFFECTS (result) = 1;
+           if (TREE_CODE (result) == INDIRECT_REF)
+             TREE_THIS_VOLATILE (result) = TYPE_VOLATILE (TREE_TYPE (result));
+         }
+
+       if ((TREE_CODE (result) == INDIRECT_REF
+            || TREE_CODE (result) == UNCONSTRAINED_ARRAY_REF)
+           && can_never_be_null)
+         TREE_THIS_NOTRAP (result) = 1;
+
+       break;
+      }
 
     case NEGATE_EXPR:
     case BIT_NOT_EXPR:
@@ -2442,7 +2458,10 @@ gnat_stabilize_reference_1 (tree e, bool force)
   TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (e);
   TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
 
-  if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
+  if (code == INDIRECT_REF
+      || code == UNCONSTRAINED_ARRAY_REF
+      || code == ARRAY_REF
+      || code == ARRAY_RANGE_REF)
     TREE_THIS_NOTRAP (result) = TREE_THIS_NOTRAP (e);
 
   return result;
@@ -2578,7 +2597,10 @@ gnat_stabilize_reference (tree ref, bool force, bool *success)
   TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (ref);
   TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
 
-  if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
+  if (code == INDIRECT_REF
+      || code == UNCONSTRAINED_ARRAY_REF
+      || code == ARRAY_REF
+      || code == ARRAY_RANGE_REF)
     TREE_THIS_NOTRAP (result) = TREE_THIS_NOTRAP (ref);
 
   return result;