public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
@ 2019-02-11 19:20 Martin Sebor
  2019-02-11 19:34 ` Jakub Jelinek
                   ` (2 more replies)
  0 siblings, 3 replies; 33+ messages in thread
From: Martin Sebor @ 2019-02-11 19:20 UTC (permalink / raw)
  To: gcc-patches, Jeff Law, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 514 bytes --]

This is a repost of a patch for PR 88383 updated to also fix the just
reported PR 89288 (the original patch only partially handles this case).
The review of the first patch was derailed by questions about the design
of the built-in so the fix for the ICE was never approved.  I think
the ICEs should be fixed for GCC 9 and any open design questions should
be dealt with independently.

Martin

The patch for PR 88383 was originally posted last December:
   https://gcc.gnu.org/ml/gcc-patches/2018-12/msg00337.html

[-- Attachment #2: gcc-88383.diff --]
[-- Type: text/x-patch, Size: 8081 bytes --]

PR c/88383 - ICE calling __builtin_has_attribute on a reference
PR c/89288 - ICE in tree_code_size, at tree.c:865

gcc/c-family/ChangeLog:

	PR c/88383
	PR c/89288
	* c-attribs.c (validate_attribute): Handle expressions.
	(has_attribute): Handle types referenced by expressions.
	Avoid considering array attributes in ARRAY_REF expressions .

gcc/cp/ChangeLog:

	PR c/88383
	PR c/89288
	* parser.c (cp_parser_has_attribute_expression): Handle assignment
	expressions.

gcc/testsuite/ChangeLog:

	PR c/88383
	PR c/89288
	* c-c++-common/builtin-has-attribute-4.c: Adjust expectations.
	* c-c++-common/builtin-has-attribute-6.c: New test.

Index: gcc/c-family/c-attribs.c
===================================================================
--- gcc/c-family/c-attribs.c	(revision 268774)
+++ gcc/c-family/c-attribs.c	(working copy)
@@ -4032,8 +4032,12 @@ validate_attribute (location_t atloc, tree oper, t
 
   if (TYPE_P (oper))
     tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, oper);
+  else if (DECL_P (oper))
+    tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
+  else if (EXPR_P (oper))
+    tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, TREE_TYPE (oper));
   else
-    tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
+    return false;
 
   /* Temporarily clear CURRENT_FUNCTION_DECL to make decl_attributes
      believe the DECL declared above is at file scope.  (See bug 87526.)  */
