Skip to content

Commit 7e80927

Browse files
committed
c-family: add btf_type_tag and btf_decl_tag attributes
Add two new c-family attributes, "btf_type_tag" and "btf_decl_tag" along with attribute handlers for them. These attributes may be used to annotate types or declarations respectively with arbitrary strings, which will be recorded in DWARF and/or BTF information. Both attributes accept exactly one string argument. Wide strings are not supported. gcc/c-family/ * c-attribs.cc (c_common_attribute_table): Add btf_decl_tag and btf_type_tag attributes. (handle_btf_decl_tag_attribute): New handler for btf_decl_tag. (hanlde_btf_type_tag_attribute): New handler for btf_type_tag. (btf_tag_args_ok): Helper for new attribute handlers. gcc/testsuite/ * gcc.dg/attr-btf-decl-tag-1.c: New test. * gcc.dg/attr-btf-decl-tag-2.c: New test. * gcc.dg/attr-btf-type-tag-1.c: New test. * gcc.dg/attr-btf-type-tag-2.c: New test. * gcc.dg/attr-btf-type-tag-3.c: New test.
1 parent 4e44fe4 commit 7e80927

File tree

6 files changed

+167
-1
lines changed

6 files changed

+167
-1
lines changed

gcc/c-family/c-attribs.cc

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ static tree handle_fd_arg_attribute (tree *, tree, tree, int, bool *);
189189
static tree handle_flag_enum_attribute (tree *, tree, tree, int, bool *);
190190
static tree handle_null_terminated_string_arg_attribute (tree *, tree, tree, int, bool *);
191191

192+
static tree handle_btf_decl_tag_attribute (tree *, tree, tree, int, bool *);
193+
static tree handle_btf_type_tag_attribute (tree *, tree, tree, int, bool *);
194+
192195
/* Helper to define attribute exclusions. */
193196
#define ATTR_EXCL(name, function, type, variable) \
194197
{ name, function, type, variable }
@@ -657,7 +660,11 @@ const struct attribute_spec c_common_gnu_attributes[] =
657660
{ "flag_enum", 0, 0, false, true, false, false,
658661
handle_flag_enum_attribute, NULL },
659662
{ "null_terminated_string_arg", 1, 1, false, true, true, false,
660-
handle_null_terminated_string_arg_attribute, NULL}
663+
handle_null_terminated_string_arg_attribute, NULL},
664+
{ "btf_type_tag", 1, 1, false, true, false, false,
665+
handle_btf_type_tag_attribute, NULL},
666+
{ "btf_decl_tag", 1, 1, true, false, false, false,
667+
handle_btf_decl_tag_attribute, NULL}
661668
};
662669

663670
const struct scoped_attribute_specs c_common_gnu_attribute_table =
@@ -5172,6 +5179,107 @@ handle_null_terminated_string_arg_attribute (tree *node, tree name, tree args,
51725179
return NULL_TREE;
51735180
}
51745181

