aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-attribs.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-04-01 17:04:10 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-04-01 11:04:10 -0600
commitddeae8c8ac2681f5fb738f78df747782afa6ac15 (patch)
tree793b61eaa47bfc7ada1b66ad9c0e0e349f14c1ac /gcc/c-family/c-attribs.c
parent8bad0ced9fad845ef61bb3e27c38d004e0ab6d0f (diff)
downloadgcc-ddeae8c8ac2681f5fb738f78df747782afa6ac15.zip
gcc-ddeae8c8ac2681f5fb738f78df747782afa6ac15.tar.gz
gcc-ddeae8c8ac2681f5fb738f78df747782afa6ac15.tar.bz2
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
Diffstat (limited to 'gcc/c-family/c-attribs.c')
-rw-r--r--gcc/c-family/c-attribs.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index e559d3b..d055a08 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))