@@ -4042,7 +4046,7 @@ validate_attribute (location_t atloc, tree oper, t
   if (DECL_P (tmpdecl))
     {
       if (DECL_P (oper))
-	/* An alias cannot be a defintion so declare the symbol extern.  */
+	/* An alias cannot be a definition so declare the symbol extern.  */
 	DECL_EXTERNAL (tmpdecl) = true;
       /* Attribute visibility only applies to symbols visible from other
 	 translation units so make it "public."   */
@@ -4078,11 +4082,17 @@ has_attribute (location_t atloc, tree t, tree attr
       do
 	{
 	  /* Determine the array element/member declaration from
-	     an ARRAY/COMPONENT_REF.  */
+	     a COMPONENT_REF and an INDIRECT_REF involving a refeence.  */
 	  STRIP_NOPS (t);
 	  tree_code code = TREE_CODE (t);
-	  if (code == ARRAY_REF)
-	    t = TREE_OPERAND (t, 0);
+	  if (code == INDIRECT_REF)
+	    {
+	      tree op0 = TREE_OPERAND (t, 0);
+	      if (TREE_CODE (TREE_TYPE (op0)) == REFERENCE_TYPE)
+		t = op0;
+	      else
+		break;
+	    }
 	  else if (code == COMPONENT_REF)
 	    t = TREE_OPERAND (t, 1);
 	  else
@@ -4133,7 +4143,8 @@ has_attribute (location_t atloc, tree t, tree attr
 	}
       else
 	{
-	  atlist = TYPE_ATTRIBUTES (TREE_TYPE (expr));
+	  type = TREE_TYPE (expr);
+	  atlist = TYPE_ATTRIBUTES (type);
 	  done = true;
 	}
 
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 268774)
+++ gcc/cp/parser.c	(working copy)
@@ -8542,9 +8542,9 @@ cp_parser_has_attribute_expression (cp_parser *par
   cp_parser_parse_definitely (parser);
 
   /* If the type-id production did not work out, then we must be
-     looking at the unary-expression production.  */
+     looking at an expression.  */
   if (!oper || oper == error_mark_node)
-    oper = cp_parser_unary_expression (parser);
+    oper = cp_parser_assignment_expression (parser);
 
   STRIP_ANY_LOCATION_WRAPPER (oper);
 
Index: gcc/testsuite/c-c++-common/builtin-has-attribute-4.c
===================================================================
--- gcc/testsuite/c-c++-common/builtin-has-attribute-4.c	(revision 268774)
+++ gcc/testsuite/c-c++-common/builtin-has-attribute-4.c	(working copy)
@@ -154,7 +154,8 @@ void test_packed (struct PackedMember *p)
   A (0, gpak[0].c, packed);
   A (0, gpak[1].s, packed);
   A (1, gpak->a, packed);
-  A (1, (*gpak).a[0], packed);
+  /* It's the array that's declared packed but not its elements.  */
+  A (0, (*gpak).a[0], packed);
 
   /* The following fails because in C it's represented as
        INDIRECT_REF (POINTER_PLUS (NOP_EXPR (ADDR_EXPR (gpak)), ...))
@@ -164,7 +165,8 @@ void test_packed (struct PackedMember *p)
   A (0, p->c, packed);
   A (0, p->s, packed);
   A (1, p->a, packed);
-  A (1, p->a[0], packed);
+  /* It's the array that's declared packed but not its elements.  */
+  A (0, p->a[0], packed);
   /* Similar to the comment above.
    A (1, *p->a, packed);  */
 }
Index: gcc/testsuite/c-c++-common/builtin-has-attribute-6.c
===================================================================
--- gcc/testsuite/c-c++-common/builtin-has-attribute-6.c	(nonexistent)
+++ gcc/testsuite/c-c++-common/builtin-has-attribute-6.c	(working copy)
@@ -0,0 +1,114 @@
+/* PR c/88383 - ICE calling _builtin_has_attribute(r, aligned(N)))
+   on an overaligned reference r
+   PR c/89288 - ICE in tree_code_size, at tree.c:865
+   { dg-options "-Wall -ftrack-macro-expansion=0" }
+   { dg-options "-Wall -Wno-narrowing -Wno-unused -ftrack-macro-expansion=0" { target c++ } }  */
+
+#define ATTR(...) __attribute__ ((__VA_ARGS__))
+
+#define A(expect, sym, attr)						\
+  typedef int Assert [1 - 2 * !(__builtin_has_attribute (sym, attr) == expect)]
+
+typedef ATTR (aligned (8)) int Int8;
+
+/* The attribute applies to the array, not to the type of its elements.  */
+extern ATTR (aligned (8)) char i8arr[];
+
+/* The attribute applies to the pointer, not to the type it points to.  */
+extern ATTR (aligned (8)) int *ptr;
+extern Int8 *i8ptr;
+
+#if __cplusplus
+
+/* Similarly here, the attribute applies to the reference, not to its type.  */
+extern ATTR (aligned (8)) int &ref;
+extern Int8 &i8ref;
+
+#else
+
+/* Fake references in C.  */
+extern ATTR (aligned (8)) int ref;
+Int8 i8ref;
+
+#endif
+
+void test (void)
+{
+  /* Verify that the built-in detects the attribute on the array. */
+  A (1, i8arr, aligned);
+  A (0, i8arr, aligned (1));
+  A (0, i8arr, aligned (2));
+  A (0, i8arr, aligned (4));
+  A (1, i8arr, aligned (8));
+  A (0, i8arr, aligned (16));
+
+  A (0, i8arr + 1, aligned);
+  A (0, i8arr + 2, aligned (1));
+  A (0, i8arr + 3, aligned (8));
+
+  /* Verify the builtin detects the absence of the attribute on
+     the elements.  */
+  A (0, i8arr[0], aligned);
+  A (0, *i8arr,   aligned);
+
+  /* Verify that the built-in doesn't confuse the attribute on
+     the pointer type with that to the pointed to type.  This
+     also exercises PR c/89288.  */
+  A (0, (Int8*)0, aligned);
+  A (0, (int*)0,  aligned);
+  A (0, (void*)0, aligned);
+  A (0, 0,        aligned);
+
+  /* Verify that the built-in detects the attribute on the pointer
+     itself. */
+  A (1, ptr, aligned);
+  A (0, ptr, aligned (1));
+  A (0, ptr, aligned (2));
+  A (0, ptr, aligned (4));
+  A (1, ptr, aligned (8));
+  A (0, ptr, aligned (16));
+
+  A (0, ptr + 1, aligned);
+  A (0, ptr + 2, aligned (1));
+  A (0, ptr + 3, aligned (8));
+
+  /* The pointed to type is not declared with attribute aligned.  */
+  A (0, *ptr, aligned);
+  A (0, *ptr, aligned (1));
+  A (0, *ptr, aligned (2));
+  A (0, *ptr, aligned (4));
+  A (0, *ptr, aligned (8));
+  A (0, *ptr, aligned (16));
+
+  A (0, *ptr + 1, aligned);
+  A (0, *ptr + 2, aligned (1));
+  A (0, *ptr + 3, aligned (8));
+
+  /* Verify that the built-in correctly detects the attribute on
+     the type of the lvalue referenced by the pointer. */
+  A (0, i8ptr,     aligned);
+  A (0, i8ptr,     aligned (8));
+  A (0, i8ptr + 1, aligned);
+  A (0, i8ptr + 3, aligned (8));
+  A (1, *i8ptr,    aligned);
+  A (0, *i8ptr,    aligned (1));
+  A (0, *i8ptr,    aligned (2));
+  A (0, *i8ptr,    aligned (4));
+  A (1, *i8ptr,    aligned (8));
+  A (0, *i8ptr,    aligned (16));
+
+  /* The reference itself is declared aligned, even though the type
+     it refers to isn't.  But see PR c++/88362.  */
+  A (1, ref, aligned);
+  A (0, ref, aligned (1));
+  A (0, ref, aligned (2));
+  A (0, ref, aligned (4));
+  A (1, ref, aligned (8));
+  A (0, ref, aligned (16));
+
+  /* Also verify that assignment expressions are accepted.  */
+  A (0, ref = 1,  aligned);
+  A (0, ref += 2, aligned (1));
+  A (0, ref /= 3, aligned (8));
+
+}

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-11 19:20 [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288) Martin Sebor
@ 2019-02-11 19:34 ` Jakub Jelinek
  2019-02-11 20:23 ` Jakub Jelinek
  2019-02-19  2:53 ` PING " Martin Sebor
  2 siblings, 0 replies; 33+ messages in thread
From: Jakub Jelinek @ 2019-02-11 19:34 UTC (permalink / raw)
  To: Martin Sebor; +Cc: gcc-patches, Jeff Law

On Mon, Feb 11, 2019 at 12:20:42PM -0700, Martin Sebor wrote:
> This is a repost of a patch for PR 88383 updated to also fix the just
> reported PR 89288 (the original patch only partially handles this case).
> The review of the first patch was derailed by questions about the design
> of the built-in so the fix for the ICE was never approved.  I think
> the ICEs should be fixed for GCC 9 and any open design questions should
> be dealt with independently.

Well, it is closely coupled with the design questions.

>    if (TYPE_P (oper))
>      tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, oper);
> +  else if (DECL_P (oper))
> +    tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
> +  else if (EXPR_P (oper))
> +    tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, TREE_TYPE (oper));
>    else
> -    tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
> +    return false;

The EXPR_P conditional makes no sense.  Why should __builtin_has_attribute (1 + 1, ...)
do something (if unfolded yet) and __builtin_has_attribute (2, ...)
something different?  1 + 1 when unfolded is EXPR_P, but 2 is not.

	Jakub

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-11 19:20 [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288) Martin Sebor
  2019-02-11 19:34 ` Jakub Jelinek
@ 2019-02-11 20:23 ` Jakub Jelinek
  2019-02-11 20:59   ` Martin Sebor
  2019-02-19  2:53 ` PING " Martin Sebor
  2 siblings, 1 reply; 33+ messages in thread
From: Jakub Jelinek @ 2019-02-11 20:23 UTC (permalink / raw)
  To: Martin Sebor; +Cc: gcc-patches, Jeff Law

On Mon, Feb 11, 2019 at 12:20:42PM -0700, Martin Sebor wrote:
> --- gcc/c-family/c-attribs.c	(revision 268774)
> +++ gcc/c-family/c-attribs.c	(working copy)
> @@ -4032,8 +4032,12 @@ validate_attribute (location_t atloc, tree oper, t
>  
>    if (TYPE_P (oper))
>      tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, oper);
> +  else if (DECL_P (oper))
> +    tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
> +  else if (EXPR_P (oper))
> +    tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, TREE_TYPE (oper));
>    else
> -    tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
> +    return false;
>  
>    /* Temporarily clear CURRENT_FUNCTION_DECL to make decl_attributes
>       believe the DECL declared above is at file scope.  (See bug 87526.)  */

Why do you this kind of validation at all?  You do compare the arguments
later on in the caller, why isn't that sufficient?  Creating some decl (and
ignoring for that whether the attribute is decl_required, type_required and/or
function_type_required) is a sure way to get many warnings, even if the
arguments are reasonable.

	Jakub

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-11 20:23 ` Jakub Jelinek
@ 2019-02-11 20:59   ` Martin Sebor
  0 siblings, 0 replies; 33+ messages in thread
From: Martin Sebor @ 2019-02-11 20:59 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, Jeff Law

On 2/11/19 1:23 PM, Jakub Jelinek wrote:
> On Mon, Feb 11, 2019 at 12:20:42PM -0700, Martin Sebor wrote:
>> --- gcc/c-family/c-attribs.c	(revision 268774)
>> +++ gcc/c-family/c-attribs.c	(working copy)
>> @@ -4032,8 +4032,12 @@ validate_attribute (location_t atloc, tree oper, t
>>   
>>     if (TYPE_P (oper))
>>       tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, oper);
>> +  else if (DECL_P (oper))
>> +    tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
>> +  else if (EXPR_P (oper))
>> +    tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, TREE_TYPE (oper));
>>     else
>> -    tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
>> +    return false;
>>   
>>     /* Temporarily clear CURRENT_FUNCTION_DECL to make decl_attributes
>>        believe the DECL declared above is at file scope.  (See bug 87526.)  */
> 
> Why do you this kind of validation at all?  You do compare the arguments
> later on in the caller, why isn't that sufficient?  Creating some decl (and
> ignoring for that whether the attribute is decl_required, type_required and/or
> function_type_required) is a sure way to get many warnings, even if the
> arguments are reasonable.
> 

The snippet above deals with validating an attribute with one or
more arguments in the context where it's being queried, to make
sure the whole attribute specification makes any sense at all.
It's meant to catch gross mistakes like

   __builtin_has_attribute (func, alloc_size ("1"));

but it's far from perfect.

The difference in the example you asked about in your other mail
can be seen here:

   const int i = 1;

   enum {
     e = __builtin_has_attribute (1 + 0, alloc_size ("foo")),
     f = __builtin_has_attribute (i + 1, alloc_size ("bar"))
   };

Because the EPPR_P(oper) test fails for the first enumerator
the first invalid attribute specification is not diagnosed.  But
because it succeeds for (i + 1), the second specification triggers
a warning about alloc_size being only applicable to function types.
I suppose this could improved by handling constants the same as
expressions.

But this is far from the only limitation.  Attributes with no
arguments don't even make it this far.  Because the validation
depends on decl_attributes to detect these mistakes and that
function doesn't distinguish success from failure, the validation
succeeds even for non-sensical attributes.  But it should never
cause the built-in to give a false positive.  There are at least
a couple of FIXMEs in the code where I would like to improve
the validation in GCC 10.  But none of them is inherent in
the design of the built-in or serious enough to seriously
compromise its usefulness.

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-11 19:20 [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288) Martin Sebor
  2019-02-11 19:34 ` Jakub Jelinek
  2019-02-11 20:23 ` Jakub Jelinek
@ 2019-02-19  2:53 ` Martin Sebor
  2019-02-21 19:40   ` Jeff Law
  2 siblings, 1 reply; 33+ messages in thread
From: Martin Sebor @ 2019-02-19  2:53 UTC (permalink / raw)
  To: gcc-patches, Jeff Law, Jakub Jelinek

Please let me know what it will take to get the fix for these two
issues approved.  I've answered the questions so I don't know what
else I'm expected to do here.

   https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00793.html

On 2/11/19 12:20 PM, Martin Sebor wrote:
> This is a repost of a patch for PR 88383 updated to also fix the just
> reported PR 89288 (the original patch only partially handles this case).
> The review of the first patch was derailed by questions about the design
> of the built-in so the fix for the ICE was never approved.  I think
> the ICEs should be fixed for GCC 9 and any open design questions should
> be dealt with independently.
> 
> Martin
> 
> The patch for PR 88383 was originally posted last December:
>    https://gcc.gnu.org/ml/gcc-patches/2018-12/msg00337.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-19  2:53 ` PING " Martin Sebor
@ 2019-02-21 19:40   ` Jeff Law
  2019-02-21 20:47     ` Martin Sebor
  0 siblings, 1 reply; 33+ messages in thread
From: Jeff Law @ 2019-02-21 19:40 UTC (permalink / raw)
  To: Martin Sebor, gcc-patches, Jakub Jelinek

On 2/18/19 7:53 PM, Martin Sebor wrote:
> Please let me know what it will take to get the fix for these two
> issues approved.  I've answered the questions so I don't know what
> else I'm expected to do here.
> 
>   https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00793.html
I think there is still a fundamental disagreement about whether or not
this should be handling expressions.  Without an agreement on that it's
hard to see how this could go forward.

jeff

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-21 19:40   ` Jeff Law
@ 2019-02-21 20:47     ` Martin Sebor
  2019-02-21 20:56       ` Jeff Law
  0 siblings, 1 reply; 33+ messages in thread
From: Martin Sebor @ 2019-02-21 20:47 UTC (permalink / raw)
  To: Jeff Law, gcc-patches, Jakub Jelinek

On 2/21/19 12:08 PM, Jeff Law wrote:
> On 2/18/19 7:53 PM, Martin Sebor wrote:
>> Please let me know what it will take to get the fix for these two
>> issues approved.  I've answered the questions so I don't know what
>> else I'm expected to do here.
>>
>>    https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00793.html
> I think there is still a fundamental disagreement about whether or not
> this should be handling expressions.  Without an agreement on that it's
> hard to see how this could go forward.

I think it's wrong to hold up a fix for an ICE because you don't
like the current design.  The built-in successfully handles common
expressions (see c-c++-common/builtin-has-attribute-5.c).  It just
fails for some of the less common ones.  Not fixing those will only
penalize users who run into the ICE, and cast a bad light on
the quality of the release.   Any design questions should be
settled separately of these ICEs (should have been when
the feature was being reviewed).

That said, I have explained the rationale for the current design.
Neither you nor Jakub has explained what you find wrong with it or
why either of your alternatives is preferable.  You said it should
be an error to apply the built-in to expressions (why?).  Jakub
thought there perhaps should be two built-ins, one for expressions
and another for decls.  His rationale?  The current design is not
good.  Clearly,  the two of you don't agree on what you'd like to
see; the only thing you agree on is that you don't like what's
there now.  What do you expect me to do with that, now at the end
of stage 4?

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-21 20:47     ` Martin Sebor
@ 2019-02-21 20:56       ` Jeff Law
  2019-02-21 22:42         ` Martin Sebor
  0 siblings, 1 reply; 33+ messages in thread
From: Jeff Law @ 2019-02-21 20:56 UTC (permalink / raw)
  To: Martin Sebor, gcc-patches, Jakub Jelinek

On 2/21/19 1:12 PM, Martin Sebor wrote:
> On 2/21/19 12:08 PM, Jeff Law wrote:
>> On 2/18/19 7:53 PM, Martin Sebor wrote:
>>> Please let me know what it will take to get the fix for these two
>>> issues approved.  I've answered the questions so I don't know what
>>> else I'm expected to do here.
>>>
>>>    https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00793.html
>> I think there is still a fundamental disagreement about whether or not
>> this should be handling expressions.  Without an agreement on that it's
>> hard to see how this could go forward.
> 
> I think it's wrong to hold up a fix for an ICE because you don't
> like the current design.  The built-in successfully handles common
> expressions (see c-c++-common/builtin-has-attribute-5.c).  It just
> fails for some of the less common ones.  Not fixing those will only
> penalize users who run into the ICE, and cast a bad light on
> the quality of the release.   Any design questions should be
> settled separately of these ICEs (should have been when
> the feature was being reviewed).
> 
> That said, I have explained the rationale for the current design.
> Neither you nor Jakub has explained what you find wrong with it or
> why either of your alternatives is preferable.  You said it should
> be an error to apply the built-in to expressions (why?).  Jakub
> thought there perhaps should be two built-ins, one for expressions
> and another for decls.  His rationale?  The current design is not
> good.  Clearly,  the two of you don't agree on what you'd like to
> see; the only thing you agree on is that you don't like what's
> there now.  What do you expect me to do with that, now at the end
> of stage 4?
Fix the ice in another way.  Handling expressions here seems
fundamentally wrong.  ISTM that making this query on an expression
should result in an immediate error.

jeff

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-21 20:56       ` Jeff Law
@ 2019-02-21 22:42         ` Martin Sebor
  2019-02-21 22:45           ` Jeff Law
  2019-02-22 18:01           ` Marek Polacek
  0 siblings, 2 replies; 33+ messages in thread
From: Martin Sebor @ 2019-02-21 22:42 UTC (permalink / raw)
  To: Jeff Law, gcc-patches, Jakub Jelinek

On 2/21/19 1:27 PM, Jeff Law wrote:
> On 2/21/19 1:12 PM, Martin Sebor wrote:
>> On 2/21/19 12:08 PM, Jeff Law wrote:
>>> On 2/18/19 7:53 PM, Martin Sebor wrote:
>>>> Please let me know what it will take to get the fix for these two
>>>> issues approved.  I've answered the questions so I don't know what
>>>> else I'm expected to do here.
>>>>
>>>>     https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00793.html
>>> I think there is still a fundamental disagreement about whether or not
>>> this should be handling expressions.  Without an agreement on that it's
>>> hard to see how this could go forward.
>>
>> I think it's wrong to hold up a fix for an ICE because you don't
>> like the current design.  The built-in successfully handles common
>> expressions (see c-c++-common/builtin-has-attribute-5.c).  It just
>> fails for some of the less common ones.  Not fixing those will only
>> penalize users who run into the ICE, and cast a bad light on
>> the quality of the release.   Any design questions should be
>> settled separately of these ICEs (should have been when
>> the feature was being reviewed).
>>
>> That said, I have explained the rationale for the current design.
>> Neither you nor Jakub has explained what you find wrong with it or
>> why either of your alternatives is preferable.  You said it should
>> be an error to apply the built-in to expressions (why?).  Jakub
>> thought there perhaps should be two built-ins, one for expressions
>> and another for decls.  His rationale?  The current design is not
>> good.  Clearly,  the two of you don't agree on what you'd like to
>> see; the only thing you agree on is that you don't like what's
>> there now.  What do you expect me to do with that, now at the end
>> of stage 4?
> Fix the ice in another way.  Handling expressions here seems
> fundamentally wrong.  ISTM that making this query on an expression
> should result in an immediate error.

Sorry but "it seems wrong" is not a compelling argument.  You need
to explain what you think is wrong with it.

The built-in is modeled on the sizeof, alignof, and typeof operators.
The manual documents like this:

   bool __builtin_has_attribute (type-or-expression, attribute)

   ...The type-or-expression argument is subject to the same
   restrictions as the argument to typeof (see Typeof).

It was reviewed and approved with no objections to the API.  So it
seems that it's up to you to provide a convincing argument that this
was the wrong choice.  What serious problems do you think it might
cause that justify rejecting expressions, and how will users overcome
this limitation?

I already explained the rationale behind the decision to have
the built-in accept expressions: to be able to easily query for
type attributes in expressions such as:

   typedef __attribute__ ((may_alias)) int* BadInt;

   void f (BadInt *p)
   {
     _Static_assert (__builtin_has_attribute (*p, may_alias));
   }

or

   struct S {
     int a[1] __attribute__ ((packed));
   };

   void f (struct S *p)
   {
     _Static_assert (__builtin_has_attribute (p->a, packed));
   }

or even

     _Static_assert (__builtin_has_attribute (p->a[0], packed));

If the built-in rejects expressions, I don't see how one would
query for these properties.

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-21 22:42         ` Martin Sebor
@ 2019-02-21 22:45           ` Jeff Law
  2019-02-21 23:07             ` Martin Sebor
  2019-02-22 18:01           ` Marek Polacek
  1 sibling, 1 reply; 33+ messages in thread
From: Jeff Law @ 2019-02-21 22:45 UTC (permalink / raw)
  To: Martin Sebor, gcc-patches, Jakub Jelinek

On 2/21/19 3:39 PM, Martin Sebor wrote:
> On 2/21/19 1:27 PM, Jeff Law wrote:
>> On 2/21/19 1:12 PM, Martin Sebor wrote:
>>> On 2/21/19 12:08 PM, Jeff Law wrote:
>>>> On 2/18/19 7:53 PM, Martin Sebor wrote:
>>>>> Please let me know what it will take to get the fix for these two
>>>>> issues approved.  I've answered the questions so I don't know what
>>>>> else I'm expected to do here.
>>>>>
>>>>>     https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00793.html
>>>> I think there is still a fundamental disagreement about whether or not
>>>> this should be handling expressions.  Without an agreement on that it's
>>>> hard to see how this could go forward.
>>>
>>> I think it's wrong to hold up a fix for an ICE because you don't
>>> like the current design.  The built-in successfully handles common
>>> expressions (see c-c++-common/builtin-has-attribute-5.c).  It just
>>> fails for some of the less common ones.  Not fixing those will only
>>> penalize users who run into the ICE, and cast a bad light on
>>> the quality of the release.   Any design questions should be
>>> settled separately of these ICEs (should have been when
>>> the feature was being reviewed).
>>>
>>> That said, I have explained the rationale for the current design.
>>> Neither you nor Jakub has explained what you find wrong with it or
>>> why either of your alternatives is preferable.  You said it should
>>> be an error to apply the built-in to expressions (why?).  Jakub
>>> thought there perhaps should be two built-ins, one for expressions
>>> and another for decls.  His rationale?  The current design is not
>>> good.  Clearly,  the two of you don't agree on what you'd like to
>>> see; the only thing you agree on is that you don't like what's
>>> there now.  What do you expect me to do with that, now at the end
>>> of stage 4?
>> Fix the ice in another way.  Handling expressions here seems
>> fundamentally wrong.  ISTM that making this query on an expression
>> should result in an immediate error.
> 
> Sorry but "it seems wrong" is not a compelling argument.  You need
> to explain what you think is wrong with it.
Attributes on expressions seems fundamentally broken.  Jakub has raised
this issue as well.  If you want things to move forward you need to
address this fundamental issue.

> 
> The built-in is modeled on the sizeof, alignof, and typeof operators.
> The manual documents like this:
Understood, but that makes it rather different from most (all?) other
attributes.  Attributes apply to decls and types, not expressions.

> 
>   bool __builtin_has_attribute (type-or-expression, attribute)
> 
>   ...The type-or-expression argument is subject to the same
>   restrictions as the argument to typeof (see Typeof).
> 
> It was reviewed and approved with no objections to the API. 

ANd I botched that.  Mistakes happen.


Jeff

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-21 22:45           ` Jeff Law
@ 2019-02-21 23:07             ` Martin Sebor
  0 siblings, 0 replies; 33+ messages in thread
From: Martin Sebor @ 2019-02-21 23:07 UTC (permalink / raw)
  To: Jeff Law, gcc-patches, Jakub Jelinek

On 2/21/19 3:42 PM, Jeff Law wrote:
> On 2/21/19 3:39 PM, Martin Sebor wrote:
>> On 2/21/19 1:27 PM, Jeff Law wrote:
>>> On 2/21/19 1:12 PM, Martin Sebor wrote:
>>>> On 2/21/19 12:08 PM, Jeff Law wrote:
>>>>> On 2/18/19 7:53 PM, Martin Sebor wrote:
>>>>>> Please let me know what it will take to get the fix for these two
>>>>>> issues approved.  I've answered the questions so I don't know what
>>>>>> else I'm expected to do here.
>>>>>>
>>>>>>      https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00793.html
>>>>> I think there is still a fundamental disagreement about whether or not
>>>>> this should be handling expressions.  Without an agreement on that it's
>>>>> hard to see how this could go forward.
>>>>
>>>> I think it's wrong to hold up a fix for an ICE because you don't
>>>> like the current design.  The built-in successfully handles common
>>>> expressions (see c-c++-common/builtin-has-attribute-5.c).  It just
>>>> fails for some of the less common ones.  Not fixing those will only
>>>> penalize users who run into the ICE, and cast a bad light on
>>>> the quality of the release.   Any design questions should be
>>>> settled separately of these ICEs (should have been when
>>>> the feature was being reviewed).
>>>>
>>>> That said, I have explained the rationale for the current design.
>>>> Neither you nor Jakub has explained what you find wrong with it or
>>>> why either of your alternatives is preferable.  You said it should
>>>> be an error to apply the built-in to expressions (why?).  Jakub
>>>> thought there perhaps should be two built-ins, one for expressions
>>>> and another for decls.  His rationale?  The current design is not
>>>> good.  Clearly,  the two of you don't agree on what you'd like to
>>>> see; the only thing you agree on is that you don't like what's
>>>> there now.  What do you expect me to do with that, now at the end
>>>> of stage 4?
>>> Fix the ice in another way.  Handling expressions here seems
>>> fundamentally wrong.  ISTM that making this query on an expression
>>> should result in an immediate error.
>>
>> Sorry but "it seems wrong" is not a compelling argument.  You need
>> to explain what you think is wrong with it.
> Attributes on expressions seems fundamentally broken.  Jakub has raised
> this issue as well.  If you want things to move forward you need to
> address this fundamental issue.

I need to understand what this fundamental problem is.

>> The built-in is modeled on the sizeof, alignof, and typeof operators.
>> The manual documents like this:
> Understood, but that makes it rather different from most (all?) other
> attributes.  Attributes apply to decls and types, not expressions.
> 
>>
>>    bool __builtin_has_attribute (type-or-expression, attribute)
>>
>>    ...The type-or-expression argument is subject to the same
>>    restrictions as the argument to typeof (see Typeof).
>>
>> It was reviewed and approved with no objections to the API.
> 
> ANd I botched that.  Mistakes happen.

It was also reviewed by Joseph and Jason.

Can you show how one would query for attribute packed in the example
I gave if the built-in were to reject expressions:

   struct S {
     int a[1] __attribute__ ((packed));
   };

   void f (struct S *p)
   {
     _Static_assert (__builtin_has_attribute (p->a, packed));
   }

In any event, if there is a problem I will certainly fix it.  But
I need to know what the problem is first.

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-21 22:42         ` Martin Sebor
  2019-02-21 22:45           ` Jeff Law
@ 2019-02-22 18:01           ` Marek Polacek
  2019-02-22 19:03             ` Martin Sebor
  2019-03-19 18:37             ` Jeff Law
  1 sibling, 2 replies; 33+ messages in thread
From: Marek Polacek @ 2019-02-22 18:01 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Jeff Law, gcc-patches, Jakub Jelinek

On Thu, Feb 21, 2019 at 03:39:21PM -0700, Martin Sebor wrote:
> On 2/21/19 1:27 PM, Jeff Law wrote:
> > On 2/21/19 1:12 PM, Martin Sebor wrote:
> > > On 2/21/19 12:08 PM, Jeff Law wrote:
> > > > On 2/18/19 7:53 PM, Martin Sebor wrote:
> > > > > Please let me know what it will take to get the fix for these two
> > > > > issues approved.  I've answered the questions so I don't know what
> > > > > else I'm expected to do here.
> > > > > 
> > > > >     https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00793.html
> > > > I think there is still a fundamental disagreement about whether or not
> > > > this should be handling expressions.  Without an agreement on that it's
> > > > hard to see how this could go forward.
> > > 
> > > I think it's wrong to hold up a fix for an ICE because you don't
> > > like the current design.  The built-in successfully handles common
> > > expressions (see c-c++-common/builtin-has-attribute-5.c).  It just
> > > fails for some of the less common ones.  Not fixing those will only
> > > penalize users who run into the ICE, and cast a bad light on
> > > the quality of the release.   Any design questions should be
> > > settled separately of these ICEs (should have been when
> > > the feature was being reviewed).
> > > 
> > > That said, I have explained the rationale for the current design.
> > > Neither you nor Jakub has explained what you find wrong with it or
> > > why either of your alternatives is preferable.  You said it should
> > > be an error to apply the built-in to expressions (why?).  Jakub
> > > thought there perhaps should be two built-ins, one for expressions
> > > and another for decls.  His rationale?  The current design is not
> > > good.  Clearly,  the two of you don't agree on what you'd like to
> > > see; the only thing you agree on is that you don't like what's
> > > there now.  What do you expect me to do with that, now at the end
> > > of stage 4?
> > Fix the ice in another way.  Handling expressions here seems
> > fundamentally wrong.  ISTM that making this query on an expression
> > should result in an immediate error.
> 
> Sorry but "it seems wrong" is not a compelling argument.  You need
> to explain what you think is wrong with it.

"Attributes apply to decls and types, not expressions" seems like an
argument strong enough.  (There are also special attributes for enums
 and ';' and labels.)

> The built-in is modeled on the sizeof, alignof, and typeof operators.
> The manual documents like this:
> 
>   bool __builtin_has_attribute (type-or-expression, attribute)
> 
>   ...The type-or-expression argument is subject to the same
>   restrictions as the argument to typeof (see Typeof).
> 
> It was reviewed and approved with no objections to the API.  So it
> seems that it's up to you to provide a convincing argument that this
> was the wrong choice.  What serious problems do you think it might
> cause that justify rejecting expressions, and how will users overcome
> this limitation?
> 
> I already explained the rationale behind the decision to have
> the built-in accept expressions: to be able to easily query for
> type attributes in expressions such as:
> 
>   typedef __attribute__ ((may_alias)) int* BadInt;
> 
>   void f (BadInt *p)
>   {
>     _Static_assert (__builtin_has_attribute (*p, may_alias));
>   }
> 
> or
> 
>   struct S {
>     int a[1] __attribute__ ((packed));
>   };
> 
>   void f (struct S *p)
>   {
>     _Static_assert (__builtin_has_attribute (p->a, packed));
>   }
> 
> or even
> 
>     _Static_assert (__builtin_has_attribute (p->a[0], packed));
> 
> If the built-in rejects expressions, I don't see how one would
> query for these properties.

So how about __builtin_has_attribute (typeof (p->a), packed)?

Trying to query/set attributes on things like "1 + 1" just doesn't make any
sense.  So why don't we handle TYPE_P/DECL_P and give an error for the rest?

Marek

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-22 18:01           ` Marek Polacek
@ 2019-02-22 19:03             ` Martin Sebor
  2019-03-19 18:37             ` Jeff Law
  1 sibling, 0 replies; 33+ messages in thread
From: Martin Sebor @ 2019-02-22 19:03 UTC (permalink / raw)
  To: Marek Polacek; +Cc: Jeff Law, gcc-patches, Jakub Jelinek

>> I already explained the rationale behind the decision to have
>> the built-in accept expressions: to be able to easily query for
>> type attributes in expressions such as:
>>
>>    typedef __attribute__ ((may_alias)) int* BadInt;
>>
>>    void f (BadInt *p)
>>    {
>>      _Static_assert (__builtin_has_attribute (*p, may_alias));
>>    }
>>
>> or
>>
>>    struct S {
>>      int a[1] __attribute__ ((packed));
>>    };
>>
>>    void f (struct S *p)
>>    {
>>      _Static_assert (__builtin_has_attribute (p->a, packed));
>>    }
>>
>> or even
>>
>>      _Static_assert (__builtin_has_attribute (p->a[0], packed));
>>
>> If the built-in rejects expressions, I don't see how one would
>> query for these properties.
> 
> So how about __builtin_has_attribute (typeof (p->a), packed)?

typeof (p->a) is int, not 'packed int', so the built-in returns
false in this case, while true in the expression I wrote.  This
applies to any attribute that's attached to a member as opposed
to its type.  I know of no way to refer to a struct member in C
without using some non-trivial expression (in C++, S::a could
be used instead).

> Trying to query/set attributes on things like "1 + 1" just doesn't make any
> sense.  So why don't we handle TYPE_P/DECL_P and give an error for the rest?

Mainly because of the above.  But also because there is no harm
in accepting arbitrary expressions and querying their type, no
problem that I'm aware of that would justify giving an error.

This is analogous to __alignof__.  If __alignof__ (1 + 1) makes
enough sense to accept then I see no reason why
__builtin_has_attribute (1 + 1, aligned) should not be.

Martin

PS __alignof__ is documented to determine the alignment requirement
of a function, object, or a type, but it accepts expressions as well.
For lvalues, like p->a above, __alignof__ is further documented to
determine the alignment of the lvalue's type, but that's not what
it actually does, at least not in the sense of
__alignof__ (__typeof__ (p->a)), for over- or underaligned struct
members declared either with attribute aligned or packed.  What
it does is return the alignment of the member subobject, which is,
I'm sure, what most users expect.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-02-22 18:01           ` Marek Polacek
  2019-02-22 19:03             ` Martin Sebor
@ 2019-03-19 18:37             ` Jeff Law
  2019-03-19 22:15               ` Martin Sebor
  2019-03-20  3:14               ` Joseph Myers
  1 sibling, 2 replies; 33+ messages in thread
From: Jeff Law @ 2019-03-19 18:37 UTC (permalink / raw)
  To: Marek Polacek, Martin Sebor; +Cc: gcc-patches, Jakub Jelinek

On 2/22/19 9:42 AM, Marek Polacek wrote:
> On Thu, Feb 21, 2019 at 03:39:21PM -0700, Martin Sebor wrote:
>> On 2/21/19 1:27 PM, Jeff Law wrote:
>>> On 2/21/19 1:12 PM, Martin Sebor wrote:
>>>> On 2/21/19 12:08 PM, Jeff Law wrote:
>>>>> On 2/18/19 7:53 PM, Martin Sebor wrote:
>>>>>> Please let me know what it will take to get the fix for these two
>>>>>> issues approved.  I've answered the questions so I don't know what
>>>>>> else I'm expected to do here.
>>>>>>
>>>>>>     https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00793.html
>>>>> I think there is still a fundamental disagreement about whether or not
>>>>> this should be handling expressions.  Without an agreement on that it's
>>>>> hard to see how this could go forward.
>>>>
>>>> I think it's wrong to hold up a fix for an ICE because you don't
>>>> like the current design.  The built-in successfully handles common
>>>> expressions (see c-c++-common/builtin-has-attribute-5.c).  It just
>>>> fails for some of the less common ones.  Not fixing those will only
>>>> penalize users who run into the ICE, and cast a bad light on
>>>> the quality of the release.   Any design questions should be
>>>> settled separately of these ICEs (should have been when
>>>> the feature was being reviewed).
>>>>
>>>> That said, I have explained the rationale for the current design.
>>>> Neither you nor Jakub has explained what you find wrong with it or
>>>> why either of your alternatives is preferable.  You said it should
>>>> be an error to apply the built-in to expressions (why?).  Jakub
>>>> thought there perhaps should be two built-ins, one for expressions
>>>> and another for decls.  His rationale?  The current design is not
>>>> good.  Clearly,  the two of you don't agree on what you'd like to
>>>> see; the only thing you agree on is that you don't like what's
>>>> there now.  What do you expect me to do with that, now at the end
>>>> of stage 4?
>>> Fix the ice in another way.  Handling expressions here seems
>>> fundamentally wrong.  ISTM that making this query on an expression
>>> should result in an immediate error.
>>
>> Sorry but "it seems wrong" is not a compelling argument.  You need
>> to explain what you think is wrong with it.
> 
> "Attributes apply to decls and types, not expressions" seems like an
> argument strong enough.  (There are also special attributes for enums
>  and ';' and labels.)
So I think Martin's argument is that for an expression we can look at
the type of the expression and see if the attribute is on that type.

That leads to some inconsistencies (that Jakub has pointed out) where an
unfolded expression could produce a different result than it's folded
result if the result was a constant.

AFAICT the goal (outside handling just types) here is to be able to ask
things like is a particular field within a structure packed, aliasing
properties of objects, etc.

My next thought was to use typeof to extract the type of the expression
and pass that through (independent of Marek suggesting the same).
Martin points out in a subsequent email that won't work because p->a in
the supplied example returns an int rather than a packed int.   One
could argue that's the wrong return value for typeof, but I don't think
it's that clear cut.  In this specific instance I'd claim it's wrong,
but I'd hazard a guess we don't have clear semantics in this space.

I'll note that our documentation clearly states that attributes can be
applied to functions, variables, labels, enums, statements and types.
No provision AFAICT is made for expressions.  Users have never had the
ability or assumption that they can ask for attributes on an expression.

Martin's patch essentially allows for asking indirectly -- but I suspect
it's going to be inconsistent in more ways than Jakub pointed out as the
type system in gimple is "loose" in certain ways and the result could
well change as we go through the optimizer pipeline (ie, this is bigger
than just constant folding causing inconsistencies).

Given that we're talking about a new feature with no existing end user
expectations and the fact that attributes are documented as applying
only to things which are decls or types, I'm more inclined to stay
conservative at this point and reject expressions as syntax errors.

We can revisit in gcc-10 and see if there's a reasonable way to tighten
semantics around typeof and/or loosen the requirement that we can only
ask about attributes of DECL/TYPE nodes and define good semantics around
that if we try.  I'm also willing to revisit if other reviewers chime in
with other opinions -- this kind of stuff isn't my strongest area.


Jeff

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-03-19 18:37             ` Jeff Law
@ 2019-03-19 22:15               ` Martin Sebor
  2019-03-20  3:14               ` Joseph Myers
  1 sibling, 0 replies; 33+ messages in thread
From: Martin Sebor @ 2019-03-19 22:15 UTC (permalink / raw)
  To: Jeff Law, Marek Polacek; +Cc: gcc-patches, Jakub Jelinek

On 3/19/19 12:30 PM, Jeff Law wrote:
> On 2/22/19 9:42 AM, Marek Polacek wrote:
>> On Thu, Feb 21, 2019 at 03:39:21PM -0700, Martin Sebor wrote:
>>> On 2/21/19 1:27 PM, Jeff Law wrote:
>>>> On 2/21/19 1:12 PM, Martin Sebor wrote:
>>>>> On 2/21/19 12:08 PM, Jeff Law wrote:
>>>>>> On 2/18/19 7:53 PM, Martin Sebor wrote:
>>>>>>> Please let me know what it will take to get the fix for these two
>>>>>>> issues approved.  I've answered the questions so I don't know what
>>>>>>> else I'm expected to do here.
>>>>>>>
>>>>>>>      https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00793.html
>>>>>> I think there is still a fundamental disagreement about whether or not
>>>>>> this should be handling expressions.  Without an agreement on that it's
>>>>>> hard to see how this could go forward.
>>>>>
>>>>> I think it's wrong to hold up a fix for an ICE because you don't
>>>>> like the current design.  The built-in successfully handles common
>>>>> expressions (see c-c++-common/builtin-has-attribute-5.c).  It just
>>>>> fails for some of the less common ones.  Not fixing those will only
>>>>> penalize users who run into the ICE, and cast a bad light on
>>>>> the quality of the release.   Any design questions should be
>>>>> settled separately of these ICEs (should have been when
>>>>> the feature was being reviewed).
>>>>>
>>>>> That said, I have explained the rationale for the current design.
>>>>> Neither you nor Jakub has explained what you find wrong with it or
>>>>> why either of your alternatives is preferable.  You said it should
>>>>> be an error to apply the built-in to expressions (why?).  Jakub
>>>>> thought there perhaps should be two built-ins, one for expressions
>>>>> and another for decls.  His rationale?  The current design is not
>>>>> good.  Clearly,  the two of you don't agree on what you'd like to
>>>>> see; the only thing you agree on is that you don't like what's
>>>>> there now.  What do you expect me to do with that, now at the end
>>>>> of stage 4?
>>>> Fix the ice in another way.  Handling expressions here seems
>>>> fundamentally wrong.  ISTM that making this query on an expression
>>>> should result in an immediate error.
>>>
>>> Sorry but "it seems wrong" is not a compelling argument.  You need
>>> to explain what you think is wrong with it.
>>
>> "Attributes apply to decls and types, not expressions" seems like an
>> argument strong enough.  (There are also special attributes for enums
>>   and ';' and labels.)
> So I think Martin's argument is that for an expression we can look at
> the type of the expression and see if the attribute is on that type.
> 
> That leads to some inconsistencies (that Jakub has pointed out) where an
> unfolded expression could produce a different result than it's folded
> result if the result was a constant.

The built-in is evaluated during parsing (same as __alignof__)
so I'm not sure I understand what inconsistencies it could be
subject to that __alignof__ isn't.  I'm open to examples, I just
can't think of any.

> 
> AFAICT the goal (outside handling just types) here is to be able to ask
> things like is a particular field within a structure packed, aliasing
> properties of objects, etc.

Yes.  The goal is to query functions, variables (including members),
and types for most attributes known to GCC that may be attached to
them.

> 
> My next thought was to use typeof to extract the type of the expression
> and pass that through (independent of Marek suggesting the same).
> Martin points out in a subsequent email that won't work because p->a in
> the supplied example returns an int rather than a packed int.   One
> could argue that's the wrong return value for typeof, but I don't think
> it's that clear cut.  In this specific instance I'd claim it's wrong,
> but I'd hazard a guess we don't have clear semantics in this space.

__alignof__ is documented to work this way:

   If the operand of __alignof__ is an lvalue rather than a type,
   its value is the required alignment for its type, taking into
   account any minimum alignment specified with GCC's __attribute__
   extension (see Variable Attributes). For example, after this
   declaration:

      struct foo { int x; char y; } foo1;

   the value of __alignof__ (foo1.y) is 1, even though its actual
   alignment is probably 2 or 4, the same as __alignof__ (int).

What isn't documented is the semantics for expressions that aren't
lvalues.  They are nevertheless accepted and, AFAICT, __alignof__
returns the alignment of their type.

> 
> I'll note that our documentation clearly states that attributes can be
> applied to functions, variables, labels, enums, statements and types.
> No provision AFAICT is made for expressions.  Users have never had the
> ability or assumption that they can ask for attributes on an expression.

Not quite.  As I said above, __alignof__ accepts expressions
because there is no way to apply the operator to a member without
using an expression of some sort.  But it also accepts any other
expressions.

> Martin's patch essentially allows for asking indirectly -- but I suspect
> it's going to be inconsistent in more ways than Jakub pointed out as the
> type system in gimple is "loose" in certain ways and the result could
> well change as we go through the optimizer pipeline (ie, this is bigger
> than just constant folding causing inconsistencies).

As I explained above, the built-in is fully evaluated and folded
by the front-ends during parsing.  It never makes it into GIMPLE.

> 
> Given that we're talking about a new feature with no existing end user
> expectations and the fact that attributes are documented as applying
> only to things which are decls or types, I'm more inclined to stay
> conservative at this point and reject expressions as syntax errors.
> 
> We can revisit in gcc-10 and see if there's a reasonable way to tighten
> semantics around typeof and/or loosen the requirement that we can only
> ask about attributes of DECL/TYPE nodes and define good semantics around
> that if we try.  I'm also willing to revisit if other reviewers chime in
> with other opinions -- this kind of stuff isn't my strongest area.

There is no way to do what you suggest without preventing
the built-in from being used with struct members, and  I don't
see what good crippling it like that would do, or what could
then be done differently to fix it.

By the way of an example, both the __alignof__ and the built-in
arguments are accepted today but the latter would not work if
references to members were considered an error:

   struct S { __attribute__ ((packed, aligned (2))) int i; };

   _Static_assert (__alignof__ (((struct S*)0)->i) == 2);
   _Static_assert (__alignof__ (__typeof__ (((struct S*)0)->i)) == 4);

   _Static_assert (__builtin_has_attribute (((struct S*)0)->i, packed));
   _Static_assert (__builtin_has_attribute (((struct S*)0)->i, aligned));

   _Static_assert (!__builtin_has_attribute (__typeof__ (((struct 
S*)0)->i), packed));
   _Static_assert (!__builtin_has_attribute (__typeof__ (((struct 
S*)0)->i), aligned));

because the attribute is attached to i's DECL and not to its type,
and there is no other way to refer to the member i of struct S.

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-03-19 18:37             ` Jeff Law
  2019-03-19 22:15               ` Martin Sebor
@ 2019-03-20  3:14               ` Joseph Myers
  2019-03-20  4:08                 ` Jeff Law
  1 sibling, 1 reply; 33+ messages in thread
From: Joseph Myers @ 2019-03-20  3:14 UTC (permalink / raw)
  To: Jeff Law; +Cc: Marek Polacek, Martin Sebor, gcc-patches, Jakub Jelinek

On Tue, 19 Mar 2019, Jeff Law wrote:

> I'll note that our documentation clearly states that attributes can be
> applied to functions, variables, labels, enums, statements and types.

A key thing here is that they can be applied to fields - that is, they can 
be properties of a FIELD_DECL.  Referring to a field either requires an 
expression referring to that field, or some other custom syntax that uses 
both a type name and a field name (like in __builtin_offsetof).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-03-20  3:14               ` Joseph Myers
@ 2019-03-20  4:08                 ` Jeff Law
  2019-03-21 22:03                   ` Martin Sebor
  0 siblings, 1 reply; 33+ messages in thread
From: Jeff Law @ 2019-03-20  4:08 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Marek Polacek, Martin Sebor, gcc-patches, Jakub Jelinek

On 3/19/19 8:22 PM, Joseph Myers wrote:
> On Tue, 19 Mar 2019, Jeff Law wrote:
> 
>> I'll note that our documentation clearly states that attributes can be
>> applied to functions, variables, labels, enums, statements and types.
> 
> A key thing here is that they can be applied to fields - that is, they can 
> be properties of a FIELD_DECL.  Referring to a field either requires an 
> expression referring to that field, or some other custom syntax that uses 
> both a type name and a field name (like in __builtin_offsetof).
> 
Thanks for chiming in, your opinions on this kind of thing are greatly
appreciated.

Understood WRT applying to fields, and I think that's consistent with
some of what Jakub has expressed elsewhere -- specifically that we
should consider allowing COMPONENT_REFs as the exception, returning the
attributes of the associated FIELD_DECL in that case.

Is there a need to call out BIT_FIELD_REFs where we can't actually get
to the underlying DECL?  And if so, how do we do that in the end user
documentation that is clear and consistent?

One of the big worries I've got here is that documenting when an
expression as an argument to __builtin_has_attribute (or any attribute
query) can be expected to work.  It's always easier on our end users to
loosen semantics of extensions over time than it is to tighten them.


Jeff

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-03-20  4:08                 ` Jeff Law
@ 2019-03-21 22:03                   ` Martin Sebor
  2019-03-21 22:19                     ` Jakub Jelinek
  2019-04-04 22:01                     ` PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288) Jeff Law
  0 siblings, 2 replies; 33+ messages in thread
From: Martin Sebor @ 2019-03-21 22:03 UTC (permalink / raw)
  To: Jeff Law, Joseph Myers; +Cc: Marek Polacek, gcc-patches, Jakub Jelinek

On 3/19/19 9:33 PM, Jeff Law wrote:
> On 3/19/19 8:22 PM, Joseph Myers wrote:
>> On Tue, 19 Mar 2019, Jeff Law wrote:
>>
>>> I'll note that our documentation clearly states that attributes can be
>>> applied to functions, variables, labels, enums, statements and types.
>>
>> A key thing here is that they can be applied to fields - that is, they can
>> be properties of a FIELD_DECL.  Referring to a field either requires an
>> expression referring to that field, or some other custom syntax that uses
>> both a type name and a field name (like in __builtin_offsetof).
>>
> Thanks for chiming in, your opinions on this kind of thing are greatly
> appreciated.
> 
> Understood WRT applying to fields, and I think that's consistent with
> some of what Jakub has expressed elsewhere -- specifically that we
> should consider allowing COMPONENT_REFs as the exception, returning the
> attributes of the associated FIELD_DECL in that case.
> 
> Is there a need to call out BIT_FIELD_REFs where we can't actually get
> to the underlying DECL?  And if so, how do we do that in the end user
> documentation that is clear and consistent?

Is it possible to see a BIT_FIELD_REF here?  I couldn't find a way.

> 
> One of the big worries I've got here is that documenting when an
> expression as an argument to __builtin_has_attribute (or any attribute
> query) can be expected to work.  It's always easier on our end users to
> loosen semantics of extensions over time than it is to tighten them.

I wonder if a part of the issue isn't due to a mismatch between
the C terminology and what GCC uses internally.  Every argument
to the built-in that's not a type (and every argument to attribute
copy which doesn't accept types) must be a C expression:

1) either an identifier naming a function or variable, or
2) some other expression like a member reference via . or ->,
    an array subscript, or the indirection expression *.

