Patch to remove empty _elabs _elabb - ytomino/drake GitHub Wiki

Now, sometimes gcc-4.7 meaninglessly generates empty _elabs/_elabb for some packages having nothing to initialization. These empty routines are harmless, but make a executable file fat.

This patch removes these.

diff --git gcc/ada/bindgen.adb gcc/ada/bindgen.adb
index a4b7d39..33af4bf 100644
--- gcc/ada/bindgen.adb
+++ gcc/ada/bindgen.adb
@@ -1338,6 +1338,7 @@ package body Bindgen is
       U     : Unit_Record;
       Uspec : Unit_Record;
       Unum  : Unit_Id;
+      Has_E : Boolean;

       procedure Gen_Header;
       --  Generate the header of the finalization routine
@@ -1389,6 +1390,12 @@ package body Bindgen is

          Get_Name_String (Uspec.Uname);

+         --  same condition as Gen_Elab_Externals
+         Has_E := Uspec.Set_Elab_Entity
+            and then not Uspec.SAL_Interface
+            and then not (No_Run_Time_Mode
+               and then Is_Predefined_File_Name (Uspec.Sfile));
+
          --  We are only interested in non-generic packages

          if U.Unit_Kind /= 'p' or else U.Is_Generic then
@@ -1408,7 +1415,9 @@ package body Bindgen is
             --  has a finalizer. In that case, this is where we decrement
             --  the elaboration entity.

-            if U.Utype = Is_Body and then Uspec.Has_Finalizer then
+            if U.Utype = Is_Body and then Uspec.Has_Finalizer
+               and then Has_E
+            then
                if not Lib_Final_Built then
                   Gen_Header;
                   Lib_Final_Built := True;
@@ -1522,7 +1531,9 @@ package body Bindgen is

             WBI ("      begin");

-            if U.Utype /= Is_Spec then
+            if U.Utype /= Is_Spec
+               and then Has_E
+            then
                Set_String ("         E");
                Set_Unit_Number (Unum);
                Set_String (" := E");
@@ -1531,7 +1542,9 @@ package body Bindgen is
                Write_Statement_Buffer;
             end if;

-            if Interface_Library_Unit or not Bind_Main_Program then
+            if (Interface_Library_Unit or not Bind_Main_Program)
+               and then Has_E
+            then
                Set_String ("         if E");
                Set_Unit_Number (Unum);
                Set_String (" = 0 then");
@@ -1544,7 +1557,9 @@ package body Bindgen is
             Set_Char   (';');
             Write_Statement_Buffer;

-            if Interface_Library_Unit or not Bind_Main_Program then
+            if (Interface_Library_Unit or not Bind_Main_Program)
+               and then Has_E
+            then
                WBI ("         end if;");
             end if;

diff --git gcc/ada/gcc-interface/trans.c gcc/ada/gcc-interface/trans.c
index eebe2a9..805f384 100644
--- gcc/ada/gcc-interface/trans.c
+++ gcc/ada/gcc-interface/trans.c
@@ -263,6 +263,34 @@ static tree create_init_temporary (const char *, tree, tree *, Node_Id);
    of configurations.  */
 static const char *extract_encoding (const char *) ATTRIBUTE_UNUSED;
 static const char *decode_name (const char *) ATTRIBUTE_UNUSED;
+
+static bool is_empty (tree x);
+static bool is_empty (tree x)
+{
+  if (x){
+    switch (TREE_CODE (x)){
+    case STATEMENT_LIST:
+      do {
+        struct tree_statement_list_node *i = STATEMENT_LIST_HEAD(x);
+        while (i){
+          if (! is_empty (i->stmt)){
+            return false;
+          }
+          i = i->next;
+        }
+      }while (0);
+      break;
+    case STMT_STMT:
+      if (! is_empty (STMT_STMT_STMT (x))){ /* elm->exp.operands[0] */
+        return false;
+      }
+      break;
+    default:
+      return false;
+    }
+  }
+  return true;
+}

 /* This is the main program of the back-end.  It sets up all the table
    structures and then generates code.  */
@@ -659,7 +687,7 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
       gnu_stmts = gnu_body;
       if (TREE_CODE (gnu_stmts) == BIND_EXPR)
       gnu_stmts = BIND_EXPR_BODY (gnu_stmts);
-      if (!gnu_stmts || !STATEMENT_LIST_HEAD (gnu_stmts))
+      if (is_empty (gnu_stmts))
       Set_Has_No_Elaboration_Code (info->gnat_node, 1);
       else
       {
⚠️ **GitHub.com Fallback** ⚠️