[Linux-kernel-mentees] [PATCH v2 06/25] parsing_c: parser: Add attribute production in spec_qualif_list
Jaskaran Singh
jaskaransingh7654321 at gmail.com
Thu May 28 12:24:08 UTC 2020
As per GCC's C grammar, the specifier-qualifier-list has the following
production:
specifier-qualifier-list:
gnu-attributes specifier-qualifier-list[opt]
Add this production to the spec_qualif_list rule of Coccinelle's C
parser. This parses attributes in struct fields and casts
successfully. Some code examples from Linux v5.5-rc4:
kernel/rcu/tree.h:
struct rcu_node {
...
raw_spinlock_t __private lock;
...
};
kernel/sysctl.c:
char __user **buffer = (char __user **)buf;
Signed-off-by: Jaskaran Singh <jaskaransingh7654321 at gmail.com>
---
parsing_c/parser_c.mly | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index e4352a61..be3fdbab 100644
--- a/parsing_c/parser_c.mly
+++ b/parsing_c/parser_c.mly
@@ -1500,10 +1500,12 @@ abstract_declaratorp:
/*(* for struct and also typename *)*/
/*(* can't put decl_spec cos no storage is allowed for field struct *)*/
spec_qualif_list2:
- | type_spec { addTypeD ($1, nullDecl) }
- | type_qualif { {nullDecl with qualifD = (fst $1,[snd $1])}}
- | type_spec spec_qualif_list { addTypeD ($1,$2) }
- | type_qualif spec_qualif_list { addQualifD ($1,$2) }
+ | type_spec { ([], addTypeD ($1, nullDecl)) }
+ | type_qualif { ([], {nullDecl with qualifD = (fst $1,[snd $1])})}
+ | attribute { ([$1], nullDecl) }
+ | type_spec spec_qualif_list { (fst $2, addTypeD ($1,snd $2)) }
+ | type_qualif spec_qualif_list { (fst $2, addQualifD ($1,snd $2)) }
+ | attribute spec_qualif_list { ([$1]@(fst $2), snd $2) }
spec_qualif_list: spec_qualif_list2 { dt "spec_qualif" (); $1 }
@@ -1521,9 +1523,12 @@ type_qualif_list:
type_name:
| spec_qualif_list
- { let (returnType, _) = fixDeclSpecForDecl $1 in returnType }
+ { let (attrs, ds) = $1 in
+ let (returnType, _) = fixDeclSpecForDecl ds in returnType }
| spec_qualif_list abstract_declaratort
- { let (returnType, _) = fixDeclSpecForDecl $1 in $2 returnType }
+ { let (attrs1, ds) = $1 in
+ let (returnType, _) = fixDeclSpecForDecl ds in
+ $2 returnType }
@@ -1808,7 +1813,8 @@ struct_decl2:
field_declaration:
| spec_qualif_list struct_declarator_list TPtVirg
{
- let (returnType,storage) = fixDeclSpecForDecl $1 in
+ let (attrs, ds) = $1 in
+ let (returnType,storage) = fixDeclSpecForDecl ds in
if fst (unwrap storage) <> NoSto
then internal_error "parsing don't allow this";
@@ -1823,8 +1829,9 @@ field_declaration:
| spec_qualif_list TPtVirg
{
+ let (attrs, ds) = $1 in
(* gccext: allow empty elements if it is a structdef or enumdef *)
- let (returnType,storage) = fixDeclSpecForDecl $1 in
+ let (returnType,storage) = fixDeclSpecForDecl ds in
if fst (unwrap storage) <> NoSto
then internal_error "parsing don't allow this";
--
2.21.1
More information about the Linux-kernel-mentees
mailing list