But GCC distinguishes three kinds of arguments:

1) a DECL,
2) some sort of a reference like ARRAY_REF, COMPONENT_REF or
    INDIRECT_REF
3) an expression that satisfies the EXPR_P() predicate (e.g.,
    (struct S*)0, or (struct S){ 1 })

Jeff, you seem to want the built-in to accept just (1) on the GCC
list above and reject (3) (and seem to be waffling on (2)).

How would such an argument be described in a way that users
unfamiliar with GCC internals could easily understand?

All sorts of expressions can be used to refer to fields.  Given
the type definition 'struct A { int b[2]; };' besides
FUNCTION_DECL, PARM_DECL, and VAR_DECL we might expect to commonly
see arguments like:

COMPONENT_REF:
   ((struct A*)0)->b
   (*((struct A*)0)).b
   ((struct A*)0)[0].b

INDIRECT_REF:
   *((struct A*)0)[0].b

ARRAY_REF:
   ((struct A*)0)[0].b[0]

To users, they're all just expressions.

Fields aside, the expressions below seem quite plausible to me
too, especially when the built-in argument is the result of macro
expansion:

CALL_EXPR:
   foo ()

COMPOUND_LITERAL_EXPR:
   (struct A){ ... }

COND_EXPR:
   (0 ? a0 : a1)

