diff mbox

Fix ICE with asm "m" (stmt-expr) operand (PR middle-end/67653)

Message ID 20160120135152.GW3017@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Jan. 20, 2016, 1:51 p.m. UTC
On Wed, Jan 20, 2016 at 10:41:47AM +0100, Richard Biener wrote:
> > We already do diagnose tons of other cases for inline asm at
> > gimplification time.  I can replace the error with a warning followed by
> > copying it to addressable memory, that seems to be what the older gccs were
> > doing during expansion after issuing above mentioned warning.
> 
> That sounds better then though it would be nice to warn from the FE
> somehow.

Like this?  I'm afraid I don't know how to find out if it is a case we can
or can't handle better at the FE side.

2016-01-20  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/67653
	* gimplify.c (gimplify_asm_expr): Warn if it is too late to
	attempt to mark memory input operand addressable and
	call prepare_gimple_addressable in that case.  Don't adjust
	input_location for diagnostics, use error_at instead.

	* c-c++-common/pr67653.c: New test.
	* gcc.dg/torture/pr29119.c: Add dg-warning.



	Jakub

Comments

Marek Polacek Jan. 20, 2016, 1:59 p.m. UTC | #1
On Wed, Jan 20, 2016 at 02:51:52PM +0100, Jakub Jelinek wrote:
> On Wed, Jan 20, 2016 at 10:41:47AM +0100, Richard Biener wrote:
> > > We already do diagnose tons of other cases for inline asm at
> > > gimplification time.  I can replace the error with a warning followed by
> > > copying it to addressable memory, that seems to be what the older gccs were
> > > doing during expansion after issuing above mentioned warning.
> > 
> > That sounds better then though it would be nice to warn from the FE
> > somehow.
> 
> Like this?  I'm afraid I don't know how to find out if it is a case we can
> or can't handle better at the FE side.
> 
> 2016-01-20  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/67653
> 	* gimplify.c (gimplify_asm_expr): Warn if it is too late to
> 	attempt to mark memory input operand addressable and
> 	call prepare_gimple_addressable in that case.  Don't adjust
> 	input_location for diagnostics, use error_at instead.
> 
> 	* c-c++-common/pr67653.c: New test.
> 	* gcc.dg/torture/pr29119.c: Add dg-warning.
> 
> --- gcc/gimplify.c.jj	2016-01-19 09:20:22.467792253 +0100
> +++ gcc/gimplify.c	2016-01-20 14:44:17.571333221 +0100
> @@ -5305,12 +5305,41 @@ gimplify_asm_expr (tree *expr_p, gimple_
>  	    TREE_VALUE (link) = error_mark_node;
>  	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
>  				is_gimple_lvalue, fb_lvalue | fb_mayfail);
> +	  if (tret != GS_ERROR)
> +	    {
> +	      /* Unlike output operands, memory inputs are not guaranteed
> +		 to be lvalues by the FE, and while the expressions are
> +		 marked addressable there, if it is e.g. a statement
> +		 expression, temporaries in it might not end up being
> +		 addressable.  They might be already used in the IL and thus
> +		 it is too late to make them addressable now though.  */
> +	      tree x = TREE_VALUE (link);
> +	      while (handled_component_p (x))
> +		x = TREE_OPERAND (x, 0);
> +	      if (TREE_CODE (x) == MEM_REF
> +		  && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
> +		x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
> +	      if ((TREE_CODE (x) == VAR_DECL
> +		   || TREE_CODE (x) == PARM_DECL
> +		   || TREE_CODE (x) == RESULT_DECL)
> +		  && !TREE_ADDRESSABLE (x)
> +		  && is_gimple_reg (x))
> +		{
> +		  warning_at (EXPR_HAS_LOCATION (TREE_VALUE (link))
> +			      ? EXPR_HAS_LOCATION (TREE_VALUE (link))
> +			      : input_location, 0,

This looks wrong, I think you meant EXPR_HAS_LOCATION ? EXPR_LOCATION : ...
Or use EXPR_LOC_OR_LOC.

> +			      "memory input %d is not directly addressable",
> +			      i);
> +		  prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
> +		}
> +	    }
>  	  mark_addressable (TREE_VALUE (link));
>  	  if (tret == GS_ERROR)
>  	    {
> -	      if (EXPR_HAS_LOCATION (TREE_VALUE (link)))
> -	        input_location = EXPR_LOCATION (TREE_VALUE (link));
> -	      error ("memory input %d is not directly addressable", i);
> +	      error_at (EXPR_HAS_LOCATION (TREE_VALUE (link))
> +			? EXPR_HAS_LOCATION (TREE_VALUE (link))
> +			: input_location,

Here as well.

	Marek
Andreas Schwab Jan. 20, 2016, 2:14 p.m. UTC | #2
Jakub Jelinek <jakub@redhat.com> writes:

> +			      "memory input %d is not directly addressable",

What does that mean?

Andreas.
Richard Biener Jan. 20, 2016, 2:17 p.m. UTC | #3
On Wed, 20 Jan 2016, Andreas Schwab wrote:

> Jakub Jelinek <jakub@redhat.com> writes:
> 
> > +			      "memory input %d is not directly addressable",
> 
> What does that mean?

Is "input %d is not addressable" better?

Otherwise the patch looks ok.

Richard.
Jakub Jelinek Jan. 20, 2016, 2:22 p.m. UTC | #4
On Wed, Jan 20, 2016 at 03:14:04PM +0100, Andreas Schwab wrote:
> Jakub Jelinek <jakub@redhat.com> writes:
> 
> > +			      "memory input %d is not directly addressable",
> 
> What does that mean?

That is preexisting diagnostic wording, just for the cases that can be handled by
preloading the var into a temporary there is just a warning while for other
cases it is an error.

	Jakub
Andreas Schwab Jan. 20, 2016, 4:07 p.m. UTC | #5
Richard Biener <rguenther@suse.de> writes:

> On Wed, 20 Jan 2016, Andreas Schwab wrote:
>
>> Jakub Jelinek <jakub@redhat.com> writes:
>> 
>> > +			      "memory input %d is not directly addressable",
>> 
>> What does that mean?
>
> Is "input %d is not addressable" better?

If that's the same what the standard calls "addressable storage", then
it's ok.

Andreas.
diff mbox

Patch

--- gcc/gimplify.c.jj	2016-01-19 09:20:22.467792253 +0100
+++ gcc/gimplify.c	2016-01-20 14:44:17.571333221 +0100
@@ -5305,12 +5305,41 @@  gimplify_asm_expr (tree *expr_p, gimple_
 	    TREE_VALUE (link) = error_mark_node;
 	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
 				is_gimple_lvalue, fb_lvalue | fb_mayfail);
+	  if (tret != GS_ERROR)
+	    {
+	      /* Unlike output operands, memory inputs are not guaranteed
+		 to be lvalues by the FE, and while the expressions are
+		 marked addressable there, if it is e.g. a statement
+		 expression, temporaries in it might not end up being
+		 addressable.  They might be already used in the IL and thus
+		 it is too late to make them addressable now though.  */
+	      tree x = TREE_VALUE (link);
+	      while (handled_component_p (x))
+		x = TREE_OPERAND (x, 0);
+	      if (TREE_CODE (x) == MEM_REF
+		  && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
+		x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
+	      if ((TREE_CODE (x) == VAR_DECL
+		   || TREE_CODE (x) == PARM_DECL
+		   || TREE_CODE (x) == RESULT_DECL)
+		  && !TREE_ADDRESSABLE (x)
+		  && is_gimple_reg (x))
+		{
+		  warning_at (EXPR_HAS_LOCATION (TREE_VALUE (link))
+			      ? EXPR_HAS_LOCATION (TREE_VALUE (link))
+			      : input_location, 0,
+			      "memory input %d is not directly addressable",
+			      i);
+		  prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
+		}
+	    }
 	  mark_addressable (TREE_VALUE (link));
 	  if (tret == GS_ERROR)
 	    {
-	      if (EXPR_HAS_LOCATION (TREE_VALUE (link)))
-	        input_location = EXPR_LOCATION (TREE_VALUE (link));
-	      error ("memory input %d is not directly addressable", i);
+	      error_at (EXPR_HAS_LOCATION (TREE_VALUE (link))
+			? EXPR_HAS_LOCATION (TREE_VALUE (link))
+			: input_location,
+			"memory input %d is not directly addressable", i);
 	      ret = tret;
 	    }
 	}
--- gcc/testsuite/c-c++-common/pr67653.c.jj	2016-01-20 14:38:46.842942355 +0100
+++ gcc/testsuite/c-c++-common/pr67653.c	2016-01-20 14:47:05.715989904 +0100
@@ -0,0 +1,8 @@ 
+/* PR middle-end/67653 */
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  __asm__ ("" : : "m" (({ static int a; a; })));	/* { dg-warning "memory input 0 is not directly addressable" } */
+}
--- gcc/testsuite/gcc.dg/torture/pr29119.c.jj	2008-09-05 12:54:28.000000000 +0200
+++ gcc/testsuite/gcc.dg/torture/pr29119.c	2016-01-20 14:47:14.867862361 +0100
@@ -2,6 +2,5 @@ 
 
 void ldt_add_entry(void)
 {
-   __asm__ ("" :: "m"(({unsigned __v; __v;})));
+   __asm__ ("" :: "m"(({unsigned __v; __v;})));	/* { dg-warning "memory input 0 is not directly addressable" } */
 }
-