This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C,C++] integer constants in attribute arguments
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 18 Jan 2014 23:33:31 +0100 (CET)
- Subject: Re: [C,C++] integer constants in attribute arguments
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot DEB dot 2 dot 02 dot 1311301103070 dot 10346 at stedding dot saclay dot inria dot fr> <52C5DD73 dot 2070305 at redhat dot com>
- Reply-to: gcc-patches at gcc dot gnu dot org
On Thu, 2 Jan 2014, Jason Merrill wrote:
On 11/30/2013 05:41 AM, Marc Glisse wrote:
for some reason one of the attributes can see a FUNCTION_DECL where others
see an IDENTIFIER_NODE, I didn't try to understand why and just added that
check to the code.
Please do check.
In the C front-end (at least), the grammar says:
attrib:
empty
any-word
any-word ( identifier )
any-word ( identifier , nonempty-expr-list )
any-word ( expr-list )
So when we have: __attribute__((nonnull(bar,bar)))
the parser will keep bar as an identifier for the first argument, but
parse the second one as an expr-list and thus find the associated
function_decl. So this can happen anytime an attribute has several
arguments, and I added the same check to nonnull that I had for alloc_size
(and fixed the argument numbering while I was there).
+ if (size && size != error_mark_node && TREE_CODE (size) !=
IDENTIFIER_NODE)
Why is the error_mark_node check needed here and not in the other places?
Don't know, I removed it for now. If it is needed, someone will eventually
provide a testcase in bugzilla.
Bootstrap and testsuite on x86_64-linux-gnu with
--enable-languages=c,c++,objc,obj-c++.
2014-01-19 Marc Glisse <marc.glisse@inria.fr>
PR c++/53017
PR c++/59211
gcc/c-family/
* c-common.c (handle_aligned_attribute, handle_alloc_size_attribute,
handle_vector_size_attribute, handle_nonnull_attribute): Call
default_conversion on the attribute argument.
(handle_nonnull_attribute): Increment the argument number.
gcc/cp/
* tree.c (handle_init_priority_attribute): Likewise.
gcc/
* doc/extend.texi (Function Attributes): Typo.
gcc/testsuite/
* c-c++-common/attributes-1.c: New testcase.
* g++.dg/cpp0x/constexpr-attribute2.C: Likewise.
--
Marc Glisse
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c (revision 206766)
+++ gcc/c-family/c-common.c (working copy)
@@ -7517,24 +7517,32 @@ check_cxx_fundamental_alignment_constrai
/* Handle a "aligned" attribute; arguments as in
struct attribute_spec.handler. */
static tree
handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
int flags, bool *no_add_attrs)
{
tree decl = NULL_TREE;
tree *type = NULL;
int is_type = 0;
- tree align_expr = (args ? TREE_VALUE (args)
- : size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT));
+ tree align_expr;
int i;
+ if (args)
+ {
+ align_expr = TREE_VALUE (args);
+ if (align_expr && TREE_CODE (align_expr) != IDENTIFIER_NODE)
+ align_expr = default_conversion (align_expr);
+ }
+ else
+ align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT);
+
if (DECL_P (*node))
{
decl = *node;
type = &TREE_TYPE (decl);
is_type = TREE_CODE (*node) == TYPE_DECL;
}
else if (TYPE_P (*node))
type = node, is_type = 1;
if ((i = check_user_alignment (align_expr, false)) == -1
@@ -8014,20 +8022,23 @@ handle_malloc_attribute (tree *node, tre
struct attribute_spec.handler. */
static tree
handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args,
int ARG_UNUSED (flags), bool *no_add_attrs)
{
unsigned arg_count = type_num_arguments (*node);
for (; args; args = TREE_CHAIN (args))
{
tree position = TREE_VALUE (args);
+ if (position && TREE_CODE (position) != IDENTIFIER_NODE
+ && TREE_CODE (position) != FUNCTION_DECL)
+ position = default_conversion (position);
if (TREE_CODE (position) != INTEGER_CST
|| TREE_INT_CST_HIGH (position)
|| TREE_INT_CST_LOW (position) < 1
|| TREE_INT_CST_LOW (position) > arg_count )
{
warning (OPT_Wattributes,
"alloc_size parameter outside range");
*no_add_attrs = true;
return NULL_TREE;
@@ -8458,20 +8469,22 @@ handle_vector_size_attribute (tree *node
int ARG_UNUSED (flags),
bool *no_add_attrs)
{
unsigned HOST_WIDE_INT vecsize, nunits;
enum machine_mode orig_mode;
tree type = *node, new_type, size;
*no_add_attrs = true;
size = TREE_VALUE (args);
+ if (size && TREE_CODE (size) != IDENTIFIER_NODE)
+ size = default_conversion (size);
if (!tree_fits_uhwi_p (size))
{
warning (OPT_Wattributes, "%qE attribute ignored", name);
return NULL_TREE;
}
/* Get the vector size (in bytes). */
vecsize = tree_to_uhwi (size);
@@ -8551,25 +8564,30 @@ handle_nonnull_attribute (tree *node, tr
if (!prototype_p (type))
{
error ("nonnull attribute without arguments on a non-prototype");
*no_add_attrs = true;
}
return NULL_TREE;
}
/* Argument list specified. Verify that each argument number references
a pointer argument. */
- for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
+ for (attr_arg_num = 1; args; attr_arg_num++, args = TREE_CHAIN (args))
{
unsigned HOST_WIDE_INT arg_num = 0, ck_num;
- if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
+ tree arg = TREE_VALUE (args);
+ if (arg && TREE_CODE (arg) != IDENTIFIER_NODE
+ && TREE_CODE (arg) != FUNCTION_DECL)
+ arg = default_conversion (arg);
+
+ if (!get_nonnull_operand (arg, &arg_num))
{
error ("nonnull argument has invalid operand number (argument %lu)",
(unsigned long) attr_arg_num);
*no_add_attrs = true;
return NULL_TREE;
}
if (prototype_p (type))
{
function_args_iterator iter;
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c (revision 206766)
+++ gcc/cp/tree.c (working copy)
@@ -3242,20 +3242,21 @@ handle_init_priority_attribute (tree* no
tree args,
int /*flags*/,
bool* no_add_attrs)
{
tree initp_expr = TREE_VALUE (args);
tree decl = *node;
tree type = TREE_TYPE (decl);
int pri;
STRIP_NOPS (initp_expr);
+ initp_expr = default_conversion (initp_expr);
if (!initp_expr || TREE_CODE (initp_expr) != INTEGER_CST)
{
error ("requested init_priority is not an integer constant");
*no_add_attrs = true;
return NULL_TREE;
}
pri = TREE_INT_CST_LOW (initp_expr);
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 206766)
+++ gcc/doc/extend.texi (working copy)
@@ -2234,21 +2234,21 @@ information to improve the correctness o
The function parameter(s) denoting the allocated size are specified by
one or two integer arguments supplied to the attribute. The allocated size
is either the value of the single function argument specified or the product
of the two function arguments specified. Argument numbering starts at
one.
For instance,
@smallexample
void* my_calloc(size_t, size_t) __attribute__((alloc_size(1,2)))
-void my_realloc(void*, size_t) __attribute__((alloc_size(2)))
+void* my_realloc(void*, size_t) __attribute__((alloc_size(2)))
@end smallexample
@noindent
declares that @code{my_calloc} returns memory of the size given by
the product of parameter 1 and 2 and that @code{my_realloc} returns memory
of the size given by parameter 2.
@item always_inline
@cindex @code{always_inline} function attribute
Generally, functions are not inlined unless optimization is specified.
Index: gcc/testsuite/c-c++-common/attributes-1.c
===================================================================
--- gcc/testsuite/c-c++-common/attributes-1.c (revision 0)
+++ gcc/testsuite/c-c++-common/attributes-1.c (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-prune-output "undeclared here \\(not in a function\\)|\[^\n\r\]* was not declared in this scope" } */
+
+void* my_calloc(unsigned, unsigned) __attribute__((alloc_size(1,bar))); /* { dg-warning "outside range" } */
+void* my_realloc(void*, unsigned) __attribute__((alloc_size(bar))); /* { dg-warning "outside range" } */
+
+typedef char vec __attribute__((vector_size(bar))); /* { dg-warning "ignored" } */
+
+void f1(char*) __attribute__((nonnull(bar))); /* { dg-error "invalid operand" } */
+void f2(char*) __attribute__((nonnull(1,bar))); /* { dg-error "invalid operand" } */
+
+void g() __attribute__((aligned(bar))); /* { dg-error "invalid value|not an integer" } */
+
+void foo(void);
+void* my_calloc(unsigned, unsigned) __attribute__((alloc_size(1,foo))); /* { dg-warning "outside range" } */
+void* my_realloc(void*, unsigned) __attribute__((alloc_size(foo))); /* { dg-warning "outside range" } */
+
+typedef char vec __attribute__((vector_size(foo))); /* { dg-warning "ignored" } */
+
+void f1(char*) __attribute__((nonnull(foo))); /* { dg-error "invalid operand" } */
+void f2(char*) __attribute__((nonnull(1,foo))); /* { dg-error "invalid operand" } */
+
+void g() __attribute__((aligned(foo))); /* { dg-error "invalid value|not an integer" } */
Property changes on: gcc/testsuite/c-c++-common/attributes-1.c
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision URL
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: gcc/testsuite/g++.dg/cpp0x/constexpr-attribute2.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/constexpr-attribute2.C (revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-attribute2.C (working copy)
@@ -0,0 +1,32 @@
+// { dg-options -std=gnu++11 }
+
+struct t { t(); };
+
+constexpr int prio = 123;
+constexpr int size = 8;
+constexpr int pos = 1;
+enum A { zero = 0, one, two };
+__attribute__((init_priority(prio))) t a;
+
+enum class E1 : int {
+ first = 101,
+ second,
+ third,
+};
+__attribute__((init_priority(E1::second))) t b; // Should not compile?
+
+enum E2 {
+ E2_first = 141,
+ E2_second,
+ E2_third,
+};
+__attribute__((init_priority(E2_second))) t c;
+
+void* my_calloc(unsigned, unsigned) __attribute__((alloc_size(pos,two)));
+void* my_realloc(void*, unsigned) __attribute__((alloc_size(two)));
+
+typedef char vec __attribute__((vector_size(size)));
+
+void f(char*) __attribute__((nonnull(pos)));
+
+void g() __attribute__((aligned(size)));
Property changes on: gcc/testsuite/g++.dg/cpp0x/constexpr-attribute2.C
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision URL
\ No newline at end of property