This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix PR lto/50492


Hi,

this is another LTO bootstrap failure with Ada enabled.  There are 2 problems:

 1. dwarf2out.c thinks that it is processing pure C++ code for gnat1 so it is 
invoking some C++-specific code paths that aren't compatible with Ada.  Fixed 
by building TRANSLATION_UNIT_DECL nodes in Ada as well.

 2. the recent change:

	* gimple.c (canonicalize_cond_expr_cond): Handle cast from
	boolean-type.

breaks cross-language inlining.  More specifically, it removes a necessary cast 
between an Ada boolean type and a C boolean type (hence a GIMPLE verification 
failure later) when __gnat_is_absolute_path is inlined into Is_Absolute_Path:

   extern int __gnat_is_absolute_path (char *, int);

   function Is_Absolute_Path (Name : String) return Boolean is
      function Is_Absolute_Path
        (Name   : Address;
         Length : Integer) return Integer;
      pragma Import (C, Is_Absolute_Path, "__gnat_is_absolute_path");
   begin
      return Is_Absolute_Path (Name'Address, Name'Length) /= 0;
   end Is_Absolute_Path;

We start with:

  Ada_Boolean_Var = (Integer_Var != 0);

and forwprop figures out that (Integer_Var != 0) is equivalent to iftmp.xxx.
In combine_cond_expr_cond, the constant folder correctly turns this into:

  Ada_Boolean_Var = (Ada_Boolean_Type) iftmp.xxx;

but the call to canonicalize_cond_expr_cond wrongly removes the cast.

Note that changing Ada's boolean_type_node to a C-compatible type doesn't fix 
the problem as the boolean return type of Is_Absolute_Path has to be an Ada 
boolean type in any case, so a cast will be always necessary here.

Since reverting the canonicalize_cond_expr_cond change apparently has no effect 
(no regressions detected on x86 and x86-64), the proposed fix is just that.

Bootstrapped/regtested on x86_64-suse-linux, OK for mainline?


2011-10-07  Eric Botcazou  <ebotcazou@adacore.com>

	PR lto/50492
	* gimple.c (canonicalize_cond_expr_cond): Revert 2011-08-02 change.
ada/
	* gcc-interface/gigi.h (gnat_pushdecl): Adjust comment.
	* gcc-interface/utils.c (global_context): New variable.
	(gnat_pushdecl): Initialize it and set it as the DECL_CONTEXT of DECLs
	that are either public external or at top level.  Use "No" macro.
	(end_subprog_body): Call decl_function_context.
	(rest_of_subprog_body_compilation): Likewise.


-- 
Eric Botcazou
Index: ada/gcc-interface/utils.c
===================================================================
--- ada/gcc-interface/utils.c	(revision 179488)
+++ ada/gcc-interface/utils.c	(working copy)
@@ -200,6 +200,9 @@ static GTY(()) struct gnat_binding_level
 /* A chain of gnat_binding_level structures awaiting reuse.  */
 static GTY((deletable)) struct gnat_binding_level *free_binding_level;
 
+/* The context to be used for global declarations.  */
+static GTY(()) tree global_context;
+
 /* An array of global declarations.  */
 static GTY(()) VEC(tree,gc) *global_decls;
 
@@ -497,15 +500,19 @@ gnat_zaplevel (void)
   free_binding_level = level;
 }
 
-/* Records a ..._DECL node DECL as belonging to the current lexical scope
-   and uses GNAT_NODE for location information and propagating flags.  */
+/* Record DECL as belonging to the current lexical scope and use GNAT_NODE
+   for location information and flag propagation.  */
 
 void
 gnat_pushdecl (tree decl, Node_Id gnat_node)
 {
-  /* If this decl is public external or at toplevel, there is no context.  */
+  /* If DECL is public external or at top level, it has global context.  */
   if ((TREE_PUBLIC (decl) && DECL_EXTERNAL (decl)) || global_bindings_p ())
-    DECL_CONTEXT (decl) = 0;
+    {
+      if (!global_context)
+	global_context = build_translation_unit_decl (NULL_TREE);
+      DECL_CONTEXT (decl) = global_context;
+   }
   else
     {
       DECL_CONTEXT (decl) = current_function_decl;
@@ -518,11 +525,12 @@ gnat_pushdecl (tree decl, Node_Id gnat_n
 	DECL_STATIC_CHAIN (decl) = 1;
     }
 
-  TREE_NO_WARNING (decl) = (gnat_node == Empty || Warnings_Off (gnat_node));
+  TREE_NO_WARNING (decl) = (No (gnat_node) || Warnings_Off (gnat_node));
 
   /* Set the location of DECL and emit a declaration for it.  */
   if (Present (gnat_node))
     Sloc_to_locus (Sloc (gnat_node), &DECL_SOURCE_LOCATION (decl));
+
   add_decl_expr (decl, gnat_node);
 
   /* Put the declaration on the list.  The list of declarations is in reverse
@@ -1982,7 +1990,7 @@ end_subprog_body (tree body)
 
   DECL_SAVED_TREE (fndecl) = body;
 
-  current_function_decl = DECL_CONTEXT (fndecl);
+  current_function_decl = decl_function_context (fndecl);
 
   /* We cannot track the location of errors past this point.  */
   error_gnat_node = Empty;
@@ -1995,7 +2003,7 @@ end_subprog_body (tree body)
   dump_function (TDI_original, fndecl);
 
   /* ??? This special handling of nested functions is probably obsolete.  */
-  if (!DECL_CONTEXT (fndecl))
+  if (!decl_function_context (fndecl))
     cgraph_finalize_function (fndecl, false);
   else
     /* Register this function with cgraph just far enough to get it
Index: ada/gcc-interface/gigi.h
===================================================================
--- ada/gcc-interface/gigi.h	(revision 179488)
+++ ada/gcc-interface/gigi.h	(working copy)
@@ -450,8 +450,8 @@ extern void set_block_jmpbuf_decl (tree
 /* Get the setjmp_decl, if any, for the current binding level.  */
 extern tree get_block_jmpbuf_decl (void);
 
-/* Records a ..._DECL node DECL as belonging to the current lexical scope
-   and uses GNAT_NODE for location information.  */
+/* Record DECL as belonging to the current lexical scope and use GNAT_NODE
+   for location information and flag propagation.  */
 extern void gnat_pushdecl (tree decl, Node_Id gnat_node);
 
 extern void gnat_init_gcc_eh (void);
Index: gimple.c
===================================================================
--- gimple.c	(revision 179488)
+++ gimple.c	(working copy)
@@ -3182,9 +3182,7 @@ canonicalize_cond_expr_cond (tree t)
 {
   /* Strip conversions around boolean operations.  */
   if (CONVERT_EXPR_P (t)
-      && (truth_value_p (TREE_CODE (TREE_OPERAND (t, 0)))
-          || TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
-	     == BOOLEAN_TYPE))
+      && truth_value_p (TREE_CODE (TREE_OPERAND (t, 0))))
     t = TREE_OPERAND (t, 0);
 
   /* For !x use x == 0.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]