Commit 52f24a9e by Martin Sebor

PR c++/94346 - [9/10 Regression] ICE due to handle_copy_attribute since r9-3982

gcc/c-family/ChangeLog:

	PR c++/94346
	* c-attribs.c (handle_copy_attribute): Avoid passing expressions
	to decl_attributes.  Make handling of different kinds of entities
	more robust.

gcc/c-c++-common/ChangeLog:

	PR c++/94346
	* c-c++-common/attr-copy.c: New test.
parent c7fc15f5
2020-03-27 Martin Sebor <msebor@redhat.com> 2020-03-27 Martin Sebor <msebor@redhat.com>
PR c++/94346
* c-attribs.c (handle_copy_attribute): Avoid passing expressions
to decl_attributes. Make handling of different kinds of entities
more robust.
2020-03-27 Martin Sebor <msebor@redhat.com>
PR c++/94098 PR c++/94098
* c-attribs.c (handle_access_attribute): Avoid setting TYPE_ATTRIBUTES * c-attribs.c (handle_access_attribute): Avoid setting TYPE_ATTRIBUTES
here. here.
......
...@@ -2526,17 +2526,21 @@ handle_copy_attribute (tree *node, tree name, tree args, ...@@ -2526,17 +2526,21 @@ handle_copy_attribute (tree *node, tree name, tree args,
&& !FUNCTION_POINTER_TYPE_P (TREE_TYPE (ref))) && !FUNCTION_POINTER_TYPE_P (TREE_TYPE (ref)))
ref = TREE_TYPE (ref); ref = TREE_TYPE (ref);
tree reftype = TYPE_P (ref) ? ref : TREE_TYPE (ref);
if (DECL_P (decl)) if (DECL_P (decl))
{ {
if ((VAR_P (decl) if ((VAR_P (decl)
&& (TREE_CODE (ref) == FUNCTION_DECL && (TREE_CODE (ref) == FUNCTION_DECL
|| (EXPR_P (ref) || (EXPR_P (ref)
&& POINTER_TYPE_P (TREE_TYPE (ref)) && POINTER_TYPE_P (reftype)
&& FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (ref)))))) && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))))
|| (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == FUNCTION_DECL
&& (VAR_P (ref) && (VAR_P (ref)
|| (EXPR_P (ref) || (EXPR_P (ref)
&& !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (ref)))))) && !FUNC_OR_METHOD_TYPE_P (reftype)
&& (!POINTER_TYPE_P (reftype)
|| !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))))))
{ {
/* It makes no sense to try to copy function attributes /* It makes no sense to try to copy function attributes
to a variable, or variable attributes to a function. */ to a variable, or variable attributes to a function. */
...@@ -2586,7 +2590,7 @@ handle_copy_attribute (tree *node, tree name, tree args, ...@@ -2586,7 +2590,7 @@ handle_copy_attribute (tree *node, tree name, tree args,
/* Create a copy of just the one attribute ar AT, including /* Create a copy of just the one attribute ar AT, including
its argumentsm and add it to DECL. */ its argumentsm and add it to DECL. */
tree attr = tree_cons (atname, copy_list (atargs), NULL_TREE); tree attr = tree_cons (atname, copy_list (atargs), NULL_TREE);
decl_attributes (node, attr, flags, ref); decl_attributes (node, attr, flags, EXPR_P (ref) ? NULL_TREE : ref);
} }
/* Proceed to copy type attributes below. */ /* Proceed to copy type attributes below. */
...@@ -2606,15 +2610,11 @@ handle_copy_attribute (tree *node, tree name, tree args, ...@@ -2606,15 +2610,11 @@ handle_copy_attribute (tree *node, tree name, tree args,
/* Similarly, a function declared with attribute noreturn has it /* Similarly, a function declared with attribute noreturn has it
attached on to it, but a C11 _Noreturn function does not. */ attached on to it, but a C11 _Noreturn function does not. */
tree reftype = ref;
if (DECL_P (ref) if (DECL_P (ref)
&& TREE_THIS_VOLATILE (ref) && TREE_THIS_VOLATILE (ref)
&& FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype))) && FUNC_OR_METHOD_TYPE_P (reftype))
TREE_THIS_VOLATILE (decl) = true; TREE_THIS_VOLATILE (decl) = true;
if (DECL_P (ref) || EXPR_P (ref))
reftype = TREE_TYPE (ref);
if (POINTER_TYPE_P (reftype)) if (POINTER_TYPE_P (reftype))
reftype = TREE_TYPE (reftype); reftype = TREE_TYPE (reftype);
...@@ -2623,9 +2623,10 @@ handle_copy_attribute (tree *node, tree name, tree args, ...@@ -2623,9 +2623,10 @@ handle_copy_attribute (tree *node, tree name, tree args,
tree attrs = TYPE_ATTRIBUTES (reftype); tree attrs = TYPE_ATTRIBUTES (reftype);
/* Copy type attributes from REF to DECL. */ /* Copy type attributes from REF to DECL. Pass in REF if it's a DECL
or a type but not if it's an expression. */
for (tree at = attrs; at; at = TREE_CHAIN (at)) for (tree at = attrs; at; at = TREE_CHAIN (at))
decl_attributes (node, at, flags, ref); decl_attributes (node, at, flags, EXPR_P (ref) ? NULL_TREE : ref);
return NULL_TREE; return NULL_TREE;
} }
......
2020-03-27 Martin Sebor <msebor@redhat.com> 2020-03-27 Martin Sebor <msebor@redhat.com>
PR c++/94346
* c-c++-common/attr-copy.c: New test.
2020-03-27 Martin Sebor <msebor@redhat.com>
PR c++/94098 PR c++/94098
* g++.dg/ext/attr-access-2.C: New test. * g++.dg/ext/attr-access-2.C: New test.
......
/* PR c++/94346 - ICE due to handle_copy_attribute
{ dg-do compile }
{ dg-options "-Wall" } */
#define ATTR(...) __attribute__ ((__VA_ARGS__))
#if __cplusplus > 199711L
# define SA(expr) static_assert (expr, #expr)
#elif __cplusplus
# define SA(expr) \
typedef __attribute__ ((unused)) char Assert[!(expr) ? -1 : 1]
#else
# define SA(expr) _Static_assert (expr, #expr)
#endif
typedef struct ATTR (packed) A { ATTR (packed) unsigned bf: 1; } A;
int bar (void);
struct C
{
char c;
ATTR (copy ((bar (), ((struct A *)(0))[0]))) int i;
};
/* Verify the attribute has been copied. */
SA (__builtin_offsetof (struct C, i) == 1);
/* Verify attribute copy can copy from the type a comma expression. */
ATTR (alloc_size (1)) void* alloc1 (int);
ATTR (copy ((bar (), alloc1))) void* alloc2 (int, int);
ATTR (copy ((bar (), alloc1))) void alloc3 (int); /* { dg-warning "'alloc_size' attribute ignored on a function returning 'void'" } */
typedef ATTR (alloc_size (1)) void* F (int);
ATTR (copy ((bar (), (F*)0))) void* alloc4 (int, int);
ATTR (copy ((bar (), (F*)0))) void alloc5 (int, int); /* { dg-warning "'alloc_size' attribute ignored on a function returning 'void'" } */
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