diff options
author | Martin Sebor <msebor@redhat.com> | 2020-03-27 13:54:22 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2020-03-27 13:54:22 -0600 |
commit | ccacf77be5508dd5b4df59f402965196d11edb05 (patch) | |
tree | 3075596dc7eefeb4b555b569ab76387f07eb17a5 /gcc/calls.c | |
parent | 038769535a8cbdd3dd3e100bde3140df52f868c5 (diff) | |
download | gcc-ccacf77be5508dd5b4df59f402965196d11edb05.zip gcc-ccacf77be5508dd5b4df59f402965196d11edb05.tar.gz gcc-ccacf77be5508dd5b4df59f402965196d11edb05.tar.bz2 |
PR c++/94098 - ICE on attribute access redeclaration
gcc/c-family/ChangeLog:
PR c++/94098
* c-attribs.c (handle_access_attribute): Avoid setting TYPE_ATTRIBUTES
here.
gcc/ChangeLog:
PR c++/94098
* calls.c (init_attr_rdwr_indices): Iterate over all access attributes.
gcc/testsuite/ChangeLog:
PR c++/94098
* g++.dg/ext/attr-access-2.C: New test.
Diffstat (limited to 'gcc/calls.c')
-rw-r--r-- | gcc/calls.c | 82 |
1 files changed, 39 insertions, 43 deletions
diff --git a/gcc/calls.c b/gcc/calls.c index 4c3a8f3..5bd9227 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1873,7 +1873,7 @@ struct rdwr_access_hash: int_hash<int, -1> { }; typedef hash_map<rdwr_access_hash, attr_access> rdwr_map; /* Initialize a mapping for a call to function FNDECL declared with - attribute access. Each attribute poisitional operand inserts one + attribute access. Each attribute positional operand inserts one entry into the mapping with the operand number as the key. */ static void @@ -1882,54 +1882,50 @@ init_attr_rdwr_indices (rdwr_map *rwm, tree fntype) if (!fntype) return; - tree access = TYPE_ATTRIBUTES (fntype); - /* If the function's type has no attributes there's nothing to do. */ - if (!access) - return; - - access = lookup_attribute ("access", access); - if (!access) - return; - - /* The TREE_VALUE of an attribute is a TREE_LIST whose TREE_VALUE - is the attribute argument's value. */ - tree mode = TREE_VALUE (access); - gcc_assert (TREE_CODE (mode) == TREE_LIST); - mode = TREE_VALUE (mode); - gcc_assert (TREE_CODE (mode) == STRING_CST); - - const char *modestr = TREE_STRING_POINTER (mode); - for (const char *m = modestr; *m; ) + for (tree access = TYPE_ATTRIBUTES (fntype); + (access = lookup_attribute ("access", access)); + access = TREE_CHAIN (access)) { - attr_access acc = { }; - - switch (*m) + /* The TREE_VALUE of an attribute is a TREE_LIST whose TREE_VALUE + is the attribute argument's value. */ + tree mode = TREE_VALUE (access); + gcc_assert (TREE_CODE (mode) == TREE_LIST); + mode = TREE_VALUE (mode); + gcc_assert (TREE_CODE (mode) == STRING_CST); + + const char *modestr = TREE_STRING_POINTER (mode); + for (const char *m = modestr; *m; ) { - case 'r': acc.mode = acc.read_only; break; - case 'w': acc.mode = acc.write_only; break; - default: acc.mode = acc.read_write; break; - } + attr_access acc = { }; - char *end; - acc.ptrarg = strtoul (++m, &end, 10); - m = end; - if (*m == ',') - { - acc.sizarg = strtoul (++m, &end, 10); + switch (*m) + { + case 'r': acc.mode = acc.read_only; break; + case 'w': acc.mode = acc.write_only; break; + default: acc.mode = acc.read_write; break; + } + + char *end; + acc.ptrarg = strtoul (++m, &end, 10); m = end; - } - else - acc.sizarg = UINT_MAX; + if (*m == ',') + { + acc.sizarg = strtoul (++m, &end, 10); + m = end; + } + else + acc.sizarg = UINT_MAX; - acc.ptr = NULL_TREE; - acc.size = NULL_TREE; + acc.ptr = NULL_TREE; + acc.size = NULL_TREE; - /* Unconditionally add an entry for the required pointer - operand of the attribute, and one for the optional size - operand when it's specified. */ - rwm->put (acc.ptrarg, acc); - if (acc.sizarg != UINT_MAX) - rwm->put (acc.sizarg, acc); + /* Unconditionally add an entry for the required pointer + operand of the attribute, and one for the optional size + operand when it's specified. */ + rwm->put (acc.ptrarg, acc); + if (acc.sizarg != UINT_MAX) + rwm->put (acc.sizarg, acc); + } } } |