From: Martin Sebor Date: Mon, 1 Apr 2019 17:04:10 +0000 (+0000) Subject: PR c/89685 - ICE on attribute copy with a compound expression X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ddeae8c8ac2681f5fb738f78df747782afa6ac15;p=gcc.git PR c/89685 - ICE on attribute copy with a compound expression gcc/c-family/ChangeLog: PR c/89685 * c-attribs.c (handle_copy_attribute): Handle references and non-constant expressions. gcc/testsuite/ChangeLog: PR c/89685 * gcc.dg/attr-copy-8.c: New test. * g++.dg/ext/attr-copy-2.C: New test. From-SVN: r270062 --- diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index e10baba8a72..cf73a1cad1c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2019-04-01 Martin Sebor + + PR c/89685 + * c-attribs.c (handle_copy_attribute): Handle references and + non-constant expressions. + 2019-03-22 Jakub Jelinek PR c++/87481 diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index e559d3b55d2..d055a0897ac 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -2413,15 +2413,31 @@ handle_copy_attribute (tree *node, tree name, tree args, } /* Consider address-of expressions in the attribute argument - as requests to copy from the referenced entity. For constant - expressions, consider those to be requests to copy from their - type, such as in: + as requests to copy from the referenced entity. */ + if (TREE_CODE (ref) == ADDR_EXPR) + ref = TREE_OPERAND (ref, 0); + + do + { + /* Drill down into references to find the referenced decl. */ + tree_code refcode = TREE_CODE (ref); + if (refcode == ARRAY_REF + || refcode == INDIRECT_REF) + ref = TREE_OPERAND (ref, 0); + else if (refcode == COMPONENT_REF) + ref = TREE_OPERAND (ref, 1); + else + break; + } while (!DECL_P (ref)); + + /* For object pointer expressions, consider those to be requests + to copy from their type, such as in: struct __attribute__ (copy ((struct T *)0)) U { ... }; which copies type attributes from struct T to the declaration of struct U. */ - if (TREE_CODE (ref) == ADDR_EXPR) - ref = TREE_OPERAND (ref, 0); - else if (CONSTANT_CLASS_P (ref)) + if ((CONSTANT_CLASS_P (ref) || EXPR_P (ref)) + && POINTER_TYPE_P (TREE_TYPE (ref)) + && !FUNCTION_POINTER_TYPE_P (TREE_TYPE (ref))) ref = TREE_TYPE (ref); if (DECL_P (decl)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d194f4d88d4..1c516a95185 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-04-01 Martin Sebor + + PR c/89685 + * gcc.dg/attr-copy-8.c: New test. + * g++.dg/ext/attr-copy-2.C: New test. + 2019-04-01 Andrey Belevantsev PR rtl-optimization/86928 diff --git a/gcc/testsuite/g++.dg/ext/attr-copy-2.C b/gcc/testsuite/g++.dg/ext/attr-copy-2.C new file mode 100644 index 00000000000..7776959d9f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-copy-2.C @@ -0,0 +1,124 @@ +/* PR c/89685 - ICE on attribute copy with a compound expression + { dg-do compile } + { dg-options "-Wall -Wno-unused-value -Wno-int-to-pointer-cast" } */ + +#if __cplusplus <= 199711L +# define static_assert(expr) typedef char Assert [1 - !(expr) * 2] +#endif + +#define ATTR(...) __attribute__ ((__VA_ARGS__)) + +typedef struct ATTR (packed) A { ATTR (packed) unsigned bf: 1; } A; + +typedef struct B +{ + struct A a; + struct A *pa; + struct A &ra; +} B; + +extern struct A a; +extern struct A *pa; +extern struct A &ra; +extern B b; +extern B ab[1]; +extern B *pb; +extern B &rb; + +typedef struct C +{ + ATTR (copy ((struct A *)0)) short m_pa_0; + ATTR (copy ((struct A *)(1, 0))) int m_pa_1_0; + ATTR (copy ((struct A *)(0, 1))) long m_pa_0_1; + + ATTR (copy (*(struct A *)0)) short m_xpa_0; + ATTR (copy (*(struct A *)(1, 0))) int m_xpa_1_0; + ATTR (copy (*(struct A *)(0, 1))) long m_xpa_0_1; + + ATTR (copy (((struct A *)0)[0])) short m_arpa_0; + ATTR (copy (((struct A *)(1, 0))[0])) int m_arpa_1_0; + ATTR (copy (((struct A *)(0, 1))[0])) long m_arpa_0_1; + + ATTR (copy (a)) short m_a; + ATTR (copy (b.a)) int m_b_a; + ATTR (copy (b.pa)) long m_b_pa; + ATTR (copy (b.ra)) long m_b_ra; + + ATTR (copy (&a)) short m_ara; + ATTR (copy (&b.a)) int m_arb_a; + ATTR (copy (*b.pa)) long m_xb_pa; + ATTR (copy (b.pa[0])) long m_arb_pa; + + ATTR (copy (*pa)) short m_xpa; + ATTR (copy (pa[0])) short m_arpa; + + ATTR (copy (ra)) short m_ra; + + ATTR (copy (ab[0].a)) int m_arab_a; + ATTR (copy (ab[1].pa)) long m_arab_pa; + ATTR (copy (*ab[2].pa)) int m_xarab_pa; + ATTR (copy (ab[3].pa->bf)) unsigned int m_arab_pa_bf: 1; + ATTR (copy (ab[4].ra.bf)) unsigned int m_arab_ra_bf: 1; + + ATTR (copy (pb->a)) int m_pb_a; + ATTR (copy (pb->pa)) long m_pb_pa; + ATTR (copy (*pb->pa)) int m_xpb_pa; + ATTR (copy (pb->pa->bf)) unsigned int m_pb_pa_bf: 1; + ATTR (copy (pb->ra.bf)) unsigned int m_pb_ra_bf: 1; + + ATTR (copy (rb.a)) int m_rb_a; + ATTR (copy (rb.pa)) long m_rb_pa; + ATTR (copy (*rb.pa)) int m_xrb_pa; + ATTR (copy (rb.pa->bf)) unsigned int m_rb_pa_bf: 1; + + ATTR (aligned (4), copy ((struct A *)(0))) short m_a4_pa_0; +} C; + + +static_assert (__builtin_has_attribute (((C*)0)->m_pa_0, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_pa_1_0, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_pa_0_1, packed)); + +static_assert (__builtin_has_attribute (((C*)0)->m_xpa_0, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_xpa_1_0, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_xpa_0_1, packed)); + +static_assert (__builtin_has_attribute (((C*)0)->m_ra, packed)); + +static_assert (__builtin_has_attribute (((C*)0)->m_arpa_0, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_arpa_1_0, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_arpa_0_1, packed)); + +static_assert (__builtin_has_attribute (((C*)0)->m_a, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_b_a, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_b_pa, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_b_ra, packed)); + +static_assert (__builtin_has_attribute (((C*)0)->m_ara, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_arb_a, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_xb_pa, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_arb_pa, packed)); + +static_assert (__builtin_has_attribute (((C*)0)->m_xpa, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_arpa, packed)); + +static_assert (__builtin_has_attribute (((C*)0)->m_arab_a, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_arab_pa, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_xarab_pa, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_arab_pa_bf, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_arab_ra_bf, packed)); + +static_assert (__builtin_has_attribute (((C*)0)->m_pb_a, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_pb_pa, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_pb_pa, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_pb_pa_bf, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_pb_ra_bf, packed)); + +static_assert (__builtin_has_attribute (((C*)0)->m_rb_a, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_rb_pa, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_xrb_pa, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_rb_pa_bf, packed)); + +static_assert (__builtin_has_attribute (((C*)0)->m_a4_pa_0, packed)); +static_assert (__builtin_has_attribute (((C*)0)->m_a4_pa_0, aligned)); +static_assert (__alignof__ (((C*)0)->m_a4_pa_0) == 4); diff --git a/gcc/testsuite/gcc.dg/attr-copy-8.c b/gcc/testsuite/gcc.dg/attr-copy-8.c new file mode 100644 index 00000000000..c75d9e5c98c --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-copy-8.c @@ -0,0 +1,98 @@ +/* PR c/89685 - ICE on attribute copy with a compound expression + { dg-do compile } + { dg-options "-Wall -Wno-unused-value -Wno-int-to-pointer-cast" } */ + +#define ATTR(...) __attribute__ ((__VA_ARGS__)) + +typedef struct ATTR (packed) A { ATTR (packed) unsigned bf: 1; } A; + +typedef struct B +{ + struct A a; + struct A *pa; +} B; + +extern struct A a; +extern struct A *pa; +extern B b; +extern B ab[1]; +extern B *pb; + +typedef struct C +{ + ATTR (copy ((struct A *)0)) short m_pa_0; + ATTR (copy ((struct A *)(1, 0))) int m_pa_1_0; + ATTR (copy ((struct A *)(0, 1))) long m_pa_0_1; + + ATTR (copy (*(struct A *)0)) short m_xpa_0; + ATTR (copy (*(struct A *)(1, 0))) int m_xpa_1_0; + ATTR (copy (*(struct A *)(0, 1))) long m_xpa_0_1; + + ATTR (copy (((struct A *)0)[0])) short m_arpa_0; + ATTR (copy (((struct A *)(1, 0))[0])) int m_arpa_1_0; + ATTR (copy (((struct A *)(0, 1))[0])) long m_arpa_0_1; + + /* Also exercise COMPONENT_REF, ARRAY_REF, and INDIRECT_REF. */ + ATTR (copy (a)) short m_ra; + ATTR (copy (b.a)) int m_rb_a; + ATTR (copy (b.pa)) long m_rb_pa; + + ATTR (copy (&a)) short m_ara; + ATTR (copy (&b.a)) int m_arb_a; + ATTR (copy (*b.pa)) long m_xb_pa; + ATTR (copy (b.pa[0])) long m_arb_pa; + + ATTR (copy (*pa)) short m_xpa; + ATTR (copy (pa[0])) short m_arpa; + + ATTR (copy (ab[0].a)) int m_arab_a; + ATTR (copy (ab[1].pa)) long m_arab_pa; + ATTR (copy (*ab[2].pa)) int m_xarab_pa; + ATTR (copy (ab[3].pa->bf)) unsigned int m_arab_pa_bf: 1; + + ATTR (copy (pb->a)) int m_pb_a; + ATTR (copy (pb->pa)) long m_pb_pa; + ATTR (copy (*pb->pa)) int m_xpb_pa; + ATTR (copy (pb->pa->bf)) unsigned int m_pb_pa_bf: 1; + + ATTR (aligned (4), copy ((struct A *)(0))) short m_a4_pa_0; +} C; + + +_Static_assert (__builtin_has_attribute (((C*)0)->m_pa_0, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_pa_1_0, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_pa_0_1, packed)); + +_Static_assert (__builtin_has_attribute (((C*)0)->m_xpa_0, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_xpa_1_0, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_xpa_0_1, packed)); + +_Static_assert (__builtin_has_attribute (((C*)0)->m_arpa_0, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_arpa_1_0, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_arpa_0_1, packed)); + +_Static_assert (__builtin_has_attribute (((C*)0)->m_ra, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_rb_a, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_rb_pa, packed)); + +_Static_assert (__builtin_has_attribute (((C*)0)->m_ara, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_arb_a, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_xb_pa, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_arb_pa, packed)); + +_Static_assert (__builtin_has_attribute (((C*)0)->m_xpa, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_arpa, packed)); + +_Static_assert (__builtin_has_attribute (((C*)0)->m_arab_a, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_arab_pa, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_xarab_pa, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_arab_pa_bf, packed)); + +_Static_assert (__builtin_has_attribute (((C*)0)->m_pb_a, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_pb_pa, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_xpb_pa, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_pb_pa_bf, packed)); + +_Static_assert (__builtin_has_attribute (((C*)0)->m_a4_pa_0, packed)); +_Static_assert (__builtin_has_attribute (((C*)0)->m_a4_pa_0, aligned)); +_Static_assert (__alignof__ (((C*)0)->m_a4_pa_0) == 4);