trans.c (addressable_p): Accept COND_EXPR when both arms are addressable.
authorOlivier Hainque <hainque@gcc.gnu.org>
Fri, 21 Mar 2008 11:43:54 +0000 (11:43 +0000)
committerOlivier Hainque <hainque@gcc.gnu.org>
Fri, 21 Mar 2008 11:43:54 +0000 (11:43 +0000)
2008-03-21  Olivier Hainque  <hainque@adacore.com>
            Ed Schonberg  <schonberg@adacore.com>

* trans.c (addressable_p): Accept COND_EXPR when both arms
are addressable.
(gnat_gimplify_expr): Let the gimplifier handle &COND_EXPR.
(call_to_gnu): Do not use name reference in the error message
for a misaligned by_reference_parameter. The actual may be a
general expression.

From-SVN: r133418

gcc/ada/trans.c

index 4cfd2253987516e8fb9c052a094e7fc8045f1d54..534a056cc694a0c9edc3af03449e564671296e22 100644 (file)
@@ -2117,7 +2117,7 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
          /* If the type is by_reference, a copy is not allowed.  */
          if (Is_By_Reference_Type (Etype (gnat_formal)))
            post_error
-             ("misaligned & cannot be passed by reference", gnat_actual);
+             ("misaligned actual cannot be passed by reference", gnat_actual);
 
          /* For users of Starlet we issue a warning because the
             interface apparently assumes that by-ref parameters
@@ -5286,6 +5286,13 @@ gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
          TREE_READONLY (op) = 0;
        }
 
+      /* We let the gimplifier process &COND_EXPR and expect it to yield the
+        address of the selected operand when it is addressable.  Besides, we
+        also expect addressable_p to only let COND_EXPRs where both arms are
+        addressable reach here.  */
+      else if (TREE_CODE (op) == COND_EXPR)
+       ;
+
       /* Otherwise, if we are taking the address of something that is neither
         reference, declaration, or constant, make a variable for the operand
         here and then take its address.  If we don't do it this way, we may
@@ -6117,6 +6124,12 @@ addressable_p (tree gnu_expr, tree gnu_type)
     case CALL_EXPR:
       return true;
 
+    case COND_EXPR:
+      /* We accept &COND_EXPR as soon as both operands are addressable and
+        expect the outcome to be the address of the selected operand.  */
+      return (addressable_p (TREE_OPERAND (gnu_expr, 1), NULL_TREE)
+             && addressable_p (TREE_OPERAND (gnu_expr, 2), NULL_TREE));
+
     case COMPONENT_REF:
       return (!DECL_BIT_FIELD (TREE_OPERAND (gnu_expr, 1))
              && (!STRICT_ALIGNMENT