COMPOUND_EXPR:
   ((void)0, a)

NON_LVALUE_EXPR:
   (struct A)a

etc.  In these cases the built-in could be passed the result of
__typeof__ instead, but if the built-in itself is part of a macro
that can be invoked either with one of the arguments on the _REF
list or with one of these expressions, it would only work as
expected for half of them.

Using __typeof__ doesn't work for the copy attribute because it
only takes expressions as arguments and not types.

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-03-21 22:03                   ` Martin Sebor
@ 2019-03-21 22:19                     ` Jakub Jelinek
  2019-03-21 22:25                       ` Martin Sebor
  2019-04-04 22:01                     ` PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288) Jeff Law
  1 sibling, 1 reply; 33+ messages in thread
From: Jakub Jelinek @ 2019-03-21 22:19 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On Thu, Mar 21, 2019 at 03:59:55PM -0600, Martin Sebor wrote:
> 1) either an identifier naming a function or variable, or
> 2) some other expression like a member reference via . or ->,
>    an array subscript, or the indirection expression *.
> 
> But GCC distinguishes three kinds of arguments:
> 
> 1) a DECL,
> 2) some sort of a reference like ARRAY_REF, COMPONENT_REF or
>    INDIRECT_REF
> 3) an expression that satisfies the EXPR_P() predicate (e.g.,
>    (struct S*)0, or (struct S){ 1 })
> 
> Jeff, you seem to want the built-in to accept just (1) on the GCC
> list above and reject (3) (and seem to be waffling on (2)).
> 
> How would such an argument be described in a way that users
> unfamiliar with GCC internals could easily understand?

Say that the argument is either a type or an expression that is
either an identifier (for C++ id-expression) to cover 1) and
a postfix expression with . or -> operator (to cover COMPONENT_REF)?
We do not want to allow INDIRECT_REF, ARRAY_REF, etc.

	Jakub

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-03-21 22:19                     ` Jakub Jelinek
@ 2019-03-21 22:25                       ` Martin Sebor
  2019-03-21 22:32                         ` Jakub Jelinek
  0 siblings, 1 reply; 33+ messages in thread
From: Martin Sebor @ 2019-03-21 22:25 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On 3/21/19 4:13 PM, Jakub Jelinek wrote:
> On Thu, Mar 21, 2019 at 03:59:55PM -0600, Martin Sebor wrote:
>> 1) either an identifier naming a function or variable, or
>> 2) some other expression like a member reference via . or ->,
>>     an array subscript, or the indirection expression *.
>>
>> But GCC distinguishes three kinds of arguments:
>>
>> 1) a DECL,
>> 2) some sort of a reference like ARRAY_REF, COMPONENT_REF or
>>     INDIRECT_REF
>> 3) an expression that satisfies the EXPR_P() predicate (e.g.,
>>     (struct S*)0, or (struct S){ 1 })
>>
>> Jeff, you seem to want the built-in to accept just (1) on the GCC
>> list above and reject (3) (and seem to be waffling on (2)).
>>
>> How would such an argument be described in a way that users
>> unfamiliar with GCC internals could easily understand?
> 
> Say that the argument is either a type or an expression that is
> either an identifier (for C++ id-expression) to cover 1) and
> a postfix expression with . or -> operator (to cover COMPONENT_REF)?

That doesn't look easy to understand.

> We do not want to allow INDIRECT_REF, ARRAY_REF, etc.

Why not?  What exactly is the concern?

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-03-21 22:25                       ` Martin Sebor
@ 2019-03-21 22:32                         ` Jakub Jelinek
  2019-03-21 23:27                           ` Martin Sebor
  0 siblings, 1 reply; 33+ messages in thread
From: Jakub Jelinek @ 2019-03-21 22:32 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On Thu, Mar 21, 2019 at 04:19:37PM -0600, Martin Sebor wrote:
> > Say that the argument is either a type or an expression that is
> > either an identifier (for C++ id-expression) to cover 1) and
> > a postfix expression with . or -> operator (to cover COMPONENT_REF)?
> 
> That doesn't look easy to understand.

Why?  Those users that don't read corresponding language standards
will just see the compiler diagnosing any uses but those 3 kinds
and can then just read the documentation which will show in examples what is
accepted and what it will do.

> > We do not want to allow INDIRECT_REF, ARRAY_REF, etc.
> 
> Why not?  What exactly is the concern?

Because only the . and -> operators are needed to get at the non-static
member declaration.  INDIRECT_REF or ARRAY_REF aren't useful for that,
and then it raises the question what exactly is supposed to be the behavior
when you use *expr or expr[0] or expr->field[0].  Those expression don't
have any decl, so we'd be back at your suggestion to pretty randomly
sometimes return DECL_ATTRIBUTES, sometimes TYPE_ATTRIBUTES, sometimes both.
That is just a bad design.  If people want type attributes, they should use
__typeof or decltype or just type itself in the argument.

	Jakub

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-03-21 22:32                         ` Jakub Jelinek
@ 2019-03-21 23:27                           ` Martin Sebor
  2019-03-22  2:37                             ` Martin Sebor
  0 siblings, 1 reply; 33+ messages in thread
From: Martin Sebor @ 2019-03-21 23:27 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On 3/21/19 4:25 PM, Jakub Jelinek wrote:
> On Thu, Mar 21, 2019 at 04:19:37PM -0600, Martin Sebor wrote:
>>> Say that the argument is either a type or an expression that is
>>> either an identifier (for C++ id-expression) to cover 1) and
>>> a postfix expression with . or -> operator (to cover COMPONENT_REF)?
>>
>> That doesn't look easy to understand.
> 
> Why?  Those users that don't read corresponding language standards
> will just see the compiler diagnosing any uses but those 3 kinds
> and can then just read the documentation which will show in examples what is
> accepted and what it will do.

Because to most users it suggests that . and -> are the only operators
that are accepted in the expression and so something like p[0].a is not
a valid argument.

Those who don't read the manual will be puzzled when, after having had
p[0].a accepted, p->a[0] will trigger an error.

>>> We do not want to allow INDIRECT_REF, ARRAY_REF, etc.
>>
>> Why not?  What exactly is the concern?
> 
> Because only the . and -> operators are needed to get at the non-static
> member declaration.  INDIRECT_REF or ARRAY_REF aren't useful for that,
> and then it raises the question what exactly is supposed to be the behavior
> when you use *expr or expr[0] or expr->field[0].  Those expression don't
> have any decl, so we'd be back at your suggestion to pretty randomly
> sometimes return DECL_ATTRIBUTES, sometimes TYPE_ATTRIBUTES, sometimes both.
> That is just a bad design.  If people want type attributes, they should use
> __typeof or decltype or just type itself in the argument.

I never suggested to "pretty randomly sometimes return
DECL_ATTRIBUTES, sometimes TYPE_ATTRIBUTES, or sometimes both."
That's a silly mischaracterization, just as it would be to say
the same thing about __alignof__, and it works much the same way.
It operates on expressions and returns the alignment either
explicitly speciified for the variable (or function) or that
specified for its type.

I modeled the built-in on __alignof__.  There may bugs where it
behaves differently, or subtle deviations where I chose a different
approach, but it's certainly not random.  I'd like to fix the bugs,
and I'm open to reconsidering the deviations, but using either as
a justification for rejecting those kinds of expressions would
result in hard-to-use API.  And _that_ would be bad design.

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-03-21 23:27                           ` Martin Sebor
@ 2019-03-22  2:37                             ` Martin Sebor
  2019-04-02 21:20                               ` [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​ Martin Sebor
  0 siblings, 1 reply; 33+ messages in thread
From: Martin Sebor @ 2019-03-22  2:37 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On 3/21/19 5:05 PM, Martin Sebor wrote:
> On 3/21/19 4:25 PM, Jakub Jelinek wrote:
>> On Thu, Mar 21, 2019 at 04:19:37PM -0600, Martin Sebor wrote:
>>>> Say that the argument is either a type or an expression that is
>>>> either an identifier (for C++ id-expression) to cover 1) and
>>>> a postfix expression with . or -> operator (to cover COMPONENT_REF)?
>>>
>>> That doesn't look easy to understand.
>>
>> Why?  Those users that don't read corresponding language standards
>> will just see the compiler diagnosing any uses but those 3 kinds
>> and can then just read the documentation which will show in examples 
>> what is
>> accepted and what it will do.
> 
> Because to most users it suggests that . and -> are the only operators
> that are accepted in the expression and so something like p[0].a is not
> a valid argument.
> 
> Those who don't read the manual will be puzzled when, after having had
> p[0].a accepted, p->a[0] will trigger an error.
> 
>>>> We do not want to allow INDIRECT_REF, ARRAY_REF, etc.
>>>
>>> Why not?  What exactly is the concern?
>>
>> Because only the . and -> operators are needed to get at the non-static
>> member declaration.  INDIRECT_REF or ARRAY_REF aren't useful for that,
>> and then it raises the question what exactly is supposed to be the 
>> behavior
>> when you use *expr or expr[0] or expr->field[0].  Those expression don't
>> have any decl, so we'd be back at your suggestion to pretty randomly
>> sometimes return DECL_ATTRIBUTES, sometimes TYPE_ATTRIBUTES, sometimes 
>> both.
>> That is just a bad design.  If people want type attributes, they 
>> should use
>> __typeof or decltype or just type itself in the argument.
> 
> I never suggested to "pretty randomly sometimes return
> DECL_ATTRIBUTES, sometimes TYPE_ATTRIBUTES, or sometimes both."
> That's a silly mischaracterization, just as it would be to say
> the same thing about __alignof__, and it works much the same way.
> It operates on expressions and returns the alignment either
> explicitly speciified for the variable (or function) or that
> specified for its type.
> 
> I modeled the built-in on __alignof__.  There may bugs where it
> behaves differently, or subtle deviations where I chose a different
> approach, but it's certainly not random.  I'd like to fix the bugs,
> and I'm open to reconsidering the deviations, but using either as
> a justification for rejecting those kinds of expressions would
> result in hard-to-use API.  And _that_ would be bad design.

An example of a deviation from __alignof__ that comes to mind
is this:

   __attribute__ ((aligned (8))) int a[2];

   _Static_assert (__alignof__ (a) == 8);
   _Static_assert (__builtin_has_attribute (a, aligned));

   _Static_assert (a[0]) == 8);   // fails
   _Static_assert (__builtin_has_attribute (a[0], aligned));

I made the ARRAY_REF case the same as the VAR_DECL case because
the alignment of a whole array also implies the alignment of
the array's elements.  Ditto for attribute packed. (And with
the patch the INDIRECT_REF has the same effect.)

I'm guessing that what you're objecting to is that this decision
conflates the results of the builtin for an array declared with
an attribute with that of the array's elements, as in:

   __attribute__ ((vector_size (8))) int a[2];

   _Static_assert (__builtin_has_attribute (a, vector_size));
   _Static_assert (__builtin_has_attribute (a[0], vector_size));

where both assertions pass, even though just the array element
is a vector, while a itself is an ordinary array.  I can see
that is not quite right and might warrant reconsidering
the decision for ARRAY_REF.

