]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ada/gcc-interface/trans.c
Merge in trunk.
[thirdparty/gcc.git] / gcc / ada / gcc-interface / trans.c
index a20078993c95014f8dc65c905cbee1dbaa8fb991..118f9f223dc7435a44668ab65814e554941e33a0 100644 (file)
@@ -257,6 +257,8 @@ static tree pos_to_constructor (Node_Id, tree, Entity_Id);
 static void validate_unchecked_conversion (Node_Id);
 static tree maybe_implicit_deref (tree);
 static void set_expr_location_from_node (tree, Node_Id);
+static void set_expr_location_from_node1 (tree, Node_Id, bool);
+static bool Sloc_to_locus1 (Source_Ptr, location_t *, bool);
 static bool set_end_locus_from_node (tree, Node_Id);
 static void set_gnu_expr_location_from_node (tree, Node_Id);
 static int lvalue_required_p (Node_Id, tree, bool, bool, bool);
@@ -288,9 +290,6 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
   tree int64_type = gnat_type_for_size (64, 0);
   struct elab_info *info;
   int i;
-#ifdef ORDINARY_MAP_INSTANCE
-  struct line_map *map;
-#endif
 
   max_gnat_nodes = max_gnat_node;
 
@@ -305,10 +304,6 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
 
   type_annotate_only = (gigi_operating_mode == 1);
 
-  /* ??? Disable the generation of the SCO instance table until after the
-     back-end supports instance based debug info discriminators.  */
-  Generate_SCO_Instance_Table = False;
-
   for (i = 0; i < number_file; i++)
     {
       /* Use the identifier table to make a permanent copy of the filename as
@@ -328,11 +323,6 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
       /* We create the line map for a source file at once, with a fixed number
         of columns chosen to avoid jumping over the next power of 2.  */
       linemap_add (line_table, LC_ENTER, 0, filename, 1);
-#ifdef ORDINARY_MAP_INSTANCE
-      map = LINEMAPS_ORDINARY_MAP_AT (line_table, i);
-      if (flag_debug_instances)
-       ORDINARY_MAP_INSTANCE (map) = file_info_ptr[i].Instance;
-#endif
       linemap_line_start (line_table, file_info_ptr[i].Num_Source_Lines, 252);
       linemap_position_for_column (line_table, 252 - 1);
       linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
@@ -575,6 +565,15 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
      NULL_TREE, is_disabled, true, true, true, NULL, Empty);
   DECL_IGNORED_P (get_excptr_decl) = 1;
 
+  set_exception_parameter_decl
+    = create_subprog_decl
+      (get_identifier ("__gnat_set_exception_parameter"), NULL_TREE,
+       build_function_type_list (void_type_node,
+                                ptr_void_type_node,
+                                ptr_void_type_node,
+                                NULL_TREE),
+       NULL_TREE, is_disabled, true, true, true, NULL, Empty);
+
   raise_nodefer_decl
     = create_subprog_decl
       (get_identifier ("__gnat_raise_nodefer_with_msg"), NULL_TREE,
@@ -642,20 +641,20 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
   others_decl
     = create_var_decl (get_identifier ("OTHERS"),
                       get_identifier ("__gnat_others_value"),
-                      integer_type_node, NULL_TREE, true, false, true, false,
-                      NULL, Empty);
+                      unsigned_char_type_node,
+                      NULL_TREE, true, false, true, false, NULL, Empty);
 
   all_others_decl
     = create_var_decl (get_identifier ("ALL_OTHERS"),
                       get_identifier ("__gnat_all_others_value"),
-                      integer_type_node, NULL_TREE, true, false, true, false,
-                      NULL, Empty);
+                      unsigned_char_type_node,
+                      NULL_TREE, true, false, true, false, NULL, Empty);
 
   unhandled_others_decl
     = create_var_decl (get_identifier ("UNHANDLED_OTHERS"),
                       get_identifier ("__gnat_unhandled_others_value"),
-                      integer_type_node, NULL_TREE, true, false, true, false,
-                      NULL, Empty);
+                      unsigned_char_type_node,
+                      NULL_TREE, true, false, true, false, NULL, Empty);
 
   main_identifier_node = get_identifier ("main");
 
