gimplify.c (gimplify_modify_expr_rhs): Use simple test on the size.
* gimplify.c (gimplify_modify_expr_rhs): Use simple test on the size. * cgraph.c (cgraph_redirect_edge_call_stmt_to_callee): Do not remove the LHS of a no-return call if its type has variable size. * tree-cfgcleanup.c (fixup_noreturn_call): Likewise. * tree-cfg.c (verify_gimple_call): Accept these no-return calls. From-SVN: r223997
This commit is contained in:
parent
418dd5cefe
commit
e6a54b0185
@ -1,3 +1,11 @@
|
||||
2015-06-01 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gimplify.c (gimplify_modify_expr_rhs): Use simple test on the size.
|
||||
* cgraph.c (cgraph_redirect_edge_call_stmt_to_callee): Do not remove
|
||||
the LHS of a no-return call if its type has variable size.
|
||||
* tree-cfgcleanup.c (fixup_noreturn_call): Likewise.
|
||||
* tree-cfg.c (verify_gimple_call): Accept these no-return calls.
|
||||
|
||||
2015-06-01 Andreas Tobler <andreast@gcc.gnu.org>
|
||||
|
||||
* read-rtl.c: Adapt to use HAVE_DECL_ATOLL instead of HAVE_ATOLL.
|
||||
|
@ -1464,8 +1464,10 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
|
||||
update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
|
||||
}
|
||||
|
||||
/* If the call becomes noreturn, remove the lhs. */
|
||||
if (lhs && (gimple_call_flags (new_stmt) & ECF_NORETURN))
|
||||
/* If the call becomes noreturn, remove the LHS if possible. */
|
||||
if (lhs
|
||||
&& (gimple_call_flags (new_stmt) & ECF_NORETURN)
|
||||
&& TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
|
||||
{
|
||||
if (TREE_CODE (lhs) == SSA_NAME)
|
||||
{
|
||||
|
@ -4341,7 +4341,8 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
|
||||
/* It's OK to use the target directly if it's being
|
||||
initialized. */
|
||||
use_target = true;
|
||||
else if (variably_modified_type_p (TREE_TYPE (*to_p), NULL_TREE))
|
||||
else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
|
||||
!= INTEGER_CST)
|
||||
/* Always use the target and thus RSO for variable-sized types.
|
||||
GIMPLE cannot deal with a variable-sized assignment
|
||||
embedded in a call statement. */
|
||||
|
@ -1,3 +1,8 @@
|
||||
2015-06-01 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gnat.dg/specs/varsize_return2.ads: New test.
|
||||
* gnat.dg/specs/varsize_return2_pkg.ad[sb]: New helper.
|
||||
|
||||
2015-06-01 Yuri Rumyantsev <ysrumyan@gmail.com>
|
||||
|
||||
* gcc.dg/vect/vect-outer-simd-1.c: New test.
|
||||
|
12
gcc/testsuite/gnat.dg/specs/varsize_return2.ads
Normal file
12
gcc/testsuite/gnat.dg/specs/varsize_return2.ads
Normal file
@ -0,0 +1,12 @@
|
||||
-- { dg-do compile }
|
||||
-- { dg-options "-O" }
|
||||
|
||||
with Varsize_Return2_Pkg; use Varsize_Return2_Pkg;
|
||||
|
||||
package Varsize_Return2 is
|
||||
|
||||
package My_G is new G (0);
|
||||
|
||||
Result : constant T := My_G.Get;
|
||||
|
||||
end Varsize_Return2;
|
18
gcc/testsuite/gnat.dg/specs/varsize_return2_pkg.adb
Normal file
18
gcc/testsuite/gnat.dg/specs/varsize_return2_pkg.adb
Normal file
@ -0,0 +1,18 @@
|
||||
package body Varsize_Return2_Pkg is
|
||||
|
||||
function Len return Positive is
|
||||
begin
|
||||
return 4;
|
||||
end;
|
||||
|
||||
package body G is
|
||||
|
||||
function Get return Small_T is
|
||||
begin
|
||||
raise Program_Error;
|
||||
return Get;
|
||||
end;
|
||||
|
||||
end G;
|
||||
|
||||
end Varsize_Return2_Pkg;
|
20
gcc/testsuite/gnat.dg/specs/varsize_return2_pkg.ads
Normal file
20
gcc/testsuite/gnat.dg/specs/varsize_return2_pkg.ads
Normal file
@ -0,0 +1,20 @@
|
||||
-- { dg-excess-errors "no code generated" }
|
||||
|
||||
package Varsize_Return2_Pkg is
|
||||
|
||||
type T (D: Positive) is record
|
||||
Data: String (1 .. D);
|
||||
end record;
|
||||
|
||||
function Len return Positive;
|
||||
|
||||
generic
|
||||
I : Integer;
|
||||
package G is
|
||||
|
||||
subtype Small_T is T(Len);
|
||||
function Get return Small_T;
|
||||
|
||||
end G;
|
||||
|
||||
end Varsize_Return2_Pkg;
|
@ -3391,17 +3391,19 @@ verify_gimple_call (gcall *stmt)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gimple_call_lhs (stmt)
|
||||
&& (!is_gimple_lvalue (gimple_call_lhs (stmt))
|
||||
|| verify_types_in_gimple_reference (gimple_call_lhs (stmt), true)))
|
||||
tree lhs = gimple_call_lhs (stmt);
|
||||
if (lhs
|
||||
&& (!is_gimple_lvalue (lhs)
|
||||
|| verify_types_in_gimple_reference (lhs, true)))
|
||||
{
|
||||
error ("invalid LHS in gimple call");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gimple_call_ctrl_altering_p (stmt)
|
||||
&& gimple_call_lhs (stmt)
|
||||
&& gimple_call_noreturn_p (stmt))
|
||||
if (lhs
|
||||
&& gimple_call_ctrl_altering_p (stmt)
|
||||
&& gimple_call_noreturn_p (stmt)
|
||||
&& TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
|
||||
{
|
||||
error ("LHS in noreturn call");
|
||||
return true;
|
||||
@ -3409,19 +3411,18 @@ verify_gimple_call (gcall *stmt)
|
||||
|
||||
fntype = gimple_call_fntype (stmt);
|
||||
if (fntype
|
||||
&& gimple_call_lhs (stmt)
|
||||
&& !useless_type_conversion_p (TREE_TYPE (gimple_call_lhs (stmt)),
|
||||
TREE_TYPE (fntype))
|
||||
&& lhs
|
||||
&& !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (fntype))
|
||||
/* ??? At least C++ misses conversions at assignments from
|
||||
void * call results.
|
||||
??? Java is completely off. Especially with functions
|
||||
returning java.lang.Object.
|
||||
For now simply allow arbitrary pointer type conversions. */
|
||||
&& !(POINTER_TYPE_P (TREE_TYPE (gimple_call_lhs (stmt)))
|
||||
&& !(POINTER_TYPE_P (TREE_TYPE (lhs))
|
||||
&& POINTER_TYPE_P (TREE_TYPE (fntype))))
|
||||
{
|
||||
error ("invalid conversion in gimple call");
|
||||
debug_generic_stmt (TREE_TYPE (gimple_call_lhs (stmt)));
|
||||
debug_generic_stmt (TREE_TYPE (lhs));
|
||||
debug_generic_stmt (TREE_TYPE (fntype));
|
||||
return true;
|
||||
}
|
||||
|
@ -612,9 +612,11 @@ fixup_noreturn_call (gimple stmt)
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is an LHS, remove it. */
|
||||
/* If there is an LHS, remove it, but only if its type has fixed size.
|
||||
The LHS will need to be recreated during RTL expansion and creating
|
||||
temporaries of variable-sized types is not supported. */
|
||||
tree lhs = gimple_call_lhs (stmt);
|
||||
if (lhs)
|
||||
if (lhs && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
|
||||
{
|
||||
gimple_call_set_lhs (stmt, NULL_TREE);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user