To your point about using __typeof__: GCC is inconsistent about
what it applies variable and function attributes to, whether
the decl or its type.  For example, vector_size is documented
as a variable attribute but it applies to a type.  Similarly,
attributes alloc_size and malloc are both documented as
function attributes but the former applies to the function
type (and so can be applied to a pointer to function), while
the latter to the function decl (and is ignored with
a warning on pointers to functions).  Until this is cleaned
up, either by correcting the documentation, or preferably by
making these attributes uniformly apply to types, it should
be obvious that suggesting that "if people want type attributes,
they should use __typeof or decltype" does not offer a viable
solution.

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​
  2019-03-22  2:37                             ` Martin Sebor
@ 2019-04-02 21:20                               ` Martin Sebor
  2019-04-12 18:22                                 ` Jeff Law
  0 siblings, 1 reply; 33+ messages in thread
From: Martin Sebor @ 2019-04-02 21:20 UTC (permalink / raw)
  To: Jeff Law; +Cc: Jakub Jelinek, Joseph Myers, Marek Polacek, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1162 bytes --]

This is yet another follow up on the discussion of the fix for
the ICE in __builtin_has_attribute that started last December
with PR88383.

After my last post last week I went and added more tests to make
sure the built-in behaves as intended by comparing its result for
non-trivial expressions with that of __alignof__.  The test that
does this is the new builtin-has-attribute-7.c.

The test exposed one problem in the handling of attribute vector_size
by the built-in (I mentioned that in my last post).  It also exposed
a couple of bugs in the attribute handler itself.  I fixed both of
these in the attached patch.

This latest revision of the patch resolves the following bugs:

   PR 88383 - ICE calling __builtin_has_attribute on a reference
   PR 89288 - ICE in tree_code_size, at tree.c:865
   PR 89798 - excessive vector_size silently accepted and truncated
   PR 89797 - ICE on a vector_size (1LU << 33) int variable

Bootstrapped on x86_64-linux.  The tests are still running but
assuming they pass, is this last revision good to commit?

Martin

A link to my last comment in the archive:
   https://gcc.gnu.org/ml/gcc-patches/2019-03/msg01096.html

[-- Attachment #2: gcc-88383.diff --]
[-- Type: text/x-patch, Size: 32788 bytes --]

PR c/88383 - ICE calling __builtin_has_attribute on a reference
PR c/89288 - ICE in tree_code_size, at tree.c:865
PR c/89798 - excessive vector_size silently accepted and truncated
PR c/89797 - ICE on a vector_size (1LU << 33) int variable

gcc/ChangeLog:

	PR c/89797
	* targhooks.c (default_vector_alignment): Avoid assuming
	argument fits in SHWI.
	* tree.h (TYPE_VECTOR_SUBPARTS): Avoid sign overflow in
	a shift expression.

gcc/c-family/ChangeLog:

	PR c/88383
	PR c/89288
	PR c/89798
	PR c/89797
	* c-attribs.c (type_valid_for_vector_size): Detect excessively
	large sizes.
	(validate_attribute): Handle DECLs and expressions.
	(has_attribute): Handle types referenced by expressions.
	Avoid considering array attributes in ARRAY_REF expressions .

gcc/cp/ChangeLog:

	PR c/88383
	PR c/89288
	* parser.c (cp_parser_has_attribute_expression): Handle assignment
	expressions.

gcc/testsuite/ChangeLog:

	PR c/88383
	PR c/89288
	PR c/89798
	PR c/89797
	* c-c++-common/attributes-1.c: Adjust.
	* c-c++-common/builtin-has-attribute-6.c: New test.
	* c-c++-common/builtin-has-attribute-7.c: New test.
	* c-c++-common/builtin-has-attribute-4.c: Adjust expectations.
	* c-c++-common/builtin-has-attribute-6.c: New test.
	* gcc.dg/pr25559.c: Adjust.
	* gcc.dg/attr-vector_size.c: New test.
	
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index e559d3b55d2..9ded3df278e 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -3478,19 +3478,56 @@ type_valid_for_vector_size (tree type, tree atname, tree args,
     return type;
 
   tree size = TREE_VALUE (args);
+  /* Erroneous arguments have already been diagnosed.  */
+  if (size == error_mark_node)
+    return NULL_TREE;
+
   if (size && TREE_CODE (size) != IDENTIFIER_NODE
       && TREE_CODE (size) != FUNCTION_DECL)
     size = default_conversion (size);
 
-  if (!tree_fits_uhwi_p (size))
+  if (TREE_CODE (size) != INTEGER_CST)
+    {
+      if (error_p)
+	error ("%qE attribute argument value %qE is not an integer constant",
+	       atname, size);
+      else
+	warning (OPT_Wattributes,
+		 "%qE attribute argument value %qE is not an integer constant",
+		 atname, size);
+      return NULL_TREE;
+    }
+
+  if (!TYPE_UNSIGNED (TREE_TYPE (size))
+      && tree_int_cst_sgn (size) < 0)
     {
-      /* FIXME: make the error message more informative.  */
       if (error_p)
-	warning (OPT_Wattributes, "%qE attribute ignored", atname);
+	error ("%qE attribute argument value %qE is negative",
+	       atname, size);
+      else
+	warning (OPT_Wattributes,
+		 "%qE attribute argument value %qE is negative",
+		 atname, size);
+      return NULL_TREE;
+    }
+
+  /* The attribute argument value is constrained by the maximum bit
+     alignment representable in unsigned int on the host.  */
+  unsigned HOST_WIDE_INT vecsize;
+  unsigned HOST_WIDE_INT maxsize = tree_to_uhwi (max_object_size ());
+  if (!tree_fits_uhwi_p (size)
+      || (vecsize = tree_to_uhwi (size)) > maxsize)
+    {
+      if (error_p)
+	error ("%qE attribute argument value %qE exceeds %wu",
+	       atname, size, maxsize);
+      else
+	warning (OPT_Wattributes,
+		 "%qE attribute argument value %qE exceeds %wu",
+		 atname, size, maxsize);
       return NULL_TREE;
     }
 
-  unsigned HOST_WIDE_INT vecsize = tree_to_uhwi (size);
   if (vecsize % tree_to_uhwi (TYPE_SIZE_UNIT (type)))
     {
       if (error_p)
@@ -4033,8 +4070,12 @@ validate_attribute (location_t atloc, tree oper, tree attr)
 
   if (TYPE_P (oper))
     tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, oper);
-  else
+  else if (DECL_P (oper))
     tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
+  else if (EXPR_P (oper))
+    tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, TREE_TYPE (oper));
+  else
+    return false;
 
   /* Temporarily clear CURRENT_FUNCTION_DECL to make decl_attributes
      believe the DECL declared above is at file scope.  (See bug 87526.)  */
@@ -4043,7 +4084,7 @@ validate_attribute (location_t atloc, tree oper, tree attr)
   if (DECL_P (tmpdecl))
     {
       if (DECL_P (oper))
-	/* An alias cannot be a defintion so declare the symbol extern.  */
+	/* An alias cannot be a definition so declare the symbol extern.  */
 	DECL_EXTERNAL (tmpdecl) = true;
       /* Attribute visibility only applies to symbols visible from other
 	 translation units so make it "public."   */
@@ -4079,11 +4120,17 @@ has_attribute (location_t atloc, tree t, tree attr, tree (*convert)(tree))
       do
 	{
 	  /* Determine the array element/member declaration from
-	     an ARRAY/COMPONENT_REF.  */
+	     a COMPONENT_REF and an INDIRECT_REF involving a refeence.  */
 	  STRIP_NOPS (t);
 	  tree_code code = TREE_CODE (t);
-	  if (code == ARRAY_REF)
-	    t = TREE_OPERAND (t, 0);
+	  if (code == INDIRECT_REF)
+	    {
+	      tree op0 = TREE_OPERAND (t, 0);
+	      if (TREE_CODE (TREE_TYPE (op0)) == REFERENCE_TYPE)
+		t = op0;
+	      else
+		break;
+	    }
 	  else if (code == COMPONENT_REF)
 	    t = TREE_OPERAND (t, 1);
 	  else
@@ -4134,7 +4181,8 @@ has_attribute (location_t atloc, tree t, tree attr, tree (*convert)(tree))
 	}
       else
 	{
-	  atlist = TYPE_ATTRIBUTES (TREE_TYPE (expr));
+	  type = TREE_TYPE (expr);
+	  atlist = TYPE_ATTRIBUTES (type);
 	  done = true;
 	}
 
@@ -4210,9 +4258,10 @@ has_attribute (location_t atloc, tree t, tree attr, tree (*convert)(tree))
 	      if (tree arg = TREE_VALUE (attr))
 		{
 		  arg = convert (TREE_VALUE (arg));
-		  if (expr && DECL_P (expr)
-		      && DECL_USER_ALIGN (expr)
-		      && tree_fits_uhwi_p (arg))
+		  if (!tree_fits_uhwi_p (arg))
+		    /* Invalid argument.  */;
+		  else if (expr && DECL_P (expr)
+			   && DECL_USER_ALIGN (expr))
 		    found_match = DECL_ALIGN_UNIT (expr) == tree_to_uhwi (arg);
 		  else if (type && TYPE_USER_ALIGN (type))
 		    found_match = TYPE_ALIGN_UNIT (type) == tree_to_uhwi (arg);
@@ -4249,13 +4298,7 @@ has_attribute (location_t atloc, tree t, tree attr, tree (*convert)(tree))
 	    }
 	  else if (!strcmp ("vector_size", namestr))
 	    {
-	      if (!type)
-		continue;
-
-	      /* Determine the base type from arrays, pointers, and such.
-		 Fail if the base type is not a vector.  */
-	      type = type_for_vector_size (type);
-	      if (!VECTOR_TYPE_P (type))
+	      if (!type || !VECTOR_TYPE_P (type))
 		return false;
 
 	      if (tree arg = TREE_VALUE (attr))
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c669e49214f..6c24f2ff96a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -8552,9 +8552,9 @@ cp_parser_has_attribute_expression (cp_parser *parser)
   cp_parser_parse_definitely (parser);
 
   /* If the type-id production did not work out, then we must be
-     looking at the unary-expression production.  */
+     looking at an expression.  */
   if (!oper || oper == error_mark_node)
-    oper = cp_parser_unary_expression (parser);
+    oper = cp_parser_assignment_expression (parser);
 
   STRIP_ANY_LOCATION_WRAPPER (oper);
 
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 318f7e9784a..cfde248dd3d 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1247,14 +1247,18 @@ constant_alignment_word_strings (const_tree exp, HOST_WIDE_INT align)
   return align;
 }
 
-/* Default to natural alignment for vector types.  */
+/* Default to natural alignment for vector types, bounded by
+   MAX_OFILE_ALIGNMENT.  */
+
 HOST_WIDE_INT
 default_vector_alignment (const_tree type)
 {
-  HOST_WIDE_INT align = tree_to_shwi (TYPE_SIZE (type));
-  if (align > MAX_OFILE_ALIGNMENT)
-    align = MAX_OFILE_ALIGNMENT;
-  return align;
+  unsigned HOST_WIDE_INT align = MAX_OFILE_ALIGNMENT;
+  tree size = TYPE_SIZE (type);
+  if (tree_fits_uhwi_p (size))
+    align = tree_to_uhwi (size);
+
+  return align < MAX_OFILE_ALIGNMENT ? align : MAX_OFILE_ALIGNMENT;
 }
 
 /* The default implementation of
diff --git a/gcc/testsuite/c-c++-common/attributes-1.c b/gcc/testsuite/c-c++-common/attributes-1.c
index c4b232dad00..b73d31aa5e2 100644
--- a/gcc/testsuite/c-c++-common/attributes-1.c
+++ b/gcc/testsuite/c-c++-common/attributes-1.c
@@ -4,7 +4,7 @@
 void* my_calloc(unsigned, unsigned) __attribute__((alloc_size(1,bar))); /* { dg-warning ".alloc_size. attribute argument 2 is invalid" } */
 void* my_realloc(void*, unsigned) __attribute__((alloc_size(bar))); /* { dg-warning ".alloc_size. attribute argument is invalid" } */
 
-typedef char vec __attribute__((vector_size(bar))); /* { dg-warning "ignored" } */
+typedef char vec __attribute__((vector_size(bar)));
 
 void f1(char*) __attribute__((nonnull(bar))); /* { dg-warning ".nonnull. attribute argument is invalid" } */
 
@@ -14,7 +14,7 @@ void foo(int);
 void* my_calloc(unsigned, unsigned) __attribute__((alloc_size(1,foo))); /* { dg-warning ".alloc_size. attribute argument 2 has type .void\\\(int\\\)." } */
 void* my_realloc(void*, unsigned) __attribute__((alloc_size(foo))); /* { dg-warning ".alloc_size. attribute argument has type .void ?\\\(int\\\)" } */
 
-typedef char vec __attribute__((vector_size(foo))); /* { dg-warning "ignored" } */
+typedef char vec __attribute__((vector_size(foo))); /* { dg-error ".vector_size. attribute argument value .foo. is not an integer constant" } */
 
 void f1(char*) __attribute__((nonnull(foo))); /* { dg-warning ".nonnull. attribute argument has type .void ?\\\(int\\\)." } */
 void f2(char*) __attribute__((nonnull(1,foo))); /* { dg-warning ".nonnull. attribute argument 2 has type .void ?\\\(int\\\)." } */
diff --git a/gcc/testsuite/c-c++-common/builtin-has-attribute-4.c b/gcc/testsuite/c-c++-common/builtin-has-attribute-4.c
index a0681fa6980..ec3127794b5 100644
--- a/gcc/testsuite/c-c++-common/builtin-has-attribute-4.c
+++ b/gcc/testsuite/c-c++-common/builtin-has-attribute-4.c
@@ -3,7 +3,7 @@
    { dg-skip-if "No section attribute" { { hppa*-*-hpux* } && { ! lp64 } } }
    { dg-options "-Wall -ftrack-macro-expansion=0" }
    { dg-options "-Wall -Wno-narrowing -Wno-unused -ftrack-macro-expansion=0" { target c++ } }
-   { dg-additional-options "-DSKIP_ALIAS" { target *-*-darwin* } } 
+   { dg-additional-options "-DSKIP_ALIAS" { target *-*-darwin* } }
 */
 
 #define ATTR(...) __attribute__ ((__VA_ARGS__))
@@ -155,7 +155,8 @@ void test_packed (struct PackedMember *p)
   A (0, gpak[0].c, packed);
   A (0, gpak[1].s, packed);
   A (1, gpak->a, packed);
-  A (1, (*gpak).a[0], packed);
+  /* It's the array that's declared packed but not its elements.  */
+  A (0, (*gpak).a[0], packed);
 
   /* The following fails because in C it's represented as
        INDIRECT_REF (POINTER_PLUS (NOP_EXPR (ADDR_EXPR (gpak)), ...))
@@ -165,7 +166,8 @@ void test_packed (struct PackedMember *p)
   A (0, p->c, packed);
   A (0, p->s, packed);
   A (1, p->a, packed);
-  A (1, p->a[0], packed);
+  /* It's the array that's declared packed but not its elements.  */
+  A (0, p->a[0], packed);
   /* Similar to the comment above.
    A (1, *p->a, packed);  */
 }
@@ -218,13 +220,68 @@ void test_vector_size (void)
   A (1, iv16, vector_size (16));
   A (0, iv16, vector_size (32));
 
+  /* Verify that the attribute not detected on an array of vectors
+     but is detected on its elements.  */
+  typedef ATTR (vector_size (8)) float afv8_t[4];
+  A (0, afv8_t, vector_size);
+  A (0, afv8_t, vector_size (1));
+  A (0, afv8_t, vector_size (2));
+  A (0, afv8_t, vector_size (4));
+  A (0, afv8_t, vector_size (8));
+  A (0, afv8_t, vector_size (16));
+
+  A (1, __typeof__ ((*(afv8_t*)0)[0]), vector_size);
+  A (0, __typeof__ ((*(afv8_t*)0)[1]), vector_size (1));
+  A (0, __typeof__ ((*(afv8_t*)0)[2]), vector_size (2));
+  A (0, __typeof__ ((*(afv8_t*)0)[3]), vector_size (4));
+  A (1, __typeof__ ((*(afv8_t*)0)[0]), vector_size (8));
+  A (0, __typeof__ ((*(afv8_t*)0)[1]), vector_size (16));
+
+  A (1, __typeof__ (**(afv8_t*)0), vector_size);
+  A (0, __typeof__ (**(afv8_t*)0), vector_size (1));
+  A (0, __typeof__ (**(afv8_t*)0), vector_size (2));
+  A (0, __typeof__ (**(afv8_t*)0), vector_size (4));
+  A (1, __typeof__ (**(afv8_t*)0), vector_size (8));
+  A (0, __typeof__ (**(afv8_t*)0), vector_size (16));
+
   ATTR (vector_size (8)) float afv8[4];
-  A (1, afv8, vector_size);
+  A (0, afv8, vector_size);
   A (0, afv8, vector_size (1));
   A (0, afv8, vector_size (2));
   A (0, afv8, vector_size (4));
-  A (1, afv8, vector_size (8));
+  A (0, afv8, vector_size (8));
   A (0, afv8, vector_size (16));
+
+  A (1, afv8[0], vector_size);
+  A (0, afv8[1], vector_size (1));
+  A (0, afv8[2], vector_size (2));
+  A (0, afv8[3], vector_size (4));
+  A (1, afv8[0], vector_size (8));
+  A (0, afv8[1], vector_size (16));
+
+  A (1, *afv8, vector_size);
+  A (0, *afv8, vector_size (1));
+  A (0, *afv8, vector_size (2));
+  A (0, *afv8, vector_size (4));
+  A (1, *afv8, vector_size (8));
+  A (0, *afv8, vector_size (16));
+
+  /* sizeof (long double) is 12 on i386.  */
+  enum { VecSize = 8 * sizeof (long double) };
+  ATTR (vector_size (VecSize)) long double aldv[1][2][3];
+  A (0, aldv, vector_size);
+  A (0, aldv[0], vector_size);
+  A (0, aldv[0][0], vector_size);
+  A (1, aldv[0][0][0], vector_size);
+  A (0, aldv[0][0][1], vector_size (VecSize / 2));
+  A (1, aldv[0][0][2], vector_size (VecSize));
+
+  A (0, aldv[0][0][0][0], vector_size);
+
+  A (0, *aldv, vector_size);
+  A (0, **aldv, vector_size);
+  A (1, ***aldv, vector_size);
+  A (1, ***aldv, vector_size (VecSize));
 }
 
 
diff --git a/gcc/testsuite/c-c++-common/builtin-has-attribute-6.c b/gcc/testsuite/c-c++-common/builtin-has-attribute-6.c
new file mode 100644
index 00000000000..89cf4f23d47
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/builtin-has-attribute-6.c
@@ -0,0 +1,114 @@
+/* PR c/88383 - ICE calling _builtin_has_attribute(r, aligned(N)))
+   on an overaligned reference r
+   PR c/89288 - ICE in tree_code_size, at tree.c:865
+   { dg-options "-Wall -ftrack-macro-expansion=0" }
+   { dg-options "-Wall -Wno-narrowing -Wno-unused -ftrack-macro-expansion=0" { target c++ } }  */
+
+#define ATTR(...) __attribute__ ((__VA_ARGS__))
+
+#define A(expect, sym, attr)						\
+  typedef int Assert [1 - 2 * !(__builtin_has_attribute (sym, attr) == expect)]
+
+typedef ATTR (aligned (8)) int Int8;
+
+/* The attribute applies to the array, not to the type of its elements.  */
+extern ATTR (aligned (8)) char i8arr[];
+
+/* The attribute applies to the pointer, not to the type it points to.  */
+extern ATTR (aligned (8)) int *ptr;
+extern Int8 *i8ptr;
+
+#if __cplusplus
+
+/* Similarly here, the attribute applies to the reference, not to its type.  */
+extern ATTR (aligned (8)) int &ref;
+extern Int8 &i8ref;
+
+#else
+
+/* Fake references in C.  */
+extern ATTR (aligned (8)) int ref;
+Int8 i8ref;
+
+#endif
+
+void test (void)
+{
+  /* Verify that the built-in detects the attribute on the array. */
+  A (1, i8arr, aligned);
+  A (0, i8arr, aligned (1));
+  A (0, i8arr, aligned (2));
+  A (0, i8arr, aligned (4));
+  A (1, i8arr, aligned (8));
+  A (0, i8arr, aligned (16));
+
+  A (0, i8arr + 1, aligned);
+  A (0, i8arr + 2, aligned (1));
+  A (0, i8arr + 3, aligned (8));
+
+  /* Verify the builtin detects the absence of the attribute on
+     the elements.  */
+  A (0, i8arr[0], aligned);
+  A (0, *i8arr,   aligned);
+
+  /* Verify that the built-in doesn't confuse the attribute on
+     the pointer type with that to the pointed to type.  This
+     also exercises PR c/89288.  */
+  A (0, (Int8*)0, aligned);
+  A (0, (int*)0,  aligned);
+  A (0, (void*)0, aligned);
+  A (0, 0,        aligned);
+
+  /* Verify that the built-in detects the attribute on the pointer
+     itself. */
+  A (1, ptr, aligned);
+  A (0, ptr, aligned (1));
+  A (0, ptr, aligned (2));
+  A (0, ptr, aligned (4));
+  A (1, ptr, aligned (8));
+  A (0, ptr, aligned (16));
+
+  A (0, ptr + 1, aligned);
+  A (0, ptr + 2, aligned (1));
+  A (0, ptr + 3, aligned (8));
+
+  /* The pointed to type is not declared with attribute aligned.  */
+  A (0, *ptr, aligned);
+  A (0, *ptr, aligned (1));
+  A (0, *ptr, aligned (2));
+  A (0, *ptr, aligned (4));
+  A (0, *ptr, aligned (8));
+  A (0, *ptr, aligned (16));
+
+  A (0, *ptr + 1, aligned);
+  A (0, *ptr + 2, aligned (1));
+  A (0, *ptr + 3, aligned (8));
+
+  /* Verify that the built-in correctly detects the attribute on
+     the type of the lvalue referenced by the pointer. */
+  A (0, i8ptr,     aligned);
+  A (0, i8ptr,     aligned (8));
+  A (0, i8ptr + 1, aligned);
+  A (0, i8ptr + 3, aligned (8));
+  A (1, *i8ptr,    aligned);
+  A (0, *i8ptr,    aligned (1));
+  A (0, *i8ptr,    aligned (2));
+  A (0, *i8ptr,    aligned (4));
+  A (1, *i8ptr,    aligned (8));
+  A (0, *i8ptr,    aligned (16));
+
+  /* The reference itself is declared aligned, even though the type
+     it refers to isn't.  But see PR c++/88362.  */
+  A (1, ref, aligned);
+  A (0, ref, aligned (1));
+  A (0, ref, aligned (2));
+  A (0, ref, aligned (4));
+  A (1, ref, aligned (8));
+  A (0, ref, aligned (16));
+
+  /* Also verify that assignment expressions are accepted.  */
+  A (0, ref = 1,  aligned);
+  A (0, ref += 2, aligned (1));
+  A (0, ref /= 3, aligned (8));
+
+}
diff --git a/gcc/testsuite/c-c++-common/builtin-has-attribute-7.c b/gcc/testsuite/c-c++-common/builtin-has-attribute-7.c
new file mode 100644
index 00000000000..6ea2e9e7192
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/builtin-has-attribute-7.c
@@ -0,0 +1,396 @@
+/* Verify that __builtin_has_attribute detects attributes aligned
+   and packed in various forms of array dereferencing and indirection
+   expressions correspondingly to __alignof__.
+   { dg-do compile }
+   { dg-options "-Wall -Wno-unused -ftrack-macro-expansion=0" } */
+
+#define ATTR(...) __attribute__ ((__VA_ARGS__))
+#define ALIGN(N)  ATTR (aligned (N))
+
+#define Assert(expr) typedef int _Assert [1 - 2 * !(expr)]
+
+/* Verify that  __builtin_has_attribute (EXPR, align (ALIGN)) returns
+   the EXPECTed result.  When EXPECT is true, verify that the EXPression
+   has the expected ALIGNment.    */
+#define A3(expect, expr, align) do {					\
+    Assert (!expect || __alignof__ (expr) == align);			\
+    Assert (expect == __builtin_has_attribute (expr, aligned (align))); \
+  } while (0)
+
+#define A(expect, expr)							\
+  Assert (expect == __builtin_has_attribute (expr, aligned))		\
+
+enum { PA = __alignof__ (void*) };
+
+/* Define pointer to pointer types, with different alignments
+   at each level of indirection.  */
+typedef struct S8 { char a[8]; }   S8;
+typedef ALIGN (8)  S8              I8;
+typedef ALIGN (16) I8             *P16_I8;
+typedef            P16_I8         *P_P16_I8;
+typedef ALIGN (32) P_P16_I8       *P32_P_P16_I8;
+typedef            P32_P_P16_I8   *P_P32_P_P16_I8;
+typedef ALIGN (64) P_P32_P_P16_I8 *P64_P_P32_P_P16_I8;
+
+Assert ( 8 == __alignof__ (I8));
+Assert (16 == __alignof__ (P16_I8));
+Assert (PA == __alignof__ (P_P16_I8));
+Assert (32 == __alignof__ (P32_P_P16_I8));
+Assert (PA == __alignof__ (P_P32_P_P16_I8));
+Assert (64 == __alignof__ (P64_P_P32_P_P16_I8));
+
+
+/* Similar to the pointer of pointers above, define array of array
+   types, with different alignments at each level of indirection.  */
+typedef struct S64 { char a[64]; } S64;
+typedef ALIGN (64) S64             I64;
+typedef ALIGN (32) I64             A32_I64[3];
+typedef            A32_I64         A_A32_I64[5];
+typedef ALIGN (16) A_A32_I64       A16_A_A32_I64[7];
+typedef            A16_A_A32_I64   A_A16_A_A32_I64[11];
+typedef ALIGN (8)  A_A16_A_A32_I64 A8_A_A16_A_A32_I64[13];
+
+Assert (64 == __alignof__ (I64));
+Assert (32 == __alignof__ (A32_I64));
+/* With no explicit alignment, an array of overaligned elements
+   is considered to have the alignment of its elements.  */
+Assert (32 == __alignof__ (A_A32_I64));
+Assert (16 == __alignof__ (A16_A_A32_I64));
+Assert (16 == __alignof__ (A_A16_A_A32_I64));
+Assert ( 8 == __alignof__ (A8_A_A16_A_A32_I64));
+
+
+void test_arrays (void)
+{
+  /* Verify that the aligned attribute on each of the composite types
+     is detected corresponding to the result of __alignof__.  */
+  A (1, (*(A8_A_A16_A_A32_I64*)0));
+  A3 (1, (*(A8_A_A16_A_A32_I64*)0), 8);
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0], 8);
+  /* GCC propagates the user-align bit from element types to their
+     arrays but it doesn't propagate the attribute itself.  The built-in
+     considers both the  bit and the attribute so it succeeds below even
+     though the referenced type isn't declared with the attribute.  */
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0], 8);
+  A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0], 16);
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0], 32);
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1], 8);
+  A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1], 16);
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1], 32);
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2], 16);
+  A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1][2], 32);
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2], 64);
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3], 16);
+  A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3], 32);
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3], 64);
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3][4], 32);
+  A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3][4], 64);
+  A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3][4], 128);
+
+  A8_A_A16_A_A32_I64 a;
+  A3 (0, a[0], 8);
+  A3 (1, a[0], 16);
+  A3 (0, a[0], 32);
+  A3 (0, a[0][1], 8);
+  A3 (1, a[0][1], 16);
+  A3 (0, a[0][1], 32);
+  A3 (0, a[0][1][2], 16);
+  A3 (1, a[0][1][2], 32);
+  A3 (0, a[0][1][2], 64);
+  A3 (0, a[0][1][2][3], 16);
+  A3 (1, a[0][1][2][3], 32);
+  A3 (0, a[0][1][2][3], 64);
+  A3 (0, a[0][1][2][3][4], 32);
+  A3 (1, a[0][1][2][3][4], 64);
+  A3 (0, a[0][1][2][3][4], 128);
+}
+
+void test_pointers (void)
+{
+  /* Verify that the aligned attribute on each of the composite pointer
+     types is detected corresponding to the result of __alignof__.  */
+  A (1, I8);
+  A3 (0, I8, 4);
+  A3 (1, I8, 8);
+
+  A (1, P16_I8);
+  A3 (0, P16_I8, 8);
+  A3 (1, P16_I8, 16);
+
+  A (0, P_P16_I8);
+  A3 (0, P_P16_I8, 8);
+  A3 (0, P_P16_I8, 16);
+
+  A (1, P32_P_P16_I8);
+  A3 (0, P32_P_P16_I8, 8);
+  A3 (0, P32_P_P16_I8, 16);
+  A3 (1, P32_P_P16_I8, 32);
+
+  A (0, P_P32_P_P16_I8);
+
+  A (1, P64_P_P32_P_P16_I8);
+  A3 (0, P64_P_P32_P_P16_I8, 8);
+  A3 (0, P64_P_P32_P_P16_I8, 16);
+  A3 (0, P64_P_P32_P_P16_I8, 32);
+  A3 (1, P64_P_P32_P_P16_I8, 64);
+
+
+  /* Verify that the attribute on each of the composite types is detected
+     in the type of each of the indirection expressions.  */
+  A (1, *(P16_I8)0);
+  A3 (1, *(P16_I8)0, 8);
+  A3 (0, *(P16_I8)0, 16);
+
+  A (1, *(P_P16_I8)0);
+  A3 (0, *(P_P16_I8)0, 8);
+  A3 (1, *(P_P16_I8)0, 16);
+
+  A (0, *(P32_P_P16_I8)0);
+  A3 (0, *(P32_P_P16_I8)0, 8);
+  A3 (0, *(P32_P_P16_I8)0, 16);
+  A3 (0, *(P32_P_P16_I8)0, 32);
+
+  A (1, *(P_P32_P_P16_I8)0);
+  A3 (1, *(P_P32_P_P16_I8)0, 32);
+
+  A (0, *(P64_P_P32_P_P16_I8)0);
+
+  /* Verify that the attribute on each of the composite types is detected
+     in the type of each of the subscipting expressions.  */
+  A (1, ((P16_I8)0)[0]);
+  A3 (1, ((P16_I8)0)[1], 8);
+  A3 (0, ((P16_I8)0)[2], 16);
+
+  A (1, ((P_P16_I8)0)[3]);
+  A3 (0, ((P_P16_I8)0)[4], 8);
+  A3 (1, ((P_P16_I8)0)[5], 16);
+
+  A (0, ((P32_P_P16_I8)0)[6]);
+  A3 (0, ((P32_P_P16_I8)0)[7], 8);
+  A3 (0, ((P32_P_P16_I8)0)[8], 16);
+  A3 (0, ((P32_P_P16_I8)0)[9], 32);
+
+  A (1, ((P_P32_P_P16_I8)0)[10]);
+  A3 (1, ((P_P32_P_P16_I8)0)[11], 32);
+
+  A (0, ((P64_P_P32_P_P16_I8)0)[12]);
+
+
+  /* Verify that the attribute on each of the composite types is detected
+     in the type of each of the subscipting expression involving variables.  */
+
+  I8                   i8;
+  P16_I8               p16_i8 = &i8;
+  P_P16_I8             p_p16_i8 = &p16_i8;
+  P32_P_P16_I8         p32_p_p16_i8 = &p_p16_i8;
+  P_P32_P_P16_I8       p_p32_p_p16_i8 = &p32_p_p16_i8;
+  P64_P_P32_P_P16_I8   p64_p_p32_p_p16_i8 = &p_p32_p_p16_i8;
+
+  A (1, p16_i8[0]);
+  A3 (1, p16_i8[1], 8);
+  A3 (0, p16_i8[2], 16);
+
+  A (1, p_p16_i8[3]);
+  A3 (0, p_p16_i8[4], 8);
+  A3 (1, p_p16_i8[5], 16);
+
+  A (0, p32_p_p16_i8[6]);
+  A3 (0, p32_p_p16_i8[7], 8);
+  A3 (0, p32_p_p16_i8[8], 16);
+  A3 (0, p32_p_p16_i8[9], 32);
+
+  A (1, p_p32_p_p16_i8[10]);
+  A3 (1, p_p32_p_p16_i8[11], 32);
+
+
+  A (1, p_p16_i8[0][1]);
+  A3 (1, p_p16_i8[1][2], 8);
+  A3 (0, p_p16_i8[2][3], 16);
+
+
+  A (0, p64_p_p32_p_p16_i8[0]);
+
+  A (1, p64_p_p32_p_p16_i8[0][1]);
+  A3 (0, p64_p_p32_p_p16_i8[0][2], 16);
+  A3 (1, p64_p_p32_p_p16_i8[0][3], 32);
+  A3 (0, p64_p_p32_p_p16_i8[0][4], 64);
+
+  A (0, p64_p_p32_p_p16_i8[0][1][2]);
+
+  A (1, p64_p_p32_p_p16_i8[0][1][2][3]);
+  A3 (0, p64_p_p32_p_p16_i8[0][1][2][4], 8);
+  A3 (1, p64_p_p32_p_p16_i8[0][1][2][4], 16);
+  A3 (0, p64_p_p32_p_p16_i8[0][1][2][4], 32);
+
+  A (1, p64_p_p32_p_p16_i8[0][1][2][3][4]);
+  A3 (1, p64_p_p32_p_p16_i8[0][1][2][3][5], 8);
+  A3 (0, p64_p_p32_p_p16_i8[0][1][2][4][6], 16);
+
+
+  /* Same as above but using the indirection expression.  */
+  A (0, *p64_p_p32_p_p16_i8);
+
+  A (1, **p64_p_p32_p_p16_i8);
+  A3 (0, **p64_p_p32_p_p16_i8, 16);
+  A3 (1, **p64_p_p32_p_p16_i8, 32);
+  A3 (0, **p64_p_p32_p_p16_i8, 64);
+
+  A (0, ***p64_p_p32_p_p16_i8);
+
+  A (1, ****p64_p_p32_p_p16_i8);
+  A3 (0, ****p64_p_p32_p_p16_i8, 8);
+  A3 (1, ****p64_p_p32_p_p16_i8, 16);
+  A3 (0, ****p64_p_p32_p_p16_i8, 32);
+
+  A (1, *****p64_p_p32_p_p16_i8);
+  A3 (1, *****p64_p_p32_p_p16_i8, 8);
+  A3 (0, *****p64_p_p32_p_p16_i8, 16);
+}
+
+
+S8 f_S8 (void);
+I8 f_I8 (void);
+P16_I8 f_P16_I8 (void);
+P_P16_I8 f_P_P16_I8 (void);
+P32_P_P16_I8 f_P32_P_P16_I8 (void);
+P_P32_P_P16_I8 f_P_P32_P_P16_I8 (void);
+P64_P_P32_P_P16_I8 f_P64_P_P32_P_P16_I8 (void);
+
+void test_function_call (void)
+{
+  /* Verify that the aligned attribute on each of the composite pointer
+     types returned by the functions is detected corresponding to
+     the result of __alignof__.  */
+
+  A (0, f_S8 ());
+
+  A (1, f_I8 ());
+  A3 (1, f_I8 (), 8);
+  A3 (0, f_I8 (), 16);
+
+  A (1, f_P16_I8 ());
+  A3 (0, f_P16_I8 (), 8);
+  A3 (1, f_P16_I8 (), 16);
+  A3 (0, f_P16_I8 (), 32);
+
+  A (1, *f_P16_I8 ());
+  A3 (1, *f_P16_I8 (), 8);
+  A3 (0, *f_P16_I8 (), 16);
+
+  A (0, f_P_P16_I8 ());
+
+  A (1, *f_P_P16_I8 ());
+  A3 (0, *f_P_P16_I8 (), 8);
+  A3 (1, *f_P_P16_I8 (), 16);
+  A3 (0, *f_P_P16_I8 (), 32);
+
+  A (1, **f_P_P16_I8 ());
+  A3 (1, **f_P_P16_I8 (), 8);
+  A3 (0, **f_P_P16_I8 (), 16);
+  A3 (0, **f_P_P16_I8 (), 32);
+}
+
+
+void test_compound_literal (void)
+{
+  A (0, (S8){ });
+
+  A (1, (I8){ });
+  A3 (1, (I8){ }, 8);
+  A3 (0, (I8){ }, 16);
+
+  A (1, (I64){ });
+  A3 (0, (I64){ }, 8);
+  A3 (0, (I64){ }, 16);
+  A3 (0, (I64){ }, 32);
+  A3 (1, (I64){ }, 64);
+
+  A (1, (A32_I64){ 0 });
+  A3 (0, (A32_I64){ 0 }, 8);
+  A3 (0, (A32_I64){ 0 }, 16);
+  A3 (1, (A32_I64){ 0 }, 32);
+  A3 (0, (A32_I64){ 0 }, 64);
+
+  A (1, ((A32_I64){ 0 })[0]);
+  A3 (0, ((A32_I64){ 0 })[0], 8);
+  A3 (0, ((A32_I64){ 0 })[0], 16);
+  A3 (0, ((A32_I64){ 0 })[0], 32);
+  A3 (1, ((A32_I64){ 0 })[0], 64);
+}
+
+
+void test_ternary_expression (int i)
+{
+  A (0, (0 ? (S8){ } : (S8){ }));
+
+  A (1, (1 ? (I8){ } : (I8){ }));
+  A3 (1, (2 ? (I8){ } : (I8){ }), 8);
+  A3 (0, (3 ? (I8){ } : (I8){ }), 16);
+
+  A (1, (4 ? (I64){ } : (I64){ }));
+  A3 (0, (5 ? (I64){ } : (I64){ }), 8);
+  A3 (0, (6 ? (I64){ } : (I64){ }), 16);
+  A3 (0, (7 ? (I64){ } : (I64){ }), 32);
+  A3 (1, (8 ? (I64){ } : (I64){ }), 64);
+
+#if !__cplusplus
+  /* Suppress -Wc++-compat warning: converting an array compound literal
+     to a pointer is ill-formed in C++  */
+# pragma GCC diagnostic ignored "-Wc++-compat"
+
+  A (0, (9 ? (A32_I64){ } : (A32_I64){ })); 
+  A3 (0, (i ? (A32_I64){ } : (A32_I64){ }), 8);
+  A3 (0, (i++ ? (A32_I64){ } : (A32_I64){ }), 16);
+  A3 (0, (++i ? (A32_I64){ } : (A32_I64){ }), 32);
+  A3 (0, (!i ? (A32_I64){ } : (A32_I64){ }), 64);
+
+  A (1, (0 ? (A32_I64){ } : (A32_I64){ })[0]);
+  A3 (0, (1 ? (A32_I64){ } : (A32_I64){ })[1], 8);
+  A3 (0, (2 ? (A32_I64){ } : (A32_I64){ })[2], 16);
+  A3 (0, (3 ? (A32_I64){ } : (A32_I64){ })[3], 32);
+  A3 (1, (3 ? (A32_I64){ } : (A32_I64){ })[i], 64);
+#endif
+}
+
+
+void test_comma_expression (int i)
+{
+#if __cplusplus
+  /* In C++, the type of the comma expressions whose operand is an array
+     is the array itself with any attributes it was defined with.  */
+# define R 1
+#else
+  /* In C, the type of the comma expressions whose operand is an array
+     is a pointer type that does not include any attributes the array
+     was defined with.  */
+# define R 0
+/* Suppress -Wc++-compat warning: converting an array compound literal
+   to a pointer is ill-formed in C++
+   G++ accepts the conversion in unevaluated contexts without a warning.  */
+# pragma GCC diagnostic ignored "-Wc++-compat"
+#endif
+
+  A (0, (0, (S8){ }));
+
+  A (1, (0, (I8){ }));
+  A3 (1, (1, (I8){ }), 8);
+  A3 (0, (2, (I8){ }), 16);
+
+  A (1, (3, (I64){ }));
+  A3 (0, (4, (I64){ }), 8);
+  A3 (0, (5, (I64){ }), 16);
+  A3 (0, (6, (I64){ }), 32);
+  A3 (1, (7, (I64){ }), 64);
+
+  A (R, (8, (A32_I64){ }));
+  A3 (0, (9, (A32_I64){ }), 8);
+  A3 (0, ((void)0, (A32_I64){ }), 16);
+  A3 (R, ((I64){ },(A32_I64){ }), 32);
+  A3 (0, (0, (A32_I64){ }), 64);
+
+  A (1, (1, ((A32_I64){ })[0]));
+  A3 (0, (2, ((A32_I64){ })[0]), 8);
+  A3 (0, (i++, ((A32_I64){ })[0]), 16);
+  A3 (0, (++i, ((A32_I64){ })[0]), 32);
+  A3 (1, (i = 0, ((A32_I64){ })[0]), 64);
+}
diff --git a/gcc/testsuite/gcc.dg/attr-vector_size.c b/gcc/testsuite/gcc.dg/attr-vector_size.c
new file mode 100644
index 00000000000..00be26accd5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-vector_size.c
@@ -0,0 +1,69 @@
+/* PR middle-end/89797 - ICE on a vector_size (1LU << 33) int variable
+   PR c/89798 - excessive vector_size silently accepted and truncated
+   { dg-do compile { target int32plus } }
+   { dg-options "-Wall -Wno-unused" } */
+
+#define ASSERT(e)    _Static_assert (e, #e)
+#define VEC(N)       __attribute__ ((vector_size (N)))
+#define POW2(N)      (1LLU << N)
+#define CAT(a, b)    a ## b
+#define CONCAT(a, b) CAT (a, b)
+
+#define DEFVEC(storage, N)				\
+  typedef VEC (POW2 (N)) char CONCAT (Vec, N);		\
+  storage CONCAT (Vec, N) CONCAT (v, N);		\
+  ASSERT (sizeof (CONCAT (Vec, N)) == POW2 (N));	\
+  ASSERT (sizeof (CONCAT (v, N)) == POW2 (N))
+
+DEFVEC (extern, 27);
+DEFVEC (extern, 28);
+DEFVEC (extern, 29);
+DEFVEC (extern, 30);
+
+#if __SIZEOF_SIZE_T__ > 4
+
+DEFVEC (extern, 31);
+DEFVEC (extern, 32);
+DEFVEC (extern, 33);
+DEFVEC (extern, 34);
+DEFVEC (extern, 60);
+DEFVEC (extern, 61);
+DEFVEC (extern, 62);
+
+VEC (POW2 (63)) char v63;     /* { dg-error  "'vector_size' attribute argument value '9223372036854775808' exceeds 9223372036854775807" "LP64" { target lp64 } } */
+
+#else
+
+VEC (POW2 (31)) char v31;     /* { dg-error  "'vector_size' attribute argument value '2147483648' exceeds 2147483647" "ILP32" { target ilp32 } } */
+
+VEC (POW2 (32)) char v32;     /* { dg-error  "'vector_size' attribute argument value '4294967296' exceeds 2147483647" "ILP32" { target ilp32 } } */
+
+#endif
+
+void test_local_scope (void)
+{
+  DEFVEC (auto, 27);
+  DEFVEC (auto, 28);
+  DEFVEC (auto, 29);
+  DEFVEC (auto, 30);
+
+#if __SIZEOF_SIZE_T__ > 4
+
+  DEFVEC (auto, 31);
+  DEFVEC (auto, 32);
+  DEFVEC (auto, 33);
+  DEFVEC (auto, 34);
+  DEFVEC (auto, 60);
+  DEFVEC (auto, 61);
+  DEFVEC (auto, 62);
+
+  VEC (POW2 (63)) char v63;   /* { dg-error  "'vector_size' attribute argument value '9223372036854775808' exceeds 9223372036854775807" "LP64" { target lp64 } } */
+
+#else
+
+  VEC (POW2 (31)) char v31;   /* { dg-error  "'vector_size' attribute argument value '2147483648' exceeds 2147483647" "ILP32" { target ilp32 } } */
+
+  VEC (POW2 (32)) char v32;   /* { dg-error  "'vector_size' attribute argument value '4294967296' exceeds 2147483647" "ILP32" { target ilp32 } } */
+
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/pr25559.c b/gcc/testsuite/gcc.dg/pr25559.c
index 7879a1558b6..a8bce657b1c 100644
--- a/gcc/testsuite/gcc.dg/pr25559.c
+++ b/gcc/testsuite/gcc.dg/pr25559.c
@@ -2,7 +2,7 @@
 /* { dg-do compile } */
 
 #define vs(n) __attribute__((vector_size (n)))
-int vs (-1) a;			/* { dg-warning "attribute ignored" } */
+int vs (-1) a;			/* { dg-error ".vector_size. attribute argument value '-1' is negative" } */
 int vs (0) b;			/* { dg-error "zero vector size" } */
 int vs (1) c;			/* { dg-error "multiple of component size" } */
 int vs (sizeof (int) / 2) d;	/* { dg-error "multiple of component size" } */
diff --git a/gcc/tree.h b/gcc/tree.h
index 0e8e8dff876..94a810694a5 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3741,7 +3741,7 @@ TYPE_VECTOR_SUBPARTS (const_tree node)
       return res;
     }
   else
-    return 1 << precision;
+    return (unsigned HOST_WIDE_INT)1 << precision;
 }
 
 /* Set the number of elements in VECTOR_TYPE NODE to SUBPARTS, which must

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288)
  2019-03-21 22:03                   ` Martin Sebor
  2019-03-21 22:19                     ` Jakub Jelinek
@ 2019-04-04 22:01                     ` Jeff Law
  1 sibling, 0 replies; 33+ messages in thread
