aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-03-27 13:54:22 -0600
committerMartin Sebor <msebor@redhat.com>2020-03-27 13:54:22 -0600
commitccacf77be5508dd5b4df59f402965196d11edb05 (patch)
tree3075596dc7eefeb4b555b569ab76387f07eb17a5 /gcc/calls.c
parent038769535a8cbdd3dd3e100bde3140df52f868c5 (diff)
downloadgcc-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.c82
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);
+ }
}
}