diff options
author | Martin Sebor <msebor@redhat.com> | 2019-04-01 17:04:10 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2019-04-01 11:04:10 -0600 |
commit | ddeae8c8ac2681f5fb738f78df747782afa6ac15 (patch) | |
tree | 793b61eaa47bfc7ada1b66ad9c0e0e349f14c1ac /gcc/c-family/c-attribs.c | |
parent | 8bad0ced9fad845ef61bb3e27c38d004e0ab6d0f (diff) | |
download | gcc-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.c | 28 |
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)) |