From: Jeff Law @ 2019-04-04 22:01 UTC (permalink / raw)
  To: Martin Sebor, Joseph Myers; +Cc: Marek Polacek, gcc-patches, Jakub Jelinek

On 3/21/19 3:59 PM, Martin Sebor wrote:
> On 3/19/19 9:33 PM, Jeff Law wrote:
>> On 3/19/19 8:22 PM, Joseph Myers wrote:
>>> On Tue, 19 Mar 2019, Jeff Law wrote:
>>>
>>>> I'll note that our documentation clearly states that attributes can be
>>>> applied to functions, variables, labels, enums, statements and types.
>>>
>>> A key thing here is that they can be applied to fields - that is,
>>> they can
>>> be properties of a FIELD_DECL.  Referring to a field either requires an
>>> expression referring to that field, or some other custom syntax that
>>> uses
>>> both a type name and a field name (like in __builtin_offsetof).
>>>
>> Thanks for chiming in, your opinions on this kind of thing are greatly
>> appreciated.
>>
>> Understood WRT applying to fields, and I think that's consistent with
>> some of what Jakub has expressed elsewhere -- specifically that we
>> should consider allowing COMPONENT_REFs as the exception, returning the
>> attributes of the associated FIELD_DECL in that case.
>>
>> Is there a need to call out BIT_FIELD_REFs where we can't actually get
>> to the underlying DECL?  And if so, how do we do that in the end user
>> documentation that is clear and consistent?
> 
> Is it possible to see a BIT_FIELD_REF here?  I couldn't find a way.
Unsure.  It was a generic concern -- I don't have a motivating example.
 From very light reading in the front-ends, you're more likely to get