5182+
/* Common argument checking for btf_type_tag and btf_decl_tag.
5183+
Return true if the ARGS are valid, otherwise emit an error and
5184+
return false. */
5185+
5186+
static bool
5187+
btf_tag_args_ok (tree name, tree args)
5188+
{
5189+
if (!args) /* Correct number of args (1) is checked for us. */
5190+
return false;
5191+
else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
5192+
{
5193+
error ("%qE attribute requires a string argument", name);
5194+
return false;
5195+
}
5196+
5197+
/* Only narrow character strings are accepted. */
5198+
tree argtype = TREE_TYPE (TREE_TYPE (TREE_VALUE (args)));
5199+
if (!(argtype == char_type_node
5200+
|| argtype == char8_type_node
5201+
|| argtype == signed_char_type_node
5202+
|| argtype == unsigned_char_type_node))
5203+
{
5204+
error ("unsupported wide string type argument in %qE attribute", name);
5205+
return false;
5206+
}
5207+
5208+
return true;
5209+
}
5210+
5211+
/* Handle the "btf_decl_tag" attribute. */
5212+
5213+
static tree
5214+
handle_btf_decl_tag_attribute (tree * ARG_UNUSED (node), tree name, tree args,
5215+
int ARG_UNUSED (flags), bool *no_add_attrs)
5216+
{
5217+
if (!btf_tag_args_ok (name, args))
5218+
*no_add_attrs = true;
5219+
5220+
return NULL_TREE;
5221+
}
5222+
5223+
/* Handle the "btf_type_tag" attribute. */
5224+
5225+
static tree
5226+
handle_btf_type_tag_attribute (tree *node, tree name, tree args,
5227+
int flags, bool *no_add_attrs)
5228+
{
5229+
if (!btf_tag_args_ok (name, args))
5230+
{
5231+
*no_add_attrs = true;
5232+
return NULL_TREE;
5233+
}
5234+
5235+
if (TREE_CODE (*node) == FUNCTION_TYPE || TREE_CODE (*node) == METHOD_TYPE)
5236+
{
5237+
warning (OPT_Wattributes,
5238+
"%qE attribute does not apply to functions", name);
5239+
*no_add_attrs = true;
5240+
return NULL_TREE;
5241+
}
5242+
5243+
/* Ensure a variant type is always created to hold the type_tag,
5244+
unless ATTR_FLAG_IN_PLACE is set. Same logic as in
5245+
common_handle_aligned_attribute. */
5246+
tree decl = NULL_TREE;
5247+
tree *type = NULL;
5248+
bool is_type = false;
5249+
5250+
if (DECL_P (*node))
5251+
{
5252+
decl = *node;
5253+
type = &TREE_TYPE (decl);
5254+
is_type = TREE_CODE (*node) == TYPE_DECL;
5255+
}
5256+
else if (TYPE_P (*node))
5257+
type = node, is_type = true;
5258+
5259+
if (is_type)
5260+
{
5261+
if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
5262+
/* OK, modify the type in place. */;
5263+
5264+
/* If we have a TYPE_DECL, then copy the type, so that we
5265+
don't accidentally modify a builtin type. See pushdecl. */
5266+
else if (decl && TREE_TYPE (decl) != error_mark_node
5267+
&& DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
5268+
{
5269+
tree tt = TREE_TYPE (decl);
5270+
*type = build_variant_type_copy (*type);
5271+
DECL_ORIGINAL_TYPE (decl) = tt;
5272+
TYPE_NAME (*type) = decl;
5273+
TREE_USED (*type) = TREE_USED (decl);
5274+
TREE_TYPE (decl) = *type;
5275+
}
5276+
else
5277+
*type = build_variant_type_copy (*type);
5278+
}
5279+
5280+
return NULL_TREE;
5281+
}
5282+
51755283
/* Handle the "nonstring" variable attribute. */
51765284

51775285
static tree
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* Test btf_decl_tag attribute argument checking. */
2+
/* { dg-do compile } */
3+
4+
void *vptr __attribute__((btf_decl_tag("vptr"), btf_decl_tag ("perthread")));
5+
6+
struct Foo
7+
{
8+
int x __attribute__((btf_decl_tag (0x55))); /* { dg-error "requires a string" } */
9+
char *c __attribute__((btf_decl_tag (L"Lstr"))); /* { dg-error "unsupported wide string" } */
10+
};
11+
12+
extern int foo (int x, int y __attribute__((btf_decl_tag))); /* { dg-error "wrong number of arguments" } */
13+
14+
char *str __attribute__((btf_decl_tag("A", "B"))); /* { dg-error "wrong number of arguments" } */
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* Test btf_decl_tag attribute argument checking for wide string types. */
2+
/* { dg-do compile } */
3+
/* { dg-options "--std=c11" } */
4+
5+
int **my_ptr __attribute__((btf_decl_tag("my_ptr")));
6+
7+
void *x __attribute__((btf_decl_tag (U"Ustr"))); /* { dg-error "unsupported wide string" } */
8+
9+
const int y __attribute__((btf_decl_tag (u"ustr"))); /* { dg-error "unsupported wide string" } */
10+
11+
union U
12+
{
13+
int x;
14+
char c __attribute__((btf_decl_tag (u8"u8str"))); /* OK. */
15+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* Test btf_type_tag attribute argument checking. */
2+
/* { dg-do compile } */
3+
4+
void * __attribute__((btf_type_tag ("A"), btf_type_tag ("vptr"))) a;
5+
6+
int __attribute__((btf_type_tag (5))) b; /* { dg-error "requires a string" } */
7+
8+
char * __attribute__((btf_type_tag (L"Lstr"))) c; /* { dg-error "unsupported wide string" } */
9+
10+
int * __attribute__((btf_type_tag)) d; /* { dg-error "wrong number of arguments" } */
11+
12+
char * __attribute__((btf_type_tag ("A", "B"))) e; /* { dg-error "wrong number of arguments" } */
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* Test btf_type_tag attribute argument checking for wide string types. */
2+
/* { dg-do compile } */
3+
/* { dg-options "--std=c11" } */
4+
5+
int __attribute__((btf_type_tag (U"Ustr"))) x; /* { dg-error "unsupported wide string" } */
6+
7+
int __attribute__((btf_type_tag (u"ustr"))) y; /* { dg-error "unsupported wide string" } */
8+
9+
int __attribute__((btf_type_tag (u8"u8str"))) z; /* OK. */
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* Test btf_type_tag attribute warnings. */
2+
/* { dg-do compile } */
3+
4+
int __attribute__((btf_type_tag ("A"))) a (int x); /* { dg-warning "does not apply to functions" } */
5+
6+
__attribute__((btf_type_tag ("B"))) int *b (int y); /* { dg-warning "does not apply to functions" } */
7+
8+
int *c (int z) __attribute__((btf_type_tag ("C"))); /* { dg-warning "does not apply to functions" } */

0 commit comments

Comments
 (0)