public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] handle expressions in __builtin_has_attribute (PR 88383)
@ 2018-12-06  3:56 Martin Sebor
  2018-12-13 18:59 ` Jeff Law
  0 siblings, 1 reply; 15+ messages in thread
From: Martin Sebor @ 2018-12-06  3:56 UTC (permalink / raw)
  To: Gcc Patch List

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

The __builtin_has_attribute function fails with an ICE when
its first argument is an expression such as INDIRECT_REF, or
many others.  The code simply assumes it's either a type or
a decl.  The attached patch corrects this oversight.

While testing the fix I also noticed the C++ front end expects
the first operand to be a unary expression, which causes most
other kinds of expressions to be rejected.  The patch fixes
that as well.

Finally, while testing the fix even more I realized that
the built-in considers the underlying array itself in ARRAY_REF
expressions rather than its type, which leads to inconsistent
results for overaligned arrays (it's the array itself that's
overaligned, not its elements).  So I fixed that too and
adjusted the one test designed to verify this.

Tested on x86_64-linux.

Martin

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

PR c/88383 - ICE calling __builtin_has_attribute on a reference

gcc/c-family/ChangeLog:

	PR c/88383
	* 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
	* parser.c (cp_parser_has_attribute_expression): Handle assignment
	expressions.

gcc/testsuite/ChangeLog:

	PR c/88383
	* 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 266799)
+++ gcc/c-family/c-attribs.c	(working copy)
@@ -3994,8 +3994,10 @@ validate_attribute (location_t atloc, tree oper, t
 
   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));
 
   /* Temporarily clear CURRENT_FUNCTION_DECL to make decl_attributes
      believe the DECL declared above is at file scope.  (See bug 87526.)  */
@@ -4040,11 +4042,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
@@ -4095,7 +4103,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 266799)
+++ gcc/cp/parser.c	(working copy)
@@ -8480,9 +8480,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);
 
   /* Go back to evaluating expressions.  */
   --cp_unevaluated_operand;
Index: gcc/testsuite/c-c++-common/builtin-has-attribute-4.c
===================================================================
--- gcc/testsuite/c-c++-common/builtin-has-attribute-4.c	(revision 266799)
+++ gcc/testsuite/c-c++-common/builtin-has-attribute-4.c	(working copy)
@@ -151,7 +151,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)), ...))
@@ -161,7 +162,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,105 @@
+/* PR c/88383 - ICE calling _builtin_has_attribute(r, aligned(N)))
+   on an overaligned reference r
+   { 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 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] 15+ messages in thread

end of thread, other threads:[~2019-01-17  1:16 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-06  3:56 [PATCH] handle expressions in __builtin_has_attribute (PR 88383) Martin Sebor
2018-12-13 18:59 ` Jeff Law
2018-12-13 19:21   ` Martin Sebor
2018-12-13 19:48     ` Martin Sebor
2018-12-13 19:56       ` Jakub Jelinek
2018-12-13 22:22         ` Martin Sebor
2018-12-13 23:40           ` Jakub Jelinek
2018-12-14  4:04             ` Martin Sebor
2018-12-14  7:41               ` Jakub Jelinek
2018-12-15  0:18                 ` Martin Sebor
2018-12-21  2:56       ` Martin Sebor
2019-01-03 22:22         ` PING " Martin Sebor
2019-01-08  0:32           ` PING #2 " Martin Sebor
2019-01-15 16:31             ` Martin Sebor
2019-01-17  1:16               ` 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).