@@ -1401,6 +1400,7 @@ Pragma_to_gnu (Node_Id gnat_node)
 static tree
 Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
 {
+  const Node_Id gnat_prefix = Prefix (gnat_node);
   tree gnu_prefix, gnu_type, gnu_expr;
   tree gnu_result_type, gnu_result = error_mark_node;
   bool prefix_unused = false;
@@ -1410,13 +1410,13 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
      parameter types might be incomplete types coming from a limited with.  */
   if (Ekind (Etype (gnat_node)) == E_Access_Subprogram_Type
       && Is_Dispatch_Table_Entity (Etype (gnat_node))
-      && Nkind (Prefix (gnat_node)) == N_Identifier
-      && Is_Subprogram (Entity (Prefix (gnat_node)))
-      && Is_Public (Entity (Prefix (gnat_node)))
-      && !present_gnu_tree (Entity (Prefix (gnat_node))))
-    gnu_prefix = get_minimal_subprog_decl (Entity (Prefix (gnat_node)));
+      && Nkind (gnat_prefix) == N_Identifier
+      && Is_Subprogram (Entity (gnat_prefix))
+      && Is_Public (Entity (gnat_prefix))
+      && !present_gnu_tree (Entity (gnat_prefix)))
+    gnu_prefix = get_minimal_subprog_decl (Entity (gnat_prefix));
   else
-    gnu_prefix = gnat_to_gnu (Prefix (gnat_node));
+    gnu_prefix = gnat_to_gnu (gnat_prefix);
   gnu_type = TREE_TYPE (gnu_prefix);
 
   /* If the input is a NULL_EXPR, make a new one.  */
@@ -1559,8 +1559,8 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
         since it can use a special calling convention on some platforms,
         which cannot be propagated to the access type.  */
       else if (attribute == Attr_Access
-              && Nkind (Prefix (gnat_node)) == N_Identifier
-              && is_cplusplus_method (Entity (Prefix (gnat_node))))
+              && Nkind (gnat_prefix) == N_Identifier
+              && is_cplusplus_method (Entity (gnat_prefix)))
        post_error ("access to C++ constructor or member function not allowed",
                    gnat_node);
 
@@ -1671,13 +1671,12 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
          /* If this is a dereference and we have a special dynamic constrained
             subtype on the prefix, use it to compute the size; otherwise, use
             the designated subtype.  */
