https://gcc.gnu.org/g:a8e6360765336969e3f45ac16e4340e5e5468768

commit r15-4085-ga8e6360765336969e3f45ac16e4340e5e5468768
Author: Eric Botcazou <ebotca...@adacore.com>
Date:   Sat Oct 5 14:39:14 2024 +0200

    Fix various issues of -ftrivial-auto-var-init=zero with Ada
    
    This polishes a few rough edges that prevent -ftrivial-auto-var-init=zero
    from working in Ada:
    
      - build_common_builtin_nodes declares BUILT_IN_CLEAR_PADDING with 3
      instead 2 parameters, now gimple_fold_builtin_clear_padding contains
      the assertion:
    
        gcc_assert (gimple_call_num_args (stmt) == 2)
    
      This causes gimple_builtin_call_types_compatible_p to always return false
      in Ada (this works in C/C++ because another declaration is used).
    
      - gimple_add_init_for_auto_var uses EXPR_LOCATION to fetch the location
      of a DECL node, which always returns UNKNOWN_LOCATION.
    
      - the machinery attempts to initialize Out parameters.
    
    gcc/
            PR middle-end/116933
            * gimplify.cc (gimple_add_init_for_auto_var): Use the correct macro
            to fetch the source location of the variable.
            * tree.cc (common_builtin_nodes): Remove the 3rd parameter in the
            type of BUILT_IN_CLEAR_PADDING.
    
    gcc/ada/
            PR middle-end/116933
            * gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Out_Parameter>: Add
            the "uninitialized" attribute on Out parameters.
            * gcc-interface/utils.cc (gnat_internal_attributes): Add entry for
            the "uninitialized" attribute.
            (handle_uninitialized_attribute): New function.
    
    gcc/testsuite/
            * gnat.dg/auto_var_init.adb: New test.

Diff:
---
 gcc/ada/gcc-interface/decl.cc           |  7 +++++++
 gcc/ada/gcc-interface/utils.cc          | 27 +++++++++++++++++++++++++++
 gcc/gimplify.cc                         | 11 ++++-------
 gcc/testsuite/gnat.dg/auto_var_init.adb |  9 +++++++++
 gcc/tree.cc                             |  1 -
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index 4252e627b0ce..880eaff8d0b6 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -1563,6 +1563,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree 
gnu_expr, bool definition)
          prepend_one_attribute_pragma (&attr_list,
                                        Linker_Section_Pragma (gnat_entity));
 
+       /* Do not initialize Out parameters with -ftrivial-auto-var-init.  */
+       if (kind == E_Out_Parameter)
+         prepend_one_attribute
+           (&attr_list, ATTR_MACHINE_ATTRIBUTE,
+            get_identifier ("uninitialized"), NULL_TREE,
+            gnat_entity);
+
        /* Now create the variable or the constant and set various flags.  */
        gnu_decl
          = create_var_decl (gnu_entity_name, gnu_ext_name, gnu_type,
diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc
index 60f36b1e50d1..a88a23860d3e 100644
--- a/gcc/ada/gcc-interface/utils.cc
+++ b/gcc/ada/gcc-interface/utils.cc
@@ -107,6 +107,7 @@ static tree handle_malloc_attribute (tree *, tree, tree, 
int, bool *);
 static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
 static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
 static tree handle_used_attribute (tree *, tree, tree, int, bool *);
+static tree handle_uninitialized_attribute (tree *, tree, tree, int, bool *);
 static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
 static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
 static tree handle_simd_attribute (tree *, tree, tree, int, bool *);
@@ -214,6 +215,8 @@ static const attribute_spec gnat_internal_attributes[] =
     handle_flatten_attribute, NULL },
   { "used",         0, 0,  true,  false, false, false,
     handle_used_attribute, NULL },
+  { "uninitialized",0, 0,  true,  false, false, false,
+    handle_uninitialized_attribute, NULL },
   { "cold",         0, 0,  true,  false, false, false,
     handle_cold_attribute, attr_cold_hot_exclusions },
   { "hot",          0, 0,  true,  false, false, false,
@@ -7171,6 +7174,30 @@ handle_used_attribute (tree *pnode, tree name, tree 
ARG_UNUSED (args),
   return NULL_TREE;
 }
 
+/* Handle an "uninitialized" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_uninitialized_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+                               int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+  tree decl = *node;
+  if (!VAR_P (decl))
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored because %qD "
+              "is not a variable", name, decl);
+      *no_add_attrs = true;
+    }
+  else if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored because %qD "
+              "is not a local variable", name, decl);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle a "cold" and attribute; arguments as in
    struct attribute_spec.handler.  */
 
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index dd7efa71b742..6cdc70d21300 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -1993,17 +1993,14 @@ gimple_add_init_for_auto_var (tree decl,
 {
   gcc_assert (auto_var_p (decl));
   gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
-  location_t loc = EXPR_LOCATION (decl);
-  tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
 
-  tree init_type_node
-    = build_int_cst (integer_type_node, (int) init_type);
+  const location_t loc = DECL_SOURCE_LOCATION (decl);
+  tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
+  tree init_type_node = build_int_cst (integer_type_node, (int) init_type);
+  tree decl_name;
 
-  tree decl_name = NULL_TREE;
   if (DECL_NAME (decl))
-
     decl_name = build_string_literal (DECL_NAME (decl));
-
   else
     {
       char decl_name_anonymous[3 + (HOST_BITS_PER_INT + 2) / 3];
diff --git a/gcc/testsuite/gnat.dg/auto_var_init.adb 
b/gcc/testsuite/gnat.dg/auto_var_init.adb
new file mode 100644
index 000000000000..9f0ec7a81592
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/auto_var_init.adb
@@ -0,0 +1,9 @@
+-- { dg-do run }
+-- { dg-options "-ftrivial-auto-var-init=zero" }
+
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure Auto_Var_Init is
+begin
+  Put_Line ("Hello World!");
+end;
diff --git a/gcc/tree.cc b/gcc/tree.cc
index bc50afca9a38..095c02c54741 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -9848,7 +9848,6 @@ build_common_builtin_nodes (void)
       ftype = build_function_type_list (void_type_node,
                                        ptr_type_node,
                                        ptr_type_node,
-                                       integer_type_node,
                                        NULL_TREE);
       local_define_builtin ("__builtin_clear_padding", ftype,
                            BUILT_IN_CLEAR_PADDING,

Reply via email to