one from the C++ front-end rather the C front-end.  It may also be able
to get a BIT_FIELD_REF from some OMP constructs.  In general it looks
like the front-ends aren't generating them often, preferring to stick
with COMPONENT_REF instead.




> 
>>
>> One of the big worries I've got here is that documenting when an
>> expression as an argument to __builtin_has_attribute (or any attribute
>> query) can be expected to work.  It's always easier on our end users to
>> loosen semantics of extensions over time than it is to tighten them.
> 
> I wonder if a part of the issue isn't due to a mismatch between
> the C terminology and what GCC uses internally.  Every argument
> to the built-in that's not a type (and every argument to attribute
> copy which doesn't accept types) must be a C expression:
My hesitation has been based more on the core concept that we don't
attach attributes to expressions, only types and decls.  Thus asking if
an expression has any given attribute doesn't make much sense at first
glance.

In the copy attribute case the docs were pretty clear when and how it
applied to expressions -- specifically stating that we're going to look
at the underlying type and pull the attributes from there.

Now that in turn raises its own set of issues.  If the front-ends were
to change the type of an expression (and they have in the past,
particularly for COMPONENT_REF/INDIRECT_REF to avoid subsequent
nop-casts), then we have to worry about the inconsistencies in behavior
that's going to expose to the user.  Another case where that could
potentially happen would be LTO.  I believe LTO will canonicalize/merge
types to some degree and I don't offhand know the rules there and
inconsistencies could be exposed to the user.

Given that I think the front-end code that changed types of
COMPONENT_REF/INDIRECT_REF to avoid subsequent nop-conversions is no
longer in the tree and that (in theory) type merging in LTO should be
considering attributes I went ahead and pushed those concerns aside for
the copy attribute patch.

I'll be doing the same when re-re-re-reviewing the
__builtin_has_attribute patch :-)


jeff

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​
  2019-04-02 21:20                               ` [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​ Martin Sebor
@ 2019-04-12 18:22                                 ` Jeff Law
  2019-04-12 21:49                                   ` Jakub Jelinek
  0 siblings, 1 reply; 33+ messages in thread
From: Jeff Law @ 2019-04-12 18:22 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Jakub Jelinek, Joseph Myers, Marek Polacek, gcc-patches

On 4/2/19 3:19 PM, Martin Sebor wrote:
> This is yet another follow up on the discussion of the fix for
> the ICE in __builtin_has_attribute that started last December
> with PR88383.
> 
> After my last post last week I went and added more tests to make
> sure the built-in behaves as intended by comparing its result for
> non-trivial expressions with that of __alignof__.  The test that
> does this is the new builtin-has-attribute-7.c.
> 
> The test exposed one problem in the handling of attribute vector_size
> by the built-in (I mentioned that in my last post).  It also exposed
> a couple of bugs in the attribute handler itself.  I fixed both of
> these in the attached patch.
> 
> This latest revision of the patch resolves the following bugs:
> 
>   PR 88383 - ICE calling __builtin_has_attribute on a reference
>   PR 89288 - ICE in tree_code_size, at tree.c:865
>   PR 89798 - excessive vector_size silently accepted and truncated
>   PR 89797 - ICE on a vector_size (1LU << 33) int variable
> 
> Bootstrapped on x86_64-linux.  The tests are still running but
> assuming they pass, is this last revision good to commit?
> 
> Martin
> 
> A link to my last comment in the archive:
>   https://gcc.gnu.org/ml/gcc-patches/2019-03/msg01096.html
> 
> gcc-88383.diff
> 
> PR c/88383 - ICE calling __builtin_has_attribute on a reference
> PR c/89288 - ICE in tree_code_size, at tree.c:865
> PR c/89798 - excessive vector_size silently accepted and truncated
> PR c/89797 - ICE on a vector_size (1LU << 33) int variable
> 
> gcc/ChangeLog:
> 
> 	PR c/89797
> 	* targhooks.c (default_vector_alignment): Avoid assuming
> 	argument fits in SHWI.
> 	* tree.h (TYPE_VECTOR_SUBPARTS): Avoid sign overflow in
> 	a shift expression.
> 
> gcc/c-family/ChangeLog:
> 
> 	PR c/88383
> 	PR c/89288
> 	PR c/89798
> 	PR c/89797
> 	* c-attribs.c (type_valid_for_vector_size): Detect excessively
> 	large sizes.
> 	(validate_attribute): Handle DECLs and expressions.
> 	(has_attribute): Handle types referenced by expressions.
> 	Avoid considering array attributes in ARRAY_REF expressions .
> 
> gcc/cp/ChangeLog:
> 
> 	PR c/88383
> 	PR c/89288
> 	* parser.c (cp_parser_has_attribute_expression): Handle assignment
> 	expressions.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c/88383
> 	PR c/89288
> 	PR c/89798
> 	PR c/89797
> 	* c-c++-common/attributes-1.c: Adjust.
> 	* c-c++-common/builtin-has-attribute-6.c: New test.
> 	* c-c++-common/builtin-has-attribute-7.c: New test.
> 	* c-c++-common/builtin-has-attribute-4.c: Adjust expectations.
> 	* c-c++-common/builtin-has-attribute-6.c: New test.
> 	* gcc.dg/pr25559.c: Adjust.
> 	* gcc.dg/attr-vector_size.c: New test.
Per our offline discussion, I think this is OK with some documentation
updates to clarify expression handling.

In particular can you adjust the docs to more clearly indicate that for
an expression, we look at the attributes of the type of the expression.

With a suitable doc change of that nature, this is OK.

jeff

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​
  2019-04-12 18:22                                 ` Jeff Law
@ 2019-04-12 21:49                                   ` Jakub Jelinek
  2019-04-12 21:51                                     ` Jakub Jelinek
  2019-04-13  0:15                                     ` Martin Sebor
  0 siblings, 2 replies; 33+ messages in thread
From: Jakub Jelinek @ 2019-04-12 21:49 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On Fri, Apr 12, 2019 at 10:45:25AM -0600, Jeff Law wrote:
> > gcc/ChangeLog:
> > 
> > 	PR c/89797
> > 	* targhooks.c (default_vector_alignment): Avoid assuming
> > 	argument fits in SHWI.
> > 	* tree.h (TYPE_VECTOR_SUBPARTS): Avoid sign overflow in
> > 	a shift expression.
> > 
> > gcc/c-family/ChangeLog:
> > 
> > 	PR c/88383
> > 	PR c/89288
> > 	PR c/89798
> > 	PR c/89797
> > 	* c-attribs.c (type_valid_for_vector_size): Detect excessively
> > 	large sizes.
> > 	(validate_attribute): Handle DECLs and expressions.
> > 	(has_attribute): Handle types referenced by expressions.
> > 	Avoid considering array attributes in ARRAY_REF expressions .
> > 
> > gcc/cp/ChangeLog:
> > 
> > 	PR c/88383
> > 	PR c/89288
> > 	* parser.c (cp_parser_has_attribute_expression): Handle assignment
> > 	expressions.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > 	PR c/88383
> > 	PR c/89288
> > 	PR c/89798
> > 	PR c/89797
> > 	* c-c++-common/attributes-1.c: Adjust.
> > 	* c-c++-common/builtin-has-attribute-6.c: New test.
> > 	* c-c++-common/builtin-has-attribute-7.c: New test.
> > 	* c-c++-common/builtin-has-attribute-4.c: Adjust expectations.
> > 	* c-c++-common/builtin-has-attribute-6.c: New test.

New test twice for the same test?

> > 	* gcc.dg/pr25559.c: Adjust.
> > 	* gcc.dg/attr-vector_size.c: New test.
> Per our offline discussion, I think this is OK with some documentation
> updates to clarify expression handling.
> 
> In particular can you adjust the docs to more clearly indicate that for
> an expression, we look at the attributes of the type of the expression.
> 
> With a suitable doc change of that nature, this is OK.

Has the patch been tested at all?
I see many new FAILs after the patch:
make check-gcc check-c++-all RUNTESTFLAGS="--target_board=unix\{-m32,-m64\} dg.exp='attributes-1.c builtin-has-attribute-*.c pr71574.c attr-vector_size.c pr25559.c'"
FAIL: gcc.dg/attr-vector_size.c LP64 (test for errors, line 33)
FAIL: gcc.dg/attr-vector_size.c LP64 (test for errors, line 60)
FAIL: gcc.dg/attr-vector_size.c (test for excess errors)
FAIL: gcc.dg/pr25559.c  (test for errors, line 5)
FAIL: gcc.dg/pr25559.c (test for excess errors)
FAIL: c-c++-common/attributes-1.c  -Wc++-compat   (test for errors, line 17)
FAIL: c-c++-common/attributes-1.c  -Wc++-compat  (test for excess errors)
FAIL: c-c++-common/builtin-has-attribute-4.c  -Wc++-compat  (test for excess errors)
FAIL: c-c++-common/builtin-has-attribute-6.c  -Wc++-compat  (internal compiler error)
FAIL: c-c++-common/builtin-has-attribute-6.c  -Wc++-compat  (test for excess errors)
FAIL: c-c++-common/builtin-has-attribute-7.c  -Wc++-compat  (internal compiler error)
FAIL: c-c++-common/builtin-has-attribute-7.c  -Wc++-compat  (test for excess errors)
FAIL: c-c++-common/pr71574.c  -Wc++-compat   (test for errors, line 14)
FAIL: c-c++-common/pr71574.c  -Wc++-compat  (test for excess errors)
for -m64, 
FAIL: gcc.dg/attr-vector_size.c (internal compiler error)
FAIL: gcc.dg/attr-vector_size.c ILP32 (test for errors, line 37)
FAIL: gcc.dg/attr-vector_size.c ILP32 (test for errors, line 39)
FAIL: gcc.dg/attr-vector_size.c ILP32 (test for errors, line 64)
FAIL: gcc.dg/attr-vector_size.c ILP32 (test for errors, line 66)
FAIL: gcc.dg/attr-vector_size.c (test for excess errors)
FAIL: gcc.dg/pr25559.c  (test for errors, line 5)
FAIL: gcc.dg/pr25559.c (test for excess errors)
FAIL: c-c++-common/attributes-1.c  -Wc++-compat   (test for errors, line 17)
FAIL: c-c++-common/attributes-1.c  -Wc++-compat  (test for excess errors)
FAIL: c-c++-common/builtin-has-attribute-4.c  -Wc++-compat  (test for excess errors)
FAIL: c-c++-common/builtin-has-attribute-6.c  -Wc++-compat  (internal compiler error)
FAIL: c-c++-common/builtin-has-attribute-6.c  -Wc++-compat  (test for excess errors)
FAIL: c-c++-common/builtin-has-attribute-7.c  -Wc++-compat  (internal compiler error)
FAIL: c-c++-common/builtin-has-attribute-7.c  -Wc++-compat  (test for excess errors)
FAIL: c-c++-common/pr71574.c  -Wc++-compat   (test for errors, line 14)
FAIL: c-c++-common/pr71574.c  -Wc++-compat  (test for excess errors)
for -m32, and quite similar set for C++.

	Jakub

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​
  2019-04-12 21:49                                   ` Jakub Jelinek
@ 2019-04-12 21:51                                     ` Jakub Jelinek
  2019-04-13  0:15                                     ` Martin Sebor
  1 sibling, 0 replies; 33+ messages in thread