-         if (Nkind (Prefix (gnat_node)) == N_Explicit_Dereference)
+         if (Nkind (gnat_prefix) == N_Explicit_Dereference)
            {
-             Node_Id gnat_deref = Prefix (gnat_node);
              Node_Id gnat_actual_subtype
-               = Actual_Designated_Subtype (gnat_deref);
+               = Actual_Designated_Subtype (gnat_prefix);
              tree gnu_ptr_type
-               = TREE_TYPE (gnat_to_gnu (Prefix (gnat_deref)));
+               = TREE_TYPE (gnat_to_gnu (Prefix (gnat_prefix)));
 
              if (TYPE_IS_FAT_OR_THIN_POINTER_P (gnu_ptr_type)
                  && Present (gnat_actual_subtype))
@@ -1738,7 +1737,6 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
          align = DECL_ALIGN (TREE_OPERAND (gnu_prefix, 1)) / BITS_PER_UNIT;
        else
          {
-           Node_Id gnat_prefix = Prefix (gnat_node);
            Entity_Id gnat_type = Etype (gnat_prefix);
            unsigned int double_align;
            bool is_capped_double, align_clause;
@@ -1810,28 +1808,38 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
                         : 1), i;
        struct parm_attr_d *pa = NULL;
        Entity_Id gnat_param = Empty;
+       bool unconstrained_ptr_deref = false;
 
        /* Make sure any implicit dereference gets done.  */
        gnu_prefix = maybe_implicit_deref (gnu_prefix);
        gnu_prefix = maybe_unconstrained_array (gnu_prefix);
 
-       /* We treat unconstrained array In parameters specially.  */
-       if (!Is_Constrained (Etype (Prefix (gnat_node))))
-         {
-           Node_Id gnat_prefix = Prefix (gnat_node);
-
-           /* This is the direct case.  */
-           if (Nkind (gnat_prefix) == N_Identifier
-               && Ekind (Entity (gnat_prefix)) == E_In_Parameter)
-             gnat_param = Entity (gnat_prefix);
-
-           /* This is the indirect case.  Note that we need to be sure that
-              the access value cannot be null as we'll hoist the load.  */
-           if (Nkind (gnat_prefix) == N_Explicit_Dereference
-               && Nkind (Prefix (gnat_prefix)) == N_Identifier
-               && Ekind (Entity (Prefix (gnat_prefix))) == E_In_Parameter
-               && Can_Never_Be_Null (Entity (Prefix (gnat_prefix))))
-             gnat_param = Entity (Prefix (gnat_prefix));
+       /* We treat unconstrained array In parameters specially.  We also note
+          whether we are dereferencing a pointer to unconstrained array.  */
+       if (!Is_Constrained (Etype (gnat_prefix)))
+         switch (Nkind (gnat_prefix))
+           {
+           case N_Identifier:
+             /* This is the direct case.  */
+             if (Ekind (Entity (gnat_prefix)) == E_In_Parameter)
+               gnat_param = Entity (gnat_prefix);
+             break;
+
+           case N_Explicit_Dereference:
+             /* This is the indirect case.  Note that we need to be sure that
+                the access value cannot be null as we'll hoist the load.  */
+             if (Nkind (Prefix (gnat_prefix)) == N_Identifier
+                 && Ekind (Entity (Prefix (gnat_prefix))) == E_In_Parameter)
+               {
+                 if (Can_Never_Be_Null (Entity (Prefix (gnat_prefix))))
+                   gnat_param = Entity (Prefix (gnat_prefix));
+               }
+             else
+               unconstrained_ptr_deref = true;
+             break;
+
+           default:
+             break;
          }
 
        /* If the prefix is the view conversion of a constrained array to an
@@ -1966,22 +1974,54 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
          {
            gnu_result
              = build1 (SAVE_EXPR, TREE_TYPE (gnu_result), gnu_result);
-           if (attribute == Attr_First)
-             pa->first = gnu_result;
-           else if (attribute == Attr_Last)
-             pa->last = gnu_result;
-           else
-             pa->length = gnu_result;
+           switch (attribute)
+             {
+             case Attr_First:
+               pa->first = gnu_result;
+               break;
+
+             case Attr_Last:
+               pa->last = gnu_result;
+               break;
+
+             case Attr_Length:
+             case Attr_Range_Length:
+               pa->length = gnu_result;
+               break;
+
+             default:
+               gcc_unreachable ();
+             }
          }
 
-       /* Set the source location onto the predicate of the condition in the
-          'Length case but do not do it if the expression is cached to avoid
-          messing up the debug info.  */
-       else if ((attribute == Attr_Range_Length || attribute == Attr_Length)
-                && TREE_CODE (gnu_result) == COND_EXPR
-                && EXPR_P (TREE_OPERAND (gnu_result, 0)))
-         set_expr_location_from_node (TREE_OPERAND (gnu_result, 0),
-                                      gnat_node);
+       /* Otherwise, evaluate it each time it is referenced.  */
+       else
+         switch (attribute)
+           {
+           case Attr_First:
+           case Attr_Last:
+             /* If we are dereferencing a pointer to unconstrained array, we
+                need to capture the value because the pointed-to bounds may
+                subsequently be released.  */
+             if (unconstrained_ptr_deref)
+               gnu_result
+                 = build1 (SAVE_EXPR, TREE_TYPE (gnu_result), gnu_result);
+             break;
+
+           case Attr_Length:
+           case Attr_Range_Length:
+             /* Set the source location onto the predicate of the condition
+                but not if the expression is cached to avoid messing up the
+                debug info.  */
+             if (TREE_CODE (gnu_result) == COND_EXPR
+                 && EXPR_P (TREE_OPERAND (gnu_result, 0)))
+               set_expr_location_from_node (TREE_OPERAND (gnu_result, 0),
+                                            gnat_node);
+             break;
+
+           default:
+             gcc_unreachable ();
+           }
 
        break;
       }
@@ -2154,8 +2194,8 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
 
     case Attr_Mechanism_Code:
       {
+       Entity_Id gnat_obj = Entity (gnat_prefix);
        int code;
-       Entity_Id gnat_obj = Entity (Prefix (gnat_node));
 
        prefix_unused = true;
        gnu_result_type = get_unpadded_type (Etype (gnat_node));
@@ -2190,10 +2230,11 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
      it has a side-effect.  But don't do it if the prefix is just an entity
      name.  However, if an access check is needed, we must do it.  See second
      example in AARM 11.6(5.e).  */
-  if (prefix_unused && TREE_SIDE_EFFECTS (gnu_prefix)
-      && !Is_Entity_Name (Prefix (gnat_node)))
-    gnu_result = build_compound_expr  (TREE_TYPE (gnu_result), gnu_prefix,
-                                      gnu_result);
+  if (prefix_unused
+      && TREE_SIDE_EFFECTS (gnu_prefix)
+      && !Is_Entity_Name (gnat_prefix))
+    gnu_result
+      = build_compound_expr  (TREE_TYPE (gnu_result), gnu_prefix, gnu_result);
 
   *gnu_result_type_p = gnu_result_type;
   return gnu_result;
@@ -2719,7 +2760,7 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
 
       /* First, if we have computed a small number of invariant conditions for
         range checks applied to the iteration variable, then initialize these
-        conditions in front of the loop.  Otherwise, leave them set to True.
+        conditions in front of the loop.  Otherwise, leave them set to true.
 
         ??? The heuristics need to be improved, by taking into account the
             following datapoints:
@@ -3205,7 +3246,7 @@ finalize_nrv (tree fndecl, bitmap nrv, vec<tree, va_gc> *other, Node_Id gnat_ret
   /* Prune also the candidates that are referenced by nested functions.  */
   node = cgraph_get_create_node (fndecl);
   for (node = node->nested; node; node = node->next_nested)
-    walk_tree_without_duplicates (&DECL_SAVED_TREE (node->symbol.decl), prune_nrv_r,
+    walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl), prune_nrv_r,
                                  &data);
   if (bitmap_empty_p (nrv))
     return;
@@ -3603,6 +3644,8 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
     {
       tree gnu_retval;
 
+      gnu_return_var_stack->pop ();
+
       add_stmt (gnu_result);
       add_stmt (build1 (LABEL_EXPR, void_type_node,
                        gnu_return_label_stack->last ()));
@@ -4471,6 +4514,10 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
   tree gnu_result;
   tree gnu_expr;
   Node_Id gnat_temp;
+  /* Node providing the sloc for the cleanup actions.  */
+  Node_Id gnat_cleanup_loc_node = (Present (End_Label (gnat_node)) ?
+                                   End_Label (gnat_node) :
+                                   gnat_node);
 
   /* The GCC exception handling mechanism can handle both ZCX and SJLJ schemes
      and we have our own SJLJ mechanism.  To call the GCC mechanism, we call
@@ -4520,7 +4567,7 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
 
       /* When we exit this block, restore the saved value.  */
       add_cleanup (build_call_n_expr (set_jmpbuf_decl, 1, gnu_jmpsave_decl),
-                  End_Label (gnat_node));
+                  gnat_cleanup_loc_node);
     }
 
   /* If we are to call a function when exiting this block, add a cleanup
@@ -4528,7 +4575,7 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
      so we must register this cleanup after the EH cleanup just above.  */
   if (at_end)
     add_cleanup (build_call_n_expr (gnat_to_gnu (At_End_Proc (gnat_node)), 0),
-                End_Label (gnat_node));
+                gnat_cleanup_loc_node);
 
   /* Now build the tree for the declarations and statements inside this block.
      If this is SJLJ, set our jmp_buf as the current buffer.  */
