Commit ccacf77b by Martin Sebor

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.
parent 03876953
2020-03-27 Martin Sebor <msebor@redhat.com>
PR c++/94098
* calls.c (init_attr_rdwr_indices): Iterate over all access attributes.
2020-03-27 Andrew Stubbs <ams@codesourcery.com>
* config/gcn/gcn-valu.md:
......
2020-03-27 Martin Sebor <msebor@redhat.com>
PR c++/94098
* c-attribs.c (handle_access_attribute): Avoid setting TYPE_ATTRIBUTES
here.
2020-03-23 Jakub Jelinek <jakub@redhat.com>
PR c++/91993
......
......@@ -4182,7 +4182,6 @@ handle_access_attribute (tree *node, tree name, tree args,
/* Replace any existing access attribute specification with
the concatenation above. */
attrs = remove_attribute (IDENTIFIER_POINTER (name), attrs);
new_attrs = tree_cons (NULL_TREE, new_attrs, NULL_TREE);
new_attrs = tree_cons (name, new_attrs, attrs);
......@@ -4190,15 +4189,12 @@ handle_access_attribute (tree *node, tree name, tree args,
{
/* Repeat for the previously declared type. */
attrs = TYPE_ATTRIBUTES (TREE_TYPE (node[1]));
tree new_attrs
= append_access_attrs (node[1], attrs, attrstr, code, idxs);
if (!new_attrs)
tree attrs1 = append_access_attrs (node[1], attrs, attrstr, code, idxs);
if (!attrs1)
return NULL_TREE;
attrs = remove_attribute (IDENTIFIER_POINTER (name), attrs);
new_attrs = tree_cons (NULL_TREE, new_attrs, NULL_TREE);
new_attrs = tree_cons (name, new_attrs, attrs);
TYPE_ATTRIBUTES (TREE_TYPE (node[1])) = new_attrs;
attrs1 = tree_cons (NULL_TREE, attrs1, NULL_TREE);
new_attrs = tree_cons (name, attrs1, attrs);
}
/* Recursively call self to "replace" the documented/external form
......
......@@ -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);
}
}
}
......
2020-03-27 Martin Sebor <msebor@redhat.com>
PR c++/94098
* g++.dg/ext/attr-access-2.C: New test.
2020-03-27 Martin Sebor <msebor@redhat.com>
PR c++/94078
PR c++/93824
PR c++/93810
......
/* PR c++/94098 - checking ICE on attribute access redeclaration
{ dg-do compile }
{ dg-options "-Wall" } */
#define RO(...) __attribute__ ((access (read_only, __VA_ARGS__)))
#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
#define WO(...) __attribute__ ((access (write_only, __VA_ARGS__)))
typedef __INT32_TYPE__ int32_t;
int rdwr1_2_3_4 (void*, void*, void*, void*);
int RW (1) rdwr1_2_3_4 (void*, void*, void*, void*);
int RW (2) rdwr1_2_3_4 (void*, void*, void*, void*);
int RW (3) rdwr1_2_3_4 (void*, void*, void*, void*);
int RW (4) rdwr1_2_3_4 (void*, void*, void*, void*);
extern int32_t x[1];
void call_rdwrp1_2_3_4 (void)
{
rdwr1_2_3_4 (x, x, x, x);
rdwr1_2_3_4 (x, x, x, x + 1); // { dg-warning "\\\[-Wstringop-overflow" }
rdwr1_2_3_4 (x, x, x + 1, x); // { dg-warning "\\\[-Wstringop-overflow" }
rdwr1_2_3_4 (x, x + 1, x, x); // { dg-warning "\\\[-Wstringop-overflow" }
rdwr1_2_3_4 (x + 1, x, x, x); // { dg-warning "\\\[-Wstringop-overflow" }
}
int rdwr4_3_2_1 (void*, void*, void*, void*);
int RW (4) rdwr4_3_2_1 (void*, void*, void*, void*);
int RW (3) rdwr4_3_2_1 (void*, void*, void*, void*);
int RW (2) rdwr4_3_2_1 (void*, void*, void*, void*);
int RW (1) rdwr4_3_2_1 (void*, void*, void*, void*);
void call_rdwr4_3_2_1 (void)
{
rdwr4_3_2_1 (x, x, x, x);
rdwr4_3_2_1 (x, x, x, x + 1); // { dg-warning "\\\[-Wstringop-overflow" }
rdwr4_3_2_1 (x, x, x + 1, x); // { dg-warning "\\\[-Wstringop-overflow" }
rdwr4_3_2_1 (x, x + 1, x, x); // { dg-warning "\\\[-Wstringop-overflow" }
rdwr4_3_2_1 (x + 1, x, x, x); // { dg-warning "\\\[-Wstringop-overflow" }
}
int rdwrall (void*, void*, void*, void*);
int RW (1) rdwrall (void*, void*, void*, void*);
int RW (1) RW (2) rdwrall (void*, void*, void*, void*);
int RW (1) RW (2) RW (3) rdwrall (void*, void*, void*, void*);
int RW (1) RW (2) RW (3) RW (4) rdwrall (void*, void*, void*, void*);
void call_rdwrall (void)
{
rdwrall (x, x, x, x);
rdwrall (x, x, x, x + 1); // { dg-warning "\\\[-Wstringop-overflow" }
rdwrall (x, x, x + 1, x); // { dg-warning "\\\[-Wstringop-overflow" }
rdwrall (x, x + 1, x, x); // { dg-warning "\\\[-Wstringop-overflow" }
rdwrall (x + 1, x, x, x); // { dg-warning "\\\[-Wstringop-overflow" }
}
// Verify the attribute is a part of the function's type.
typedef __typeof__ (rdwrall) F;
void call_fnptr_typeof (F *f)
{
f (x, x, x, x);
f (x, x, x, x + 1); // { dg-warning "\\\[-Wstringop-overflow" }
f (x, x, x + 1, x); // { dg-warning "\\\[-Wstringop-overflow" }
f (x, x + 1, x, x); // { dg-warning "\\\[-Wstringop-overflow" }
f (x + 1, x, x, x); // { dg-warning "\\\[-Wstringop-overflow" }
}
// Verify the attribute is effective on a typedef.
typedef void FWRall (void*, void*, void*, void*);
typedef RW (1) void FWRall (void*, void*, void*, void*);
typedef RW (2) void FWRall (void*, void*, void*, void*);
typedef RW (3) void FWRall (void*, void*, void*, void*);
typedef RW (4) void FWRall (void*, void*, void*, void*);
void call_fnptr (FWRall *f)
{
f (x, x, x, x);
f (x, x, x, x + 1); // { dg-warning "\\\[-Wstringop-overflow" "pr94171" { xfail *-*-* } }
f (x, x, x + 1, x); // { dg-warning "\\\[-Wstringop-overflow" "pr94171" { xfail *-*-* } }
f (x, x + 1, x, x); // { dg-warning "\\\[-Wstringop-overflow" "pr94171" { xfail *-*-* } }
f (x + 1, x, x, x); // { dg-warning "\\\[-Wstringop-overflow" "pr94171" { xfail *-*-* } }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment