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]

Fix thinko in GIMPLE inliner


I've attached a testcase that, when compiled with our 4.5-based compiler at -O 
or above, runs into a thinko in the GIMPLE inliner.  However, because of new 
code on the mainline (mem-ref branch) and too ancient code in gigi on the 4.5 
branch, it doesn't run into this thinko with FSF compilers.  But the issue is 
latent in them too.

tree-inline.c:copy_bb reads:

      seq_gsi = copy_gsi;

      /* With return slot optimization we can end up with
	 non-gimple (foo *)&this->m, fix that here.  */
      if (is_gimple_assign (stmt)
	  && gimple_assign_rhs_code (stmt) == NOP_EXPR
	  && !is_gimple_val (gimple_assign_rhs1 (stmt)))
	{
	  tree new_rhs;
	  new_rhs = force_gimple_operand_gsi (&seq_gsi,
					      gimple_assign_rhs1 (stmt),
					      true, NULL, false, GSI_NEW_STMT);
	  gimple_assign_set_rhs1 (stmt, new_rhs);
	  id->regimplify = false;
	}

      gsi_insert_after (&seq_gsi, stmt, GSI_NEW_STMT);


The problem is the first GSI_NEW_STMT because:

  GSI_NEW_STMT,		/* Only valid when single statement is added, move
			   iterator to it.  */

so if force_gimple_operand_gsi happens to create more than one statement (this 
will occur when the LHS of the return statement is a VIEW_CONVERT_EXPR), the 
seq_gsi iterator will be moved to the first statement.  As a consequence, the 
modified STMT will be inserted between the first and the second newly created 
statements, wreaking havoc in the SSA form.

Fixed by using GSI_CONTINUE_LINKING instead of GSI_NEW_STMT.  Bootstrapped and 
regtested on x86_64-suse-linux, applied on mainline and 4.5 branch as obvious.


2010-09-25  Eric Botcazou  <ebotcazou@adacore.com>

	* tree-inline.c (copy_bb): Use GSI_CONTINUE_LINKING when inserting new
	statements because of the return slot optimization.


2010-09-25  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/return2.ad[sb]: New test.
	* gnat.dg/return2_pkg.ads: New helper.



-- 
Eric Botcazou
Index: tree-inline.c
===================================================================
--- tree-inline.c	(revision 164617)
+++ tree-inline.c	(working copy)
@@ -1558,7 +1558,8 @@ copy_bb (copy_body_data *id, basic_block
 	  tree new_rhs;
 	  new_rhs = force_gimple_operand_gsi (&seq_gsi,
 					      gimple_assign_rhs1 (stmt),
-					      true, NULL, false, GSI_NEW_STMT);
+					      true, NULL, false,
+					      GSI_CONTINUE_LINKING);
 	  gimple_assign_set_rhs1 (stmt, new_rhs);
 	  id->regimplify = false;
 	}
-- { dg-do compile }
-- { dg-options "-O" }

with Return2_Pkg; use Return2_Pkg;

package body Return2 is

  function Value_Internal (Image : String) return Result_Internal_T is
  begin
    return (Member => False);
  end;

  type Result_T is array (1 .. 2) of Result_Internal_T;

  function Value (Img : String) return T is
    My_F : constant String := F;
    Result : Result_T;
    Value : T;
  begin
    for I in Result'Range loop
      if G (My_F, I) /= "" then
        Result (I) := Value_Internal (G (My_F, I));
        if Result (I).Member then
          Value (Result (I).Data) := True;
        else
          raise Program_Error;
        end if;
      end if;
    end loop;
    return Value;
  end;

end Return2;
package Return2 is

  type Kind_T is (One, Two);

  type T is array (Kind_T) of Boolean;

  type Result_Internal_T (Member : Boolean := False) is record
    case Member is
      when True =>
        Data : Kind_T := Kind_T'First;
      when False =>
        null;
    end case;
  end record;

  function Value (Img : String) return T;

end Return2;
package Return2_Pkg is

  function F return String;

  function G (Line : String; Index : Positive) return String;

end Return2_Pkg;

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