@@ -4641,14 +4688,18 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
       /* Now make the TRY_CATCH_EXPR for the block.  */
       gnu_result = build2 (TRY_CATCH_EXPR, void_type_node,
                           gnu_inner_block, gnu_handlers);
-      /* Set a location.  We need to find a uniq location for the dispatching
+      /* Set a location.  We need to find a unique location for the dispatching
         code, otherwise we can get coverage or debugging issues.  Try with
         the location of the end label.  */
       if (Present (End_Label (gnat_node))
          && Sloc_to_locus (Sloc (End_Label (gnat_node)), &locus))
        SET_EXPR_LOCATION (gnu_result, locus);
       else
-       set_expr_location_from_node (gnu_result, gnat_node);
+        /* Clear column information so that the exception handler of an
+           implicit transient block does not incorrectly inherit the slocs
+           of a decision, which would otherwise confuse control flow based
+           coverage analysis tools.  */
+       set_expr_location_from_node1 (gnu_result, gnat_node, true);
     }
   else
     gnu_result = gnu_inner_block;
@@ -4843,9 +4894,23 @@ Exception_Handler_to_gnu_zcx (Node_Id gnat_node)
   add_stmt_with_node (build_call_n_expr (begin_handler_decl, 1,
                                         gnu_incoming_exc_ptr),
                      gnat_node);