From: Jakub Jelinek @ 2019-04-12 21:51 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On Fri, Apr 12, 2019 at 11:42:59PM +0200, Jakub Jelinek wrote:
> > With a suitable doc change of that nature, this is OK.
> 
> Has the patch been tested at all?
> I see many new FAILs after the patch:
> make check-gcc check-c++-all RUNTESTFLAGS="--target_board=unix\{-m32,-m64\} dg.exp='attributes-1.c builtin-has-attribute-*.c pr71574.c attr-vector_size.c pr25559.c'"
> FAIL: gcc.dg/attr-vector_size.c LP64 (test for errors, line 33)
> FAIL: gcc.dg/attr-vector_size.c LP64 (test for errors, line 60)
> FAIL: gcc.dg/attr-vector_size.c (test for excess errors)
> FAIL: gcc.dg/pr25559.c  (test for errors, line 5)
> FAIL: gcc.dg/pr25559.c (test for excess errors)
> FAIL: c-c++-common/attributes-1.c  -Wc++-compat   (test for errors, line 17)
> FAIL: c-c++-common/attributes-1.c  -Wc++-compat  (test for excess errors)
> FAIL: c-c++-common/builtin-has-attribute-4.c  -Wc++-compat  (test for excess errors)
> FAIL: c-c++-common/builtin-has-attribute-6.c  -Wc++-compat  (internal compiler error)
> FAIL: c-c++-common/builtin-has-attribute-6.c  -Wc++-compat  (test for excess errors)
> FAIL: c-c++-common/builtin-has-attribute-7.c  -Wc++-compat  (internal compiler error)
> FAIL: c-c++-common/builtin-has-attribute-7.c  -Wc++-compat  (test for excess errors)
> FAIL: c-c++-common/pr71574.c  -Wc++-compat   (test for errors, line 14)
> FAIL: c-c++-common/pr71574.c  -Wc++-compat  (test for excess errors)
> for -m64, 
> FAIL: gcc.dg/attr-vector_size.c (internal compiler error)
> FAIL: gcc.dg/attr-vector_size.c ILP32 (test for errors, line 37)
> FAIL: gcc.dg/attr-vector_size.c ILP32 (test for errors, line 39)
> FAIL: gcc.dg/attr-vector_size.c ILP32 (test for errors, line 64)
> FAIL: gcc.dg/attr-vector_size.c ILP32 (test for errors, line 66)
> FAIL: gcc.dg/attr-vector_size.c (test for excess errors)
> FAIL: gcc.dg/pr25559.c  (test for errors, line 5)
> FAIL: gcc.dg/pr25559.c (test for excess errors)
> FAIL: c-c++-common/attributes-1.c  -Wc++-compat   (test for errors, line 17)
> FAIL: c-c++-common/attributes-1.c  -Wc++-compat  (test for excess errors)
> FAIL: c-c++-common/builtin-has-attribute-4.c  -Wc++-compat  (test for excess errors)
> FAIL: c-c++-common/builtin-has-attribute-6.c  -Wc++-compat  (internal compiler error)
> FAIL: c-c++-common/builtin-has-attribute-6.c  -Wc++-compat  (test for excess errors)
> FAIL: c-c++-common/builtin-has-attribute-7.c  -Wc++-compat  (internal compiler error)
> FAIL: c-c++-common/builtin-has-attribute-7.c  -Wc++-compat  (test for excess errors)
> FAIL: c-c++-common/pr71574.c  -Wc++-compat   (test for errors, line 14)
> FAIL: c-c++-common/pr71574.c  -Wc++-compat  (test for excess errors)
> for -m32, and quite similar set for C++.

And
https://gcc.gnu.org/ml/gcc-testresults/2019-04/msg01416.html
confirms that too.

	Jakub

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​
  2019-04-12 21:49                                   ` Jakub Jelinek
  2019-04-12 21:51                                     ` Jakub Jelinek
@ 2019-04-13  0:15                                     ` Martin Sebor
  2019-04-15 13:56                                       ` Christophe Lyon
  1 sibling, 1 reply; 33+ messages in thread
From: Martin Sebor @ 2019-04-13  0:15 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On 4/12/19 3:42 PM, Jakub Jelinek wrote:
> On Fri, Apr 12, 2019 at 10:45:25AM -0600, Jeff Law wrote:
>>> gcc/ChangeLog:
>>>
>>> 	PR c/89797
>>> 	* targhooks.c (default_vector_alignment): Avoid assuming
>>> 	argument fits in SHWI.
>>> 	* tree.h (TYPE_VECTOR_SUBPARTS): Avoid sign overflow in
>>> 	a shift expression.
>>>
>>> gcc/c-family/ChangeLog:
>>>
>>> 	PR c/88383
>>> 	PR c/89288
>>> 	PR c/89798
>>> 	PR c/89797
>>> 	* c-attribs.c (type_valid_for_vector_size): Detect excessively
>>> 	large sizes.
...
> 
> Has the patch been tested at all?

A few times.  The c-attribs.c change above didn't make it into
the commit.

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​
  2019-04-13  0:15                                     ` Martin Sebor
@ 2019-04-15 13:56                                       ` Christophe Lyon
  2019-04-15 15:10                                         ` Jeff Law
  2019-04-17  6:02                                         ` Martin Sebor
  0 siblings, 2 replies; 33+ messages in thread
From: Christophe Lyon @ 2019-04-15 13:56 UTC (permalink / raw)
  To: Martin Sebor
  Cc: Jakub Jelinek, Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On Sat, 13 Apr 2019 at 00:38, Martin Sebor <msebor@gmail.com> wrote:
>
> On 4/12/19 3:42 PM, Jakub Jelinek wrote:
> > On Fri, Apr 12, 2019 at 10:45:25AM -0600, Jeff Law wrote:
> >>> gcc/ChangeLog:
> >>>
> >>>     PR c/89797
> >>>     * targhooks.c (default_vector_alignment): Avoid assuming
> >>>     argument fits in SHWI.
> >>>     * tree.h (TYPE_VECTOR_SUBPARTS): Avoid sign overflow in
> >>>     a shift expression.
> >>>
> >>> gcc/c-family/ChangeLog:
> >>>
> >>>     PR c/88383
> >>>     PR c/89288
> >>>     PR c/89798
> >>>     PR c/89797
> >>>     * c-attribs.c (type_valid_for_vector_size): Detect excessively
> >>>     large sizes.
> ...
> >
> > Has the patch been tested at all?
>
> A few times.  The c-attribs.c change above didn't make it into
> the commit.

Hi,
Even with r270331, I'm still seeing the ICE on aarch64 (actually with
trunk @r270370)

Is there still some commit missing?

Thanks,

Christophe

> Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​
  2019-04-15 13:56                                       ` Christophe Lyon
@ 2019-04-15 15:10                                         ` Jeff Law
  2019-04-17  6:02                                         ` Martin Sebor
  1 sibling, 0 replies; 33+ messages in thread
From: Jeff Law @ 2019-04-15 15:10 UTC (permalink / raw)
  To: Christophe Lyon, Martin Sebor
  Cc: Jakub Jelinek, Joseph Myers, Marek Polacek, gcc-patches

On 4/15/19 7:12 AM, Christophe Lyon wrote:
> On Sat, 13 Apr 2019 at 00:38, Martin Sebor <msebor@gmail.com> wrote:
>>
>> On 4/12/19 3:42 PM, Jakub Jelinek wrote:
>>> On Fri, Apr 12, 2019 at 10:45:25AM -0600, Jeff Law wrote:
>>>>> gcc/ChangeLog:
>>>>>
>>>>>     PR c/89797
>>>>>     * targhooks.c (default_vector_alignment): Avoid assuming
>>>>>     argument fits in SHWI.
>>>>>     * tree.h (TYPE_VECTOR_SUBPARTS): Avoid sign overflow in
>>>>>     a shift expression.
>>>>>
>>>>> gcc/c-family/ChangeLog:
>>>>>
>>>>>     PR c/88383
>>>>>     PR c/89288
>>>>>     PR c/89798
>>>>>     PR c/89797
>>>>>     * c-attribs.c (type_valid_for_vector_size): Detect excessively
>>>>>     large sizes.
>> ...
>>>
>>> Has the patch been tested at all?
>>
>> A few times.  The c-attribs.c change above didn't make it into
>> the commit.
> 
> Hi,
> Even with r270331, I'm still seeing the ICE on aarch64 (actually with
> trunk @r270370)
> 
> Is there still some commit missing?
> 
Or perhaps something else broken.  My tester flagged these are aarch64


> New tests that FAIL (4 tests):
> 
> gcc.dg/attr-vector_size.c (internal compiler error)
> gcc.dg/attr-vector_size.c (test for excess errors)
> gcc.dg/attr-vector_size.c LP64 (test for errors, line 33)
> gcc.dg/attr-vector_size.c LP64 (test for errors, line 60)

The rest of the tests passed.  It could well be something different
about the aarch64 port.  Seems like a bit of debugging is advisable.

jeff

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​
  2019-04-15 13:56                                       ` Christophe Lyon
  2019-04-15 15:10                                         ` Jeff Law
@ 2019-04-17  6:02                                         ` Martin Sebor
  2019-04-17  7:05                                           ` Jakub Jelinek
  1 sibling, 1 reply; 33+ messages in thread
From: Martin Sebor @ 2019-04-17  6:02 UTC (permalink / raw)
  To: Christophe Lyon
  Cc: Jakub Jelinek, Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On 4/15/19 7:12 AM, Christophe Lyon wrote:
> On Sat, 13 Apr 2019 at 00:38, Martin Sebor <msebor@gmail.com> wrote:
>>
>> On 4/12/19 3:42 PM, Jakub Jelinek wrote:
>>> On Fri, Apr 12, 2019 at 10:45:25AM -0600, Jeff Law wrote:
>>>>> gcc/ChangeLog:
>>>>>
>>>>>      PR c/89797
>>>>>      * targhooks.c (default_vector_alignment): Avoid assuming
>>>>>      argument fits in SHWI.
>>>>>      * tree.h (TYPE_VECTOR_SUBPARTS): Avoid sign overflow in
>>>>>      a shift expression.
>>>>>
>>>>> gcc/c-family/ChangeLog:
>>>>>
>>>>>      PR c/88383
>>>>>      PR c/89288
>>>>>      PR c/89798
>>>>>      PR c/89797
>>>>>      * c-attribs.c (type_valid_for_vector_size): Detect excessively
>>>>>      large sizes.
>> ...
>>>
>>> Has the patch been tested at all?
>>
>> A few times.  The c-attribs.c change above didn't make it into
>> the commit.
> 
> Hi,
> Even with r270331, I'm still seeing the ICE on aarch64 (actually with
> trunk @r270370)
> 
> Is there still some commit missing?

I only fixed the TYPE_VECTOR_SUBPARTS bug behind the ICE in bug
89797 for targets where NUM_POLY_INT_COEFFS == 1, and only tested
it on x86_64.

The block of code that's compiled when NUM_POLY_INT_COEFFS == 1
is also buggy but from what I can tell in more ways than one.

   inline poly_uint64
   TYPE_VECTOR_SUBPARTS (const_tree node)
   {
     STATIC_ASSERT (NUM_POLY_INT_COEFFS <= 2);
     unsigned int precision = VECTOR_TYPE_CHECK 
(node)->type_common.precision;
     if (NUM_POLY_INT_COEFFS == 2)
       {
         poly_uint64 res = 0;
         res.coeffs[0] = 1 << (precision & 0xff);
         if (precision & 0x100)
   	  res.coeffs[1] = 1 << (precision & 0xff);
         return res;
       }
     else
       return (unsigned HOST_WIDE_INT)1 << precision;
   }

Shifting 1 to the left by more than 30 bits is undefined (that
was also the bug I fixed in the other branch).  In addition,
setting res.coeffs[1] to the same value as res.coeffs[0] doesn't
seem right either, but since precision should be less than 256
it may not actually matter.  In any case, I wasn't sure and
since I don't have easy access to speedy aarch64 hardware I
wasn't brave enough to mess with it at this stage.

Then there's another bug in aarch64_simd_vector_alignment
similar to the one the patch fixed in default_vector_alignment
where the code assumes that the vector alignment fits in SHWI.

The otherwise untested patch below fixes the ICE for aarch64
but not the other (suspected) bug.

Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 270402)
+++ gcc/tree.h	(working copy)
@@ -3735,9 +3735,9 @@ TYPE_VECTOR_SUBPARTS (const_tree node)
    if (NUM_POLY_INT_COEFFS == 2)
      {
        poly_uint64 res = 0;
-      res.coeffs[0] = 1 << (precision & 0xff);
+      res.coeffs[0] = (unsigned HOST_WIDE_INT)1 << (precision & 0xff);
        if (precision & 0x100)
-	res.coeffs[1] = 1 << (precision & 0xff);
+	res.coeffs[1] = (unsigned HOST_WIDE_INT)1 << (precision & 0xff);
        return res;
      }
    else
Index: gcc/config/aarch64/aarch64.c
===================================================================
--- gcc/config/aarch64/aarch64.c	(revision 270402)
+++ gcc/config/aarch64/aarch64.c	(working copy)
@@ -14924,7 +14924,10 @@ aarch64_simd_vector_alignment (const_tree type)
         be set for non-predicate vectors of booleans.  Modes are the most
         direct way we have of identifying real SVE predicate types.  */
      return GET_MODE_CLASS (TYPE_MODE (type)) == MODE_VECTOR_BOOL ? 16 
: 128;
-  HOST_WIDE_INT align = tree_to_shwi (TYPE_SIZE (type));
+  tree size = TYPE_SIZE (type);
+  unsigned HOST_WIDE_INT align = 128;
+  if (tree_fits_uhwi_p (size))
+    align = tree_to_uhwi (TYPE_SIZE (type));
    return MIN (align, 128);
  }

I'm guessing that the full fix for TYPE_VECTOR_SUBPARTS might look
something like this, but that's just a wild guess.

===================================================================
--- gcc/tree.h	(revision 270402)
+++ gcc/tree.h	(working copy)
@@ -3735,9 +3735,9 @@ TYPE_VECTOR_SUBPARTS (const_tree node)
    if (NUM_POLY_INT_COEFFS == 2)
      {
        poly_uint64 res = 0;
-      res.coeffs[0] = 1 << (precision & 0xff);
+      res.coeffs[0] = (unsigned HOST_WIDE_INT)1 << (precision & 0xff);
        if (precision & 0x100)
-	res.coeffs[1] = 1 << (precision & 0xff);
+	res.coeffs[1] = (unsigned HOST_WIDE_INT)1 << ((precision & 0x100) >> 16);
        return res;
      }
    else

Martin

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​
  2019-04-17  6:02                                         ` Martin Sebor
@ 2019-04-17  7:05                                           ` Jakub Jelinek
  0 siblings, 0 replies; 33+ messages in thread
From: Jakub Jelinek @ 2019-04-17  7:05 UTC (permalink / raw)
  To: Martin Sebor
  Cc: Christophe Lyon, Jeff Law, Joseph Myers, Marek Polacek, gcc-patches

On Tue, Apr 16, 2019 at 08:40:29PM -0600, Martin Sebor wrote:
> --- gcc/tree.h	(revision 270402)
> +++ gcc/tree.h	(working copy)
> @@ -3735,9 +3735,9 @@ TYPE_VECTOR_SUBPARTS (const_tree node)
>    if (NUM_POLY_INT_COEFFS == 2)
>      {
>        poly_uint64 res = 0;
> -      res.coeffs[0] = 1 << (precision & 0xff);
> +      res.coeffs[0] = (unsigned HOST_WIDE_INT)1 << (precision & 0xff);
>        if (precision & 0x100)
> -	res.coeffs[1] = 1 << (precision & 0xff);
> +	res.coeffs[1] = (unsigned HOST_WIDE_INT)1 << (precision & 0xff);

Instead of (unsigned HOST_WIDE_INT)1 one should use HOST_WIDE_INT_1U
macro.

	Jakub

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2019-04-17  7:00 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-11 19:20 [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288) Martin Sebor
2019-02-11 19:34 ` Jakub Jelinek
2019-02-11 20:23 ` Jakub Jelinek
2019-02-11 20:59   ` Martin Sebor
2019-02-19  2:53 ` PING " Martin Sebor
2019-02-21 19:40   ` Jeff Law
2019-02-21 20:47     ` Martin Sebor
2019-02-21 20:56       ` Jeff Law
2019-02-21 22:42         ` Martin Sebor
2019-02-21 22:45           ` Jeff Law
2019-02-21 23:07             ` Martin Sebor
2019-02-22 18:01           ` Marek Polacek
2019-02-22 19:03             ` Martin Sebor
2019-03-19 18:37             ` Jeff Law
2019-03-19 22:15               ` Martin Sebor
2019-03-20  3:14               ` Joseph Myers
2019-03-20  4:08                 ` Jeff Law
2019-03-21 22:03                   ` Martin Sebor
2019-03-21 22:19                     ` Jakub Jelinek
2019-03-21 22:25                       ` Martin Sebor
2019-03-21 22:32                         ` Jakub Jelinek
2019-03-21 23:27                           ` Martin Sebor
2019-03-22  2:37                             ` Martin Sebor
2019-04-02 21:20                               ` [PATCH] fix ICEs in c-attribs.c (PR 88383, 89288, 89798, 89797)​ Martin Sebor
2019-04-12 18:22                                 ` Jeff Law
2019-04-12 21:49                                   ` Jakub Jelinek
2019-04-12 21:51                                     ` Jakub Jelinek
2019-04-13  0:15                                     ` Martin Sebor
2019-04-15 13:56                                       ` Christophe Lyon
2019-04-15 15:10                                         ` Jeff Law
2019-04-17  6:02                                         ` Martin Sebor
2019-04-17  7:05                                           ` Jakub Jelinek
2019-04-04 22:01                     ` PING [PATCH] fix ICE in __builtin_has_attribute (PR 88383 and 89288) Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).