-  /* ??? We don't seem to have an End_Label at hand to set the location.  */
+
+  /* Declare and initialize the choice parameter, if present.  */
+  if (Present (Choice_Parameter (gnat_node)))
+    {
+      tree gnu_param = gnat_to_gnu_entity
+       (Choice_Parameter (gnat_node), NULL_TREE, 1);
+
+      add_stmt (build_call_n_expr
+               (set_exception_parameter_decl, 2,
+                build_unary_op (ADDR_EXPR, NULL_TREE, gnu_param),
+                gnu_incoming_exc_ptr));
+    }
+
+  /* We don't have an End_Label at hand to set the location of the cleanup
+     actions, so we use that of the exception handler itself instead.  */
   add_cleanup (build_call_n_expr (end_handler_decl, 1, gnu_incoming_exc_ptr),
-              Empty);
+              gnat_node);
   add_stmt_list (Statements (gnat_node));
   gnat_poplevel ();
 
@@ -4944,7 +5009,7 @@ Compilation_Unit_to_gnu (Node_Id gnat_node)
   /* Process any pragmas and actions following the unit.  */
   add_stmt_list (Pragmas_After (Aux_Decls_Node (gnat_node)));
   add_stmt_list (Actions (Aux_Decls_Node (gnat_node)));
-  finalize_from_with_types ();
+  finalize_from_limited_with ();
 
   /* Save away what we've made so far and record this potential elaboration
      procedure.  */
@@ -6564,7 +6629,7 @@ gnat_to_gnu (Node_Id gnat_node)
           Present (gnat_temp);
           gnat_temp = Next_Formal_With_Extras (gnat_temp))
        if (Is_Itype (Etype (gnat_temp))
-           && !From_With_Type (Etype (gnat_temp)))
+           && !From_Limited_With (Etype (gnat_temp)))
          gnat_to_gnu_entity (Etype (gnat_temp), NULL_TREE, 0);
 
       /* Then the result type, set to Standard_Void_Type for procedures.  */
@@ -6572,7 +6637,7 @@ gnat_to_gnu (Node_Id gnat_node)
        Entity_Id gnat_temp_type
          = Etype (Defining_Entity (Specification (gnat_node)));
 
-       if (Is_Itype (gnat_temp_type) && !From_With_Type (gnat_temp_type))
+       if (Is_Itype (gnat_temp_type) && !From_Limited_With (gnat_temp_type))
          gnat_to_gnu_entity (Etype (gnat_temp_type), NULL_TREE, 0);
       }
 
@@ -6945,6 +7010,10 @@ gnat_to_gnu (Node_Id gnat_node)
       gnu_result = end_stmt_group ();
       break;
 
+    case N_Freeze_Generic_Entity:
+      gnu_result = alloc_stmt_list ();
+      break;
+
     case N_Itype_Reference:
       if (!present_gnu_tree (Itype (gnat_node)))
        process_type (Itype (gnat_node));
@@ -7397,13 +7466,15 @@ mark_visited (tree t)
 }
 
 /* Add GNU_CLEANUP, a cleanup action, to the current code group and
-   set its location to that of GNAT_NODE if present.  */
+   set its location to that of GNAT_NODE if present, but with column info
+   cleared so that conditional branches generated as part of the cleanup
+   code do not interfere with coverage analysis tools.  */
 
 static void
 add_cleanup (tree gnu_cleanup, Node_Id gnat_node)
 {
   if (Present (gnat_node))
-    set_expr_location_from_node (gnu_cleanup, gnat_node);
+    set_expr_location_from_node1 (gnu_cleanup, gnat_node, true);
   append_to_statement_list (gnu_cleanup, &current_stmt_group->cleanups);
 }
 
@@ -9018,10 +9089,11 @@ maybe_implicit_deref (tree exp)
 \f
 /* Convert SLOC into LOCUS.  Return true if SLOC corresponds to a source code
    location and false if it doesn't.  In the former case, set the Gigi global
-   variable REF_FILENAME to the simple debug file name as given by sinput.  */
+   variable REF_FILENAME to the simple debug file name as given by sinput.
+   If clear_column is true, set column information to 0.  */
 
-bool
-Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
+static bool
+Sloc_to_locus1 (Source_Ptr Sloc, location_t *locus, bool clear_column)
 {
   if (Sloc == No_Location)
     return false;
@@ -9035,7 +9107,7 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
     {
       Source_File_Index file = Get_Source_File_Index (Sloc);
       Logical_Line_Number line = Get_Logical_Line_Number (Sloc);
-      Column_Number column = Get_Column_Number (Sloc);
+      Column_Number column = (clear_column ? 0 : Get_Column_Number (Sloc));
       struct line_map *map = LINEMAPS_ORDINARY_MAP_AT (line_table, file - 1);
 
       /* We can have zero if pragma Source_Reference is in effect.  */
@@ -9054,20 +9126,36 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
   return true;
 }
 
+/* Similar to the above, not clearing the column information.  */
+
+bool
+Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
+{
+  return Sloc_to_locus1 (Sloc, locus, false);
+}
+
 /* Similar to set_expr_location, but start with the Sloc of GNAT_NODE and
    don't do anything if it doesn't correspond to a source location.  */
 
 static void
-set_expr_location_from_node (tree node, Node_Id gnat_node)
+set_expr_location_from_node1 (tree node, Node_Id gnat_node, bool clear_column)
 {
   location_t locus;
 
-  if (!Sloc_to_locus (Sloc (gnat_node), &locus))
+  if (!Sloc_to_locus1 (Sloc (gnat_node), &locus, clear_column))
     return;
 
   SET_EXPR_LOCATION (node, locus);
 }
 
+/* Similar to the above, not clearing the column information.  */
+
+static void
+set_expr_location_from_node (tree node, Node_Id gnat_node)
+{
+  set_expr_location_from_node1 (node, gnat_node, false);
+}
+
 /* More elaborate version of set_expr_location_from_node to be used in more
    general contexts, for example the result of the translation of a generic
    GNAT node.  */
@@ -9133,10 +9221,14 @@ post_error (const char *msg, Node_Id node)
   String_Template temp;
   Fat_Pointer fp;
 
-  temp.Low_Bound = 1, temp.High_Bound = strlen (msg);
-  fp.Array = msg, fp.Bounds = &temp;
-  if (Present (node))
-    Error_Msg_N (fp, node);
+  if (No (node))
+    return;
+
+  temp.Low_Bound = 1;
+  temp.High_Bound = strlen (msg);
+  fp.Bounds = &temp;
+  fp.Array = msg;
+  Error_Msg_N (fp, node);
 }
 
 /* Similar to post_error, but NODE is the node at which to post the error and
@@ -9148,10 +9240,14 @@ post_error_ne (const char *msg, Node_Id node, Entity_Id ent)
   String_Template temp;
   Fat_Pointer fp;
 
-  temp.Low_Bound = 1, temp.High_Bound = strlen (msg);
-  fp.Array = msg, fp.Bounds = &temp;
-  if (Present (node))
-    Error_Msg_NE (fp, node, ent);
+  if (No (node))
+    return;
+
+  temp.Low_Bound = 1;
+  temp.High_Bound = strlen (msg);
+  fp.Bounds = &temp;
+  fp.Array = msg;
+  Error_Msg_NE (fp, node, ent);
 }
 
 /* Similar to post_error_ne, but NUM is the number to use for the '^'.  */
@@ -9198,9 +9294,13 @@ set_end_locus_from_node (tree gnu_node, Node_Id gnat_node)
   gnat_node = Present (gnat_end_label) ? gnat_end_label : gnat_node;
 
   /* Some expanded subprograms have neither an End_Label nor a Sloc
-     attached.  Notify that to callers.  */
+     attached.  Notify that to callers.  For a block statement with no
+     End_Label, clear column information, so that the tree for a
+     transient block does not receive the sloc of a source condition.  */
 
-  if (!Sloc_to_locus (Sloc (gnat_node), &end_locus))
+  if (!Sloc_to_locus1 (Sloc (gnat_node), &end_locus,
+                       No (gnat_end_label) &&
+                       (Nkind (gnat_node) == N_Block_Statement)))
     return false;
 
   switch (TREE_CODE (gnu_node))