Re: [Cocci] [RFC PATCH 23/25] parsing_c: type_c: Add parameter attributes to record

2020-04-24 Thread Markus Elfring
> Paramter attributes are added to the C AST.

Please avoid a typo in the first word for this change description.

Regards,
Markus
___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


Re: [Cocci] [RFC PATCH 17/25] engine: cocci_vs_c: Add allminus argument to attribute_list

2020-04-24 Thread Markus Elfring
> This also makes sure that the test case unstruct does not break when
> attributes are identified correctly by the C parser.

Would the wording “are correctly identified” be more appropriate?

Regards,
Markus
___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


Re: [Cocci] [RFC PATCH 12/25] parsing_c: cpp_token_c: Introduce MACROANNOTATION hint

2020-04-24 Thread Markus Elfring
> A better way of denoting attributes is to pass attribute information
> from SmPL to the C parser.

Such information sounds promising.


> However, a temporary solution is to introduce a MACROANNOTATION hint
> to cpp_token_c.ml so that the parser can identify attributes easily.

Have you got any development ideas which would not need the introduction
of “temporary” approaches?


> This hint can be used as follows in standard.h, the user provided
> macro-defs file or the given C file itself:
>
>   #define __attribute_name MACROANNOTATION

Can it make sense to work with a function-like macro at such places?

#define USE_ANNOTATION(info) info ITEM_ANNOTATION

Regards,
Markus
___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


Re: [Cocci] [RFC PATCH 00/25] cocci: Improve C parsing of attributes

2020-04-24 Thread Markus Elfring
> This patch series aims to improve parsing of attributes in C by
> Coccinelle's C parser.

How do you think about to use the wording “in C source code by”?


> These parsing errors were discovered by running a build of Coccinelle's

Would you like to omit the word “These”?


> Coccinelle currently manages attributes similar to comments,

Will this aspect trigger further software development considerations?


> so to explicity state what the attributes are to the C parser,
> a MACROANNOTATION hint was used in Coccinelle's standard.h file.

I find such information suspicious at first glance.
Additional background information from an update step like
“[RFC PATCH 12/25] parsing_c: cpp_token_c: Introduce MACROANNOTATION hint”
might make the proposed data processing approach more reasonable.
https://lore.kernel.org/cocci/20200424091801.13871-13-jaskaransingh7654...@gmail.com/
https://systeme.lip6.fr/pipermail/cocci/2020-April/007217.html


> Separate patches will be sent for the above.

I am curious how the software evolution will be continued here.

Regards,
Markus
___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 17/25] engine: cocci_vs_c: Add allminus argument to attribute_list

2020-04-24 Thread Jaskaran Singh
The allminus argument is used to denote when attributes should be
removed. This is with respect to the given SmPL program.

Add the allminus argument to attribute_list, and pass it correctly in
places where attribute_list is used.

This also makes sure that the test case unstruct does not break when
attributes are identified correctly by the C parser.

Signed-off-by: Jaskaran Singh 
---
 engine/cocci_vs_c.ml | 32 ++--
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/engine/cocci_vs_c.ml b/engine/cocci_vs_c.ml
index e383aef8..413ea220 100644
--- a/engine/cocci_vs_c.ml
+++ b/engine/cocci_vs_c.ml
@@ -2563,7 +2563,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, 
iistob) ->
ident_cpp DontKnow ida nameidb >>= (fun ida nameidb ->
tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
fullType typa typb >>= (fun typa typb ->
-   attribute_list attrsa endattrs >>= (fun attrsa endattrs ->
+   attribute_list allminus attrsa endattrs >>= (fun attrsa endattrs ->
storage_optional_allminus allminus stoa (stob, iistob) >>=
 (fun stoa (stob, iistob) ->
  return (
@@ -2592,7 +2592,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, 
iistob) ->
tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
tokenf eqa iieqb >>= (fun eqa iieqb ->
fullType typa typb >>= (fun typa typb ->
-   attribute_list attrsa endattrs >>= (fun attrsa endattrs ->
+   attribute_list allminus attrsa endattrs >>= (fun attrsa endattrs ->
storage_optional_allminus allminus stoa (stob, iistob) >>=
(fun stoa (stob, iistob) ->
initialiser inia inib >>= (fun inia inib ->
@@ -2651,7 +2651,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, 
iistob) ->
   inla (stob, iistob) >>= (fun inla (stob, iistob) ->
 storage_optional_allminus allminus
   stoa (stob, iistob) >>= (fun stoa (stob, iistob) ->
-attribute_list attras attrs >>= (fun attras attrs ->
+attribute_list allminus attras attrs >>= (fun attras attrs ->
 fullType_optional_allminus allminus tya tyb >>= (fun tya tyb ->
let fninfoa = put_fninfo stoa tya inla attras in
 parameters (seqstyle paramsa) (A.unwrap paramsa) paramsb >>=
@@ -4194,29 +4194,41 @@ and attribute_list attras attrbs =
 
 (* The cheap hackish version.  No wrapping requires... *)
 
-and attribute_list attras attrbs =
+and attribute_list allminus attras attrbs =
   X.optional_attributes_flag (fun optional_attributes ->
   match attras,attrbs with
 [], _ when optional_attributes || attrbs = [] ->
-  return ([], attrbs)
+  if allminus
+  then
+let rec loop = function
+[] -> return ([],[])
+  | ib::ibs ->
+  X.distrf_attr minusizer ib >>= (fun _ ib ->
+  loop ibs >>= (fun l ibs ->
+return([],ib::ibs))) in
+loop attrbs
+  else return ([], attrbs)
   | [], _ -> fail
   | [attra], [attrb] ->
-attribute attra attrb >>= (fun attra attrb ->
+attribute allminus attra attrb >>= (fun attra attrb ->
   return ([attra], [attrb])
 )
   | [attra], attrb -> fail
   | _ -> failwith "only one attribute allowed in SmPL")
 
-and attribute = fun ea eb ->
+and attribute = fun allminus ea eb ->
   match ea, eb with
 attra, (B.Attribute attrb, ii)
   when (A.unwrap_mcode attra) = attrb ->
   let ib1 = tuple_of_list1 ii in
   tokenf attra ib1 >>= (fun attra ib1 ->
+   (if allminus
+then minusize_list [ib1]
+else return ((), [ib1])) >>= (fun _ ib1 ->
return (
  attra,
- (B.Attribute attrb, [ib1])
-))
+  (B.Attribute attrb,ib1)
+)))
   | _ -> fail
 
 (*---*)
@@ -4927,7 +4939,7 @@ let rec (rule_elem_node: (A.rule_elem, F.node) matcher) =
 inla (stob, iistob) >>= (fun inla (stob, iistob) ->
   storage_optional_allminus allminus
 stoa (stob, iistob) >>= (fun stoa (stob, iistob) ->
-  attribute_list attras attrs >>= (fun attras attrs ->
+  attribute_list allminus attras attrs >>= (fun attras attrs ->
   (
 if isvaargs
 then
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 18/25] parsing_c: parser: Make abstract_declarator pass attributes

2020-04-24 Thread Jaskaran Singh
The attributes in abstract_declarator can be used for adding parameter
attributes, cast attributes and others to the C AST. Make
abstract_declarator pass these attributes in a tuple.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parser_c.mly | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index da6b9c7b..0c3da206 100644
--- a/parsing_c/parser_c.mly
+++ b/parsing_c/parser_c.mly
@@ -1397,13 +1397,14 @@ tccro: TCCro { dt "tccro" ();$1 }
 
 /*(*---*)*/
 abstract_declarator:
- | pointer{ snd $1 }
- | direct_abstract_declarator { $1 }
- | pointer direct_abstract_declarator { fun x -> x +> $2 +> (snd $1) }
+ | pointer{ $1 }
+ | direct_abstract_declarator { ([], $1) }
+ | pointer direct_abstract_declarator
+ { (fst $1, fun x -> x +> $2 +> (snd $1)) }
 
 direct_abstract_declarator:
  | TOPar abstract_declarator TCPar /*(* forunparser: old: $2 *)*/
- { fun x -> mk_ty (ParenType ($2 x)) [$1;$3] }
+ { fun x -> mk_ty (ParenType ((snd $2) x)) [$1;$3] }
 
  | TOCroTCCro
  { fun x -> mk_ty (Array (None, x)) [$1;$2] }
@@ -1461,7 +1462,7 @@ parameter_decl2:
  { LP.kr_impossible();
let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam (snd $1) in
{ p_namei = None;
- p_type = $2 returnType;
+ p_type = (snd $2) returnType;
  p_register = hasreg, iihasreg;
}
  }
@@ -2118,7 +2119,7 @@ define_val:
  }
  | decl_spec abstract_declarator
  { let returnType = fixDeclSpecForMacro (snd $1) in
-   let typ = $2 returnType in
+   let typ = (snd $2) returnType in
DefineType typ
  }
 
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 16/25] engine: Add distrf_attr to PARAM functor

2020-04-24 Thread Jaskaran Singh
distrf_attr can be used to match a single attribute at a time. Add this
matcher function to the PARAM functor.

Signed-off-by: Jaskaran Singh 
---
 engine/cocci_vs_c.ml   | 3 +++
 engine/cocci_vs_c.mli  | 3 +++
 engine/pattern_c.ml| 1 +
 engine/transformation_c.ml | 5 +
 4 files changed, 12 insertions(+)

diff --git a/engine/cocci_vs_c.ml b/engine/cocci_vs_c.ml
index 2a3c3f94..e383aef8 100644
--- a/engine/cocci_vs_c.ml
+++ b/engine/cocci_vs_c.ml
@@ -700,6 +700,9 @@ module type PARAM =
 val distrf_exec_code_list :
   (A.meta_name A.mcode, (Ast_c.exec_code, Ast_c.il) either list) matcher
 
+val distrf_attr :
+  (A.meta_name A.mcode, Ast_c.attribute) matcher
+
 val distrf_attrs :
   (A.meta_name A.mcode, (Ast_c.attribute, Ast_c.il) either list) matcher
 
diff --git a/engine/cocci_vs_c.mli b/engine/cocci_vs_c.mli
index ef55d478..70354e19 100644
--- a/engine/cocci_vs_c.mli
+++ b/engine/cocci_vs_c.mli
@@ -162,6 +162,9 @@ module type PARAM =
   (Ast_cocci.meta_name Ast_cocci.mcode,
(Ast_c.exec_code, Ast_c.il) Common.either list) matcher
 
+val distrf_attr :
+  (Ast_cocci.meta_name Ast_cocci.mcode, Ast_c.attribute) matcher
+
 val distrf_attrs :
   (Ast_cocci.meta_name Ast_cocci.mcode,
(Ast_c.attribute, Ast_c.il) Common.either list) matcher
diff --git a/engine/pattern_c.ml b/engine/pattern_c.ml
index 7b1d0c0a..e6796368 100644
--- a/engine/pattern_c.ml
+++ b/engine/pattern_c.ml
@@ -335,6 +335,7 @@ module XMATCH = struct
   let distrf_define_params  = distrf Lib_parsing_c.ii_of_define_params
   let distrf_ident_list = distrf Lib_parsing_c.ii_of_ident_list
   let distrf_exec_code_list = distrf Lib_parsing_c.ii_of_exec_code_list
+  let distrf_attr   = distrf Lib_parsing_c.ii_of_attr
   let distrf_attrs  = distrf Lib_parsing_c.ii_of_attrs
 
 
diff --git a/engine/transformation_c.ml b/engine/transformation_c.ml
index 4de8fe51..eecd4858 100644
--- a/engine/transformation_c.ml
+++ b/engine/transformation_c.ml
@@ -621,6 +621,9 @@ module XTRANS = struct
   let distribute_mck_ini (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
 Visitor_c.vk_ini_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
 
+  let distribute_mck_attr (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
+Visitor_c.vk_attribute_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
+
   let distribute_mck_inis (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
 Visitor_c.vk_inis_splitted_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
 
@@ -750,6 +753,8 @@ module XTRANS = struct
 distrf (Lib_parsing_c.ii_of_ident_list,distribute_mck_ident_list)
   let distrf_exec_code_list =
 distrf (Lib_parsing_c.ii_of_exec_code_list,distribute_mck_exec_code_list)
+  let distrf_attr =
+distrf (Lib_parsing_c.ii_of_attr,distribute_mck_attr)
   let distrf_attrs =
 distrf (Lib_parsing_c.ii_of_attrs,distribute_mck_attrs)
 
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 23/25] parsing_c: type_c: Add parameter attributes to record

2020-04-24 Thread Jaskaran Singh
Paramter attributes are added to the C AST. Reflect this change in a
case in type_c.ml.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/type_c.ml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/parsing_c/type_c.ml b/parsing_c/type_c.ml
index 4a85b683..617b6fc6 100644
--- a/parsing_c/type_c.ml
+++ b/parsing_c/type_c.ml
@@ -304,6 +304,7 @@ let (fake_function_type:
 { Ast_c.p_namei = None;
   p_register = false, Ast_c.noii;
   p_type = ft;
+  p_attr = [];
 }
   in
   Some (paramtype, ii)
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 14/25] parsing_c: visitor_c: Add vk_attribute and vk_attribute_s

2020-04-24 Thread Jaskaran Singh
vk_attribute and vk_attribute_s were not declared in visitor_c.mli.
Declare these functions in visitor_c.mli to use these outside of
visitor_c.ml.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/visitor_c.mli | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/parsing_c/visitor_c.mli b/parsing_c/visitor_c.mli
index 1a76b87c..85551fca 100644
--- a/parsing_c/visitor_c.mli
+++ b/parsing_c/visitor_c.mli
@@ -86,6 +86,7 @@ val vk_ident_list_splitted : visitor_c -> (name, il) 
Common.either list -> unit
 
 val vk_exec_code_list_splitted :
 visitor_c -> (exec_code, il) Common.either list -> unit
+val vk_attribute   : visitor_c -> attribute -> unit
 val vk_attrs_splitted :
 visitor_c -> (attribute, il) Common.either list -> unit
 
@@ -205,6 +206,8 @@ val vk_exec_code_list_splitted_s :
 visitor_c_s ->
   (exec_code, il) Common.either list ->
(exec_code, il) Common.either list
+
+val vk_attribute_s : visitor_c_s -> attribute -> attribute
 val vk_attrs_splitted_s :
 visitor_c_s ->
   (attribute, il) Common.either list ->
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 21/25] parsing_c: visitor_c: Visit parameter attributes

2020-04-24 Thread Jaskaran Singh
As attributes are added to the parameter type, have the C AST visitor
visit these attributes as well.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/visitor_c.ml | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/parsing_c/visitor_c.ml b/parsing_c/visitor_c.ml
index aaef1acc..57b5f32b 100644
--- a/parsing_c/visitor_c.ml
+++ b/parsing_c/visitor_c.ml
@@ -1929,10 +1929,15 @@ and vk_node_s = fun bigf node ->
 (*  *)
 and vk_param_s = fun bigf param ->
   let iif ii = vk_ii_s bigf ii in
-  let {p_namei = swrapopt; p_register = (b, iib); p_type=ft} = param in
+  let
+{p_namei = swrapopt;
+ p_register = (b, iib);
+ p_type=ft;
+ p_attr = attrs} = param in
   { p_namei = swrapopt +> Common.map_option (vk_name_s bigf);
 p_register = (b, iif iib);
 p_type = vk_type_s bigf ft;
+p_attr = attrs +> List.map (vk_attribute_s bigf);
   }
 
 let vk_arguments_s = fun bigf args ->
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 20/25] parsing_c: parser: Place parameter attributes in C AST

2020-04-24 Thread Jaskaran Singh
Parameter attributes are needed so as to not break the nocast test case
when attributes are fully supported. Add parameter attributes to the C
AST.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parser_c.mly | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index 0c3da206..aedde179 100644
--- a/parsing_c/parser_c.mly
+++ b/parsing_c/parser_c.mly
@@ -857,7 +857,7 @@ new_argument:
  { let ty = addTypeD ($1,nullDecl) in
let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam ty in
Right (ArgType { p_namei = None; p_type = returnType;
-   p_register = hasreg, iihasreg;
+p_register = hasreg, iihasreg; p_attr = [];
  } )
  }
  | new_argument TOCro expr TCCro
@@ -1447,23 +1447,28 @@ parameter_decl2:
  { p_namei = Some name;
p_type = mk_ty NoType [];
p_register = (false, []);
+   p_attr = [];
  }
}
  | decl_spec declaratorp
  { LP.kr_impossible();
let ((returnType,hasreg),iihasreg) = fixDeclSpecForParam (snd $1) in
-   let (name, ftyp) = $2 in
+   let attrs = (fst $1) @ (fst $2) in
+   let (name, ftyp) = snd $2 in
{ p_namei = Some (name);
  p_type = ftyp returnType;
  p_register = (hasreg, iihasreg);
+ p_attr = attrs;
}
  }
  | decl_spec abstract_declaratorp
  { LP.kr_impossible();
let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam (snd $1) in
+   let attrs = (fst $1) @ (fst $2) in
{ p_namei = None;
  p_type = (snd $2) returnType;
  p_register = hasreg, iihasreg;
+ p_attr = attrs;
}
  }
  | decl_spec
@@ -1472,6 +1477,7 @@ parameter_decl2:
{ p_namei = None;
  p_type = returnType;
  p_register = hasreg, iihasreg;
+ p_attr = fst $1;
}
  }
 
@@ -1484,11 +1490,11 @@ parameter_decl: parameter_decl2 { et "param" ();  $1 }
 
 declaratorp:
  | declarator  { let (attr,dec) = $1 in (* attr gets ignored *)
- LP.add_ident (str_of_name (fst dec)); dec }
+ LP.add_ident (str_of_name (fst dec)); attr, dec }
  /*(* gccext: *)*/
  | declarator attributes
{ let (attr,dec) = $1 in (* attr gets ignored *)
- LP.add_ident (str_of_name (fst dec)); dec }
+ LP.add_ident (str_of_name (fst dec)); attr, dec }
 
 abstract_declaratorp:
  | abstract_declarator { $1 }
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 19/25] cocci: Add parameter attributes to C AST

2020-04-24 Thread Jaskaran Singh
With extended support of attributes, parameter attributes are needed in
the C AST so that the nocast test case does not break.

Add the p_attr field to parameter in the C AST.

Signed-off-by: Jaskaran Singh 
---
 ocaml/coccilib.mli  | 1 +
 parsing_c/ast_c.ml  | 1 +
 parsing_c/ast_c.mli | 1 +
 3 files changed, 3 insertions(+)

diff --git a/ocaml/coccilib.mli b/ocaml/coccilib.mli
index b95f2632..0e807c9a 100644
--- a/ocaml/coccilib.mli
+++ b/ocaml/coccilib.mli
@@ -109,6 +109,7 @@ module Ast_c :
   p_namei : name option;
   p_register : bool wrap;
   p_type : fullType;
+  p_attr : attribute list;
 }
 and typeQualifier = typeQualifierbis wrap
 and typeQualifierbis =
diff --git a/parsing_c/ast_c.ml b/parsing_c/ast_c.ml
index a328e661..f25f9b55 100644
--- a/parsing_c/ast_c.ml
+++ b/parsing_c/ast_c.ml
@@ -287,6 +287,7 @@ and fullType = typeQualifier * typeC
 { p_namei: name option;
   p_register: bool wrap;
   p_type: fullType;
+  p_attr: attribute list;
 }
 (* => (bool (register) * fullType) list * bool *)
 
diff --git a/parsing_c/ast_c.mli b/parsing_c/ast_c.mli
index 555a82e5..8923a335 100644
--- a/parsing_c/ast_c.mli
+++ b/parsing_c/ast_c.mli
@@ -73,6 +73,7 @@ and parameterType = {
   p_namei : name option;
   p_register : bool wrap;
   p_type : fullType;
+  p_attr : attribute list;
 }
 and typeQualifier = typeQualifierbis wrap
 and typeQualifierbis = { const : bool; volatile : bool; }
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 15/25] parsing_c: lib_parsing_c: Add ii_of_attr

2020-04-24 Thread Jaskaran Singh
ii_of_attr can be used to get the corresponding info of a single C
attribute. Add this function to lib_parsing_c.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/lib_parsing_c.ml  | 1 +
 parsing_c/lib_parsing_c.mli | 1 +
 2 files changed, 2 insertions(+)

diff --git a/parsing_c/lib_parsing_c.ml b/parsing_c/lib_parsing_c.ml
index 2ab3b3a9..99e43be3 100644
--- a/parsing_c/lib_parsing_c.ml
+++ b/parsing_c/lib_parsing_c.ml
@@ -315,6 +315,7 @@ let ii_of_define_params =
 let ii_of_ident_list = extract_info_visitor Visitor_c.vk_ident_list_splitted
 let ii_of_exec_code_list =
   extract_info_visitor Visitor_c.vk_exec_code_list_splitted
+let ii_of_attr = extract_info_visitor Visitor_c.vk_attribute
 let ii_of_attrs = extract_info_visitor Visitor_c.vk_attrs_splitted
 let ii_of_toplevel = extract_info_visitor Visitor_c.vk_toplevel
 
diff --git a/parsing_c/lib_parsing_c.mli b/parsing_c/lib_parsing_c.mli
index 1fc59420..d9578f3c 100644
--- a/parsing_c/lib_parsing_c.mli
+++ b/parsing_c/lib_parsing_c.mli
@@ -125,6 +125,7 @@ val ii_of_ident_list :
   (Ast_c.name, Ast_c.il) Common.either list -> Ast_c.info list
 val ii_of_exec_code_list :
   (Ast_c.exec_code, Ast_c.il) Common.either list -> Ast_c.info list
+val ii_of_attr : Ast_c.attribute -> Ast_c.info list
 val ii_of_attrs :
   (Ast_c.attribute, Ast_c.il) Common.either list -> Ast_c.info list
 val ii_of_toplevel : Ast_c.toplevel -> Ast_c.info list
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 25/25] engine: c_vs_c: Match parameter attributes

2020-04-24 Thread Jaskaran Singh
Parameter attributes are added to the C AST. Add an expression to check
if attributes are equal on both sides to the parameter case in c_vs_c.

Signed-off-by: Jaskaran Singh 
---
 engine/c_vs_c.ml | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/engine/c_vs_c.ml b/engine/c_vs_c.ml
index e2bd7408..b569c244 100644
--- a/engine/c_vs_c.ml
+++ b/engine/c_vs_c.ml
@@ -135,9 +135,11 @@ and typeC tya tyb =
   let iix = iia in
   acc >>= (fun xs ->
 
-let {p_register = (ba,iiba); p_namei = saopt; p_type = ta} =
+let {p_register = (ba,iiba); p_namei = saopt; p_type = ta;
+ p_attr = attrsa} =
   parama in
-let {p_register = (bb,iibb); p_namei = sbopt; p_type = tb} =
+let {p_register = (bb,iibb); p_namei = sbopt; p_type = tb;
+ p_attr = attrsb} =
   paramb in
 
 let bx = ba in
@@ -145,13 +147,15 @@ and typeC tya tyb =
 
 let sxopt = saopt in
 
+let attrsx = attrsa in
 
 (* todo?  iso on name or argument ? *)
-(ba = bb && same_s saopt sbopt) >&&>
+(ba = bb && same_s saopt sbopt && attrsa = attrsb) >&&>
 fullType ta tb >>= (fun tx ->
   let paramx = { p_register = (bx, iibx);
  p_namei = sxopt;
- p_type = tx; } in
+ p_type = tx;
+ p_attr = attrsx; } in
   return ((paramx,iix)::xs)
 )
   )
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 24/25] engine: cocci_vs_c: "Match" parameter attributes

2020-04-24 Thread Jaskaran Singh
Parameter attributes are added to the C AST, but not to the SmPL AST.
Once parameter attributes are added to SmPL as well, they can actually
be matched, but for now a call to attribute_list is required to
correctly remove attributes. Attributes from a parameter are removed
when the whole parameter is removed, replaced or otherwise.

Signed-off-by: Jaskaran Singh 
---
 engine/cocci_vs_c.ml | 50 
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/engine/cocci_vs_c.ml b/engine/cocci_vs_c.ml
index 413ea220..317fa71e 100644
--- a/engine/cocci_vs_c.ml
+++ b/engine/cocci_vs_c.ml
@@ -594,6 +594,23 @@ let initialisation_to_affectation decl =
Some x -> F.DefineExpr x
   |None -> F.Decl decl
 
+let check_allminus =
+  let mcode r (_,_,kind,_) =
+match kind with
+  A.MINUS(_,_,_,_) -> true
+| _ -> false in
+  let bind x y = x && y in
+  let option_default = true in
+  let donothing r k re = k re in
+  Visitor_ast.combiner bind option_default
+mcode mcode mcode mcode mcode mcode mcode mcode mcode
+mcode mcode mcode mcode mcode
+donothing donothing donothing donothing donothing donothing
+donothing donothing donothing donothing donothing donothing
+donothing donothing donothing donothing donothing donothing
+donothing donothing donothing donothing donothing donothing
+donothing donothing donothing donothing
+
 (*)
 (* Functor parameter combinators *)
 (*)
@@ -1994,7 +2011,8 @@ and argument arga argb =
   X.all_bound (A.get_inherited arga) >&&>
   match A.unwrap arga, argb with
   | A.TypeExp tya,
-Right (B.ArgType {B.p_register=b,iib; p_namei=sopt;p_type=tyb}) ->
+Right (B.ArgType
+{B.p_register=b,iib; p_namei=sopt;p_type=tyb;p_attr=attrs}) ->
   if b || sopt <> None
   then
 (* failwith "the argument have a storage and ast_cocci does not have"*)
@@ -2006,7 +2024,8 @@ and argument arga argb =
 (A.TypeExp tya) +> A.rewrap arga,
 (Right (B.ArgType {B.p_register=(b,iib);
p_namei=sopt;
-   p_type=tyb;}))
+   p_type=tyb;
+   p_attr=attrs;}))
 ))
 
   | A.TypeExp tya,  _  -> fail
@@ -2099,19 +2118,25 @@ and parameters_bis eas ebs =
   | [], [Left eb] ->
   let {B.p_register=(hasreg,iihasreg);
 p_namei = idbopt;
-p_type=tb; } = eb in
+p_type=tb;
+p_attr=attrs; } = eb in
 
+  let attr_allminus =
+check_allminus.Visitor_ast.combiner_parameter ea in
   if idbopt = None && not hasreg
   then
 match tb with
 | (qub, (B.BaseType B.Void,_)) ->
 fullType ta tb >>= (fun ta tb ->
+attribute_list attr_allminus [] attrs >>=
+(fun attrsa attrsb ->
   return (
   [(A.VoidParam ta) +> A.rewrap ea],
   [Left {B.p_register=(hasreg, iihasreg);
   p_namei = idbopt;
-  p_type = tb;}]
-   ))
+  p_type = tb;
+  p_attr = attrsb;}]
+   )))
 | _ -> fail
   else fail
   | _ -> fail)
@@ -2149,9 +2174,14 @@ and parameter = fun parama paramb ->
   | A.Param (typa, idaopt), eb ->
   let {B.p_register = (hasreg,iihasreg);
p_namei = nameidbopt;
-   p_type = typb;} = paramb in
+   p_type = typb;
+p_attr = attrs;} = paramb in
+
+  let attr_allminus =
+check_allminus.Visitor_ast.combiner_parameter parama in
 
   fullType typa typb >>= (fun typa typb ->
+  attribute_list attr_allminus [] attrs >>= (fun attrsa attrsb ->
match idaopt, nameidbopt with
| Some ida, Some nameidb ->
   (* todo: if minus on ida, should also minus the iihasreg ? *)
@@ -2160,7 +2190,8 @@ and parameter = fun parama paramb ->
   A.Param (typa, Some ida)+> A.rewrap parama,
   {B.p_register = (hasreg, iihasreg);
p_namei = Some (nameidb);
-   p_type = typb}
+p_type = typb;
+p_attr = attrsb;}
))
 
| None, None ->
@@ -2168,7 +2199,8 @@ and parameter = fun parama paramb ->
 A.Param (typa, None)+> A.rewrap parama,
 {B.p_register=(hasreg,iihasreg);
   p_namei = None;
-  p_type = typb;}
+  p_type = typb;
+  p_attr = attrsb;}
  )
   (* why handle this case ? because of 

[Cocci] [RFC PATCH 13/25] cocci: standard.h: Annotate attributes with MACROANNOTATION

2020-04-24 Thread Jaskaran Singh
Apply the MACROANNOTATION hint to select attributes in standard.h. These
hints can be replaced, removed or added by the user as their use case
demands.

Signed-off-by: Jaskaran Singh 
---
 standard.h | 116 ++---
 1 file changed, 58 insertions(+), 58 deletions(-)

diff --git a/standard.h b/standard.h
index 7a7f96ea..a25d2ae7 100644
--- a/standard.h
+++ b/standard.h
@@ -87,46 +87,46 @@
 // 
 // Attributes. could perhaps generalize via "__.*"
 // 
-#define  __init
-#define  __initconst
-#define  __page_aligned_data
-#define  __page_aligned_bss
-#define  __always_unused
-#define  __visible
-#define  __exit
-#define  __user
-#define  __iomem
-#define  __initdata
-#define  __exitdata
-#define  __devinit
-#define  __devexit
-#define  __devinitdata
-#define  __cpuinit
-#define  __cpuinitdata
-#define  __init_or_module
-#define  __initdata_or_module
-#define  __pminit
-#define  __pminitdata
-#define  __irq_entry
-
-#define  __cacheline_aligned
-#define  cacheline_aligned
-#define  __cacheline_aligned_in_smp
-#define  cacheline_aligned_in_smp
-#define  cacheline_internodealigned_in_smp
+#define  __init MACROANNOTATION
+#define  __initconst MACROANNOTATION
+#define  __page_aligned_data MACROANNOTATION
+#define  __page_aligned_bss MACROANNOTATION
+#define  __always_unused MACROANNOTATION
+#define  __visible MACROANNOTATION
+#define  __exit MACROANNOTATION
+#define  __user MACROANNOTATION
+#define  __iomem MACROANNOTATION
+#define  __initdata MACROANNOTATION
+#define  __exitdata MACROANNOTATION
+#define  __devinit MACROANNOTATION
+#define  __devexit MACROANNOTATION
+#define  __devinitdata MACROANNOTATION
+#define  __cpuinit MACROANNOTATION
+#define  __cpuinitdata MACROANNOTATION
+#define  __init_or_module MACROANNOTATION
+#define  __initdata_or_module MACROANNOTATION
+#define  __pminit MACROANNOTATION
+#define  __pminitdata MACROANNOTATION
+#define  __irq_entry MACROANNOTATION
+
+#define  __cacheline_aligned MACROANNOTATION
+#define  cacheline_aligned MACROANNOTATION
+#define  __cacheline_aligned_in_smp MACROANNOTATION
+#define  cacheline_aligned_in_smp MACROANNOTATION
+#define  cacheline_internodealigned_in_smp MACROANNOTATION
 
 #define  __ALIGNED__
 #define  __3xp_aligned
 
-#define  __pmac
-#define  __force
-#define  __nocast
-#define  __read_mostly
+#define  __pmac MACROANNOTATION
+#define  __force MACROANNOTATION
+#define  __nocast MACROANNOTATION
+#define  __read_mostly MACROANNOTATION
 
-#define  __must_check
+#define  __must_check MACROANNOTATION
 // pb
-#define  __unused
-#define  __maybe_unused
+#define  __unused MACROANNOTATION
+#define  __maybe_unused MACROANNOTATION
 
 
 #define  __attribute_used__
@@ -139,27 +139,27 @@
 #define  __xipram
 
 // in the other part of the kernel, in arch/, mm/, etc
-#define  __sched
-#define  __initmv
-#define  __exception
-#define  __cpuexit
-#define  __kprobes
-#define  __meminit
-#define  __meminitdata
-#define  __nosavedata
-#define  __kernel
-#define  __nomods_init
-#define  __apicdebuginit
-#define  __ipc_init
-#define  __modinit
-#define  __lockfunc
-#define  __weak
-#define  __tlb_handler_align
-#define  __lock_aligned
-#define  __force_data
-#define  __nongprelbss
-#define  __nongpreldata
-#define  __noreturn
+#define  __sched MACROANNOTATION
+#define  __initmv MACROANNOTATION
+#define  __exception MACROANNOTATION
+#define  __cpuexit MACROANNOTATION
+#define  __kprobes MACROANNOTATION
+#define  __meminit MACROANNOTATION
+#define  __meminitdata MACROANNOTATION
+#define  __nosavedata MACROANNOTATION
+#define  __kernel MACROANNOTATION
+#define  __nomods_init MACROANNOTATION
+#define  __apicdebuginit MACROANNOTATION
+#define  __ipc_init MACROANNOTATION
+#define  __modinit MACROANNOTATION
+#define  __lockfunc MACROANNOTATION
+#define  __weak MACROANNOTATION
+#define  __tlb_handler_align MACROANNOTATION
+#define  __lock_aligned MACROANNOTATION
+#define  __force_data MACROANNOTATION
+#define  __nongprelbss MACROANNOTATION
+#define  __nongpreldata MACROANNOTATION
+#define  __noreturn MACROANNOTATION
 
 #define  __section_jiffies
 #define  __vsyscall_fn
@@ -193,9 +193,9 @@
 
 
 // last last
-#define __net_init
-#define __net_exit
-#define __net_initdata
+#define __net_init MACROANNOTATION
+#define __net_exit MACROANNOTATION
+#define __net_initdata MACROANNOTATION
 
 #define __paginginit // in mm
 
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 22/25] parsing_c: unparse_hrule: Add parameter attributes in record

2020-04-24 Thread Jaskaran Singh
Parameter attributes are added to the C AST. Initialize the parameter
attributes field as empty in a case in unparse_hrule.ml.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/unparse_hrule.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/parsing_c/unparse_hrule.ml b/parsing_c/unparse_hrule.ml
index f2605d82..fca985ca 100644
--- a/parsing_c/unparse_hrule.ml
+++ b/parsing_c/unparse_hrule.ml
@@ -207,7 +207,8 @@ let print_metavar pr = function
(function _ -> pr " ")
 {Ast_c.p_register = (false,[]);
  p_namei = Some name';
- p_type = (({Ast_c.const = false; Ast_c.volatile = false},[]),ty)
+ p_type = (({Ast_c.const = false; Ast_c.volatile = false},[]),ty);
+ p_attr = [];
 }
   | _ -> failwith "function must have named parameters"
 
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 10/25] parsing_c: parser: Add MacroDecl end attributes production

2020-04-24 Thread Jaskaran Singh
Add a production for macro declaration end attributes. This parses the
following C code from Linux v5.6-rc7:

  arch/x86/kernel/nmi_selftest.c:

static DECLARE_BITMAP(nmi_ipi_mask, NR_CPUS) __initdata;

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parser_c.mly | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index 99ceb359..eb22cbcf 100644
--- a/parsing_c/parser_c.mly
+++ b/parsing_c/parser_c.mly
@@ -1598,6 +1598,17 @@ decl2:
   MacroDecl
 ((NoSto, fst $2, $4, true), [snd $2;$3;$5;$6;fakeInfo()]) }
 
+ | storage_const_opt TMacroDecl TOPar argument_list TCPar end_attributes
+   TPtVirg
+ { function _ ->
+   match $1 with
+Some (sto,stoii) ->
+  MacroDecl
+((sto, fst $2, $4, true), (snd $2::$3::$5::$7::fakeInfo()::stoii))
+   | None ->
+  MacroDecl
+((NoSto, fst $2, $4, true), [snd $2;$3;$5;$7;fakeInfo()]) }
+
  | storage_const_opt
  TMacroDecl TOPar argument_list TCPar teq initialize TPtVirg
  { function _ ->
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 01/25] parsing_c: parse_c: Ignore TMacroAttr and TMacroEndAttr in passed tokens

2020-04-24 Thread Jaskaran Singh
Most cases in parsing_hacks do not consider attributes before or after
the token in question. So, do not pass TMacroAttr or TMacroEndAttr
tokens to parsing_hacks in the before list.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parse_c.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/parsing_c/parse_c.ml b/parsing_c/parse_c.ml
index 428261f6..0d3a189a 100644
--- a/parsing_c/parse_c.ml
+++ b/parsing_c/parse_c.ml
@@ -608,13 +608,15 @@ let rec lexer_function ~pass tr = fun lexbuf ->
 | x -> x
   in
 
+  let passed_before = filter_noise 10 tr.passed_clean in
+
   let v =
if !in_exec
then v
else
  Parsing_hacks.lookahead ~pass
(clean_for_lookahead (v::tr.rest_clean))
-   tr.passed_clean in
+   passed_before in
 
   tr.passed <- v::tr.passed;
 
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 08/25] parsing_c: parser: Add field declaration end attributes production

2020-04-24 Thread Jaskaran Singh
As per GCC's C grammar, the struct-declarator rule has the following
productions:

struct-declarator:
  declarator gnu-attributes[opt]
  declarator[opt] : constant-expression gnu-attributes[opt]

While these productions are handled in the struct_declarator rule of
Coccinelle's C grammar, end attributes are not.

Add productions for end attributes in the field_declaration rule of
Coccinelle's C parser. This parses the following C code from Linux
v5.6-rc7 successfully:

  kernel/sched/sched.h:

struct task_group {
...
atomic_t load_avg __cacheline_aligned;
...
};

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parser_c.mly | 28 
 1 file changed, 28 insertions(+)

diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index 1ff2fd87..8def5f0d 100644
--- a/parsing_c/parser_c.mly
+++ b/parsing_c/parser_c.mly
@@ -1847,6 +1847,22 @@ field_declaration:
   *)
  }
 
+ | spec_qualif_list struct_declarator_list end_attributes TPtVirg
+ {
+   let (attrs, ds) = $1 in
+   let (returnType,storage) = fixDeclSpecForDecl ds in
+   if fst (unwrap storage) <> NoSto
+   then internal_error "parsing don't allow this";
+
+   let iistart = Ast_c.fakeInfo () in (* for parallelism with DeclList *)
+   FieldDeclList ($2 +> (List.map (fun (f, iivirg) ->
+ f returnType, iivirg))
+ ,[$4;iistart])
+ (* don't need to check if typedef or func initialised cos
+  * grammar don't allow typedef nor initialiser in struct
+  *)
+ }
+
  | spec_qualif_list TPtVirg
  {
let (attrs, ds) = $1 in
@@ -1859,6 +1875,18 @@ field_declaration:
FieldDeclList ([(Simple (None, returnType)) , []], [$2;iistart])
  }
 
+ | spec_qualif_list end_attributes TPtVirg
+ {
+   let (attrs, ds) = $1 in
+   (* gccext: allow empty elements if it is a structdef or enumdef *)
+   let (returnType,storage) = fixDeclSpecForDecl ds in
+   if fst (unwrap storage) <> NoSto
+   then internal_error "parsing don't allow this";
+
+   let iistart = Ast_c.fakeInfo () in (* for parallelism with DeclList *)
+   FieldDeclList ([(Simple (None, returnType)) , []], [$3;iistart])
+ }
+
 
 
 
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 05/25] parsing_c: parser: Add expression statement attributes

2020-04-24 Thread Jaskaran Singh
As per GCC's C grammar, the expression statement rule has the following
production:

expression-statement:
  gnu-attributes ;

Add this production to the expr_statement rule of Coccinelle's C parser.
If attributes are recognized, this parses the following code
successfully:

label: attribute;

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parser_c.mly | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index d259f12a..a858db56 100644
--- a/parsing_c/parser_c.mly
+++ b/parsing_c/parser_c.mly
@@ -1082,8 +1082,9 @@ stat_or_decl:
 
 
 expr_statement:
- | TPtVirg  { None,[$1] }
- | expr TPtVirg { Some $1, [$2] }
+ | TPtVirg { None,[$1] }
+ | end_attributes TPtVirg { None,[$2] }
+ | expr TPtVirg{ Some $1, [$2] }
 
 selection:
  | Tif TOPar expr TCPar cpp_ifdef_statement  %prec SHIFTHERE
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 02/25] parsing_c: parsing_hacks: Label end attributes correctly

2020-04-24 Thread Jaskaran Singh
Due to certain conflicts in the grammar, a separate token
(TMacroEndAttr) is required for attributes before a semicolon or an
assignment operator. Prior to this, multiple end attributes were not
labeled correctly, i.e., only the single attribute before the semicolon
or assignment operator would be.

Add a case to label multiple end attributes correctly.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parsing_hacks.ml | 4 
 1 file changed, 4 insertions(+)

diff --git a/parsing_c/parsing_hacks.ml b/parsing_c/parsing_hacks.ml
index 0ee0c6c6..74c3ba60 100644
--- a/parsing_c/parsing_hacks.ml
+++ b/parsing_c/parsing_hacks.ml
@@ -2771,6 +2771,10 @@ let lookahead2 ~pass next before =
  msg_attribute s1;
  TMacroAttr (s1, i1)
 
+  | (TMacroAttr(s1,i1)::(TPtVirg(ii2)|TEq(ii2))::rest,_)
+  ->
+ TMacroEndAttr (s1, i1)
+
 (*  (* christia: here insert support for macros on top level *)
   | TIdent (s, ii) :: tl :: _, _ when
 can_be_on_top_level tl && LP.current_context () = InTopLevel ->
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 03/25] parsing_c: parsing_hacks: Commentize attributes before qualif/type

2020-04-24 Thread Jaskaran Singh
For the following example from fs/btrfs/ctree.h in Linux v5.6-rc7:

__cold __noreturn
static inline void assertfail(const char *expr, const char *file, int line)
{
pr_err("assertion failed: %s, in %s:%d\n", expr, file, line);
BUG();
}

__cold and __noreturn are not labeled correctly, leading to C parsing
errors. Add a case to commentize attributes before a storage
qualifier/type qualifier/type correctly.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parsing_hacks.ml | 33 +
 1 file changed, 33 insertions(+)

diff --git a/parsing_c/parsing_hacks.ml b/parsing_c/parsing_hacks.ml
index 74c3ba60..0254fc7f 100644
--- a/parsing_c/parsing_hacks.ml
+++ b/parsing_c/parsing_hacks.ml
@@ -1952,6 +1952,29 @@ let is_type = function
   | Tshort _ -> true
   | _ -> false
 
+let is_type_qualif = function
+  | Tconst _
+  | Tvolatile _ -> true
+  | _ -> false
+
+let is_storage_spec = function
+  | Tstatic _
+  | Tregister _
+  | Textern _
+  | Tauto _ -> true
+  | _ -> false
+
+let rec is_idents ?(followed_by=fun _ -> true) ts =
+  let rec loop l =
+match l with
+| x::xs when ident x -> loop xs
+| x::xs -> followed_by x
+| [] -> failwith "unexpected end of token stream" in
+  match ts with
+  | x::xs when ident x -> loop xs
+  | x::xs -> followed_by x
+  | _ -> false
+
 let is_cparen = function (TCPar _) -> true | _ -> false
 let is_oparen = function (TOPar _) -> true | _ -> false
 
@@ -2134,6 +2157,16 @@ let lookahead2 ~pass next before =
  else
TCommentCpp (Token_c.CppDirective, i1)
 
+   (* tt xx yy *)
+  | (TIdent (s, i1)::rest, _)
+when not_struct_enum before
+   && is_idents
+   ~followed_by:
+ (function x ->
+is_type x || is_storage_spec x || is_type_qualif x) rest
+&& s ==~ regexp_annot ->
+   TCommentCpp (Token_c.CppMacro, i1)
+
   | (TIdent (s2, i2)::_  , TIdent (s, i1)::seen::_)
 when not_struct_enum before
&& is_macro s2 && is_type seen ->
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 07/25] parsing_c: parser: Add init_declarator_attrs rule

2020-04-24 Thread Jaskaran Singh
As per GCC's C grammar, the init-declarator rule has the following
production:

init-declarator:
  declarator simple-asm-expr[opt] gnu-attributes[opt]
  declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer

Due to conflicts in Coccinelle's C grammar, adding productions with
attributes to init_declarator is not possible. Create
init_declarator_attrs and use this rule in init_declarator_list for
handling attributes after commas.

Following is an example of C code that is parsed successfully:

struct mxser_mstatus ms, __user *msu = argp;

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parser_c.mly | 23 +--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index a5b0d214..1ff2fd87 100644
--- a/parsing_c/parser_c.mly
+++ b/parsing_c/parser_c.mly
@@ -1668,6 +1668,23 @@ init_declarator2:
  | declaratori TOParCplusplusInit argument_list TCPar
  { ($1, ConstrInit($3,[$2;$4])) }
 
+/*(*---*)*/
+/*(* declarators (right part of type and variable). *)*/
+/*(* This is a workaround for the following case: *)*/
+/*(*  ,   ...*)*/
+/*(* The normal init_declarator rule does not handle this, and adding *)*/
+/*(* attributes to it causes conflicts, thus the need for this rule. *)*/
+/*(*---*)*/
+init_declarator_attrs2:
+ | declaratori  { ($1, NoInit) }
+ | attributes declaratori   { ($2, NoInit) }
+ | declaratori teq initialize   { ($1, ValInit($2, $3)) }
+ | attributes declaratori teq initialize   { ($2, ValInit($3, $4)) }
+ /* C++ only */
+ | declaratori TOParCplusplusInit argument_list TCPar
+ { ($1, ConstrInit($3,[$2;$4])) }
+ | attributes declaratori TOParCplusplusInit argument_list TCPar
+ { ($2, ConstrInit($4,[$3;$5])) }
 
 /*(**)*/
 /*(* workarounds *)*/
@@ -1676,6 +1693,8 @@ teq: TEq  { et "teq" (); $1 }
 
 init_declarator: init_declarator2  { dt "init" (); $1 }
 
+init_declarator_attrs: init_declarator_attrs2 { dt "init_attrs" (); $1 }
+
 
 /*(**)*/
 /*(* gccext: *)*/
@@ -2373,9 +2392,9 @@ enumerator_list:
 
 init_declarator_list:
  | init_declarator { [$1,   []] }
- | init_declarator_list TComma cpp_directive_list init_declarator
+ | init_declarator_list TComma cpp_directive_list init_declarator_attrs
  { $1 @ [$4, [$2]] }
- | init_declarator_list TComma init_declarator { $1 @ [$3, [$2]] }
+ | init_declarator_list TComma init_declarator_attrs { $1 @ [$3, [$2]] }
 
 
 parameter_list:
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 09/25] parsing_c: parser: Handle struct/union/enum end attributes

2020-04-24 Thread Jaskaran Singh
As per GCC's C grammar, the struct-or-union-specifier and enum-specifier
have the following productions:

   struct-or-union-specifier:
 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
   identifier[opt] { struct-contents } gnu-attributes[opt]

   enum-specifier:
 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
   gnu-attributes[opt]
 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
   gnu-attributes[opt]

Add a production to the decl2 rule of Coccinelle's C parser to handle
the end attributes here (i.e. gnu-attributes after the } ). This parses
the following C code from Linux v5.6-rc7:

  drivers/net/wireless/broadcom/b43legacy/b43legacy.h

struct b43legacy_iv {
__be16 offset_size;
union {
__be16 d16;
__be32 d32;
} data __packed;
} __packed;

  drivers/scsi/myrs.h:

enum myrs_cmd_opcode {
MYRS_CMD_OP_MEMCOPY = 0x01,
MYRS_CMD_OP_SCSI_10_PASSTHRU= 0x02,
MYRS_CMD_OP_SCSI_255_PASSTHRU   = 0x03,
MYRS_CMD_OP_SCSI_10 = 0x04,
MYRS_CMD_OP_SCSI_256= 0x05,
MYRS_CMD_OP_IOCTL   = 0x20,
} __packed;

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parser_c.mly | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index 8def5f0d..99ceb359 100644
--- a/parsing_c/parser_c.mly
+++ b/parsing_c/parser_c.mly
@@ -1554,6 +1554,17 @@ decl2:
 },[]],
 ($2::iistart::snd storage))
  }
+ | decl_spec end_attributes TPtVirg
+ { function local ->
+   let (returnType,storage) = fixDeclSpecForDecl (snd $1) in
+   let iistart = Ast_c.fakeInfo () in
+   DeclList ([{v_namei = None; v_type = returnType;
+   v_storage = unwrap storage; v_local = local;
+   v_attr = fst $1; v_endattr = $2;
+   v_type_bis = ref None;
+},[]],
+($3::iistart::snd storage))
+ }
  | decl_spec init_declarator_list TPtVirg
  { function local ->
let (returnType,storage) = fixDeclSpecForDecl (snd $1) in
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 04/25] parsing_c: parser: Add rule for multiple end attributes

2020-04-24 Thread Jaskaran Singh
There is no rule for productions of multiple end attributes. Add a case
similar to that of attribute_list for end attributes.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parser_c.mly | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index bfe92e18..d259f12a 100644
--- a/parsing_c/parser_c.mly
+++ b/parsing_c/parser_c.mly
@@ -2401,8 +2401,11 @@ attribute_list:
 
 attributes: attribute_list { $1 }
 
-end_attributes:
+end_attribute_list:
  | TMacroEndAttr { [Attribute (fst $1), [snd $1]] }
+ | end_attribute_list TMacroEndAttr { $1 @ [Attribute(fst $2), [snd $2]] }
+
+end_attributes: end_attribute_list { $1 }
 
 comma_opt:
  | TComma {  [$1] }
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 00/25] cocci: Improve C parsing of attributes

2020-04-24 Thread Jaskaran Singh
This patch series aims to improve parsing of attributes in C by
Coccinelle's C parser.

These parsing errors were discovered by running a build of Coccinelle's
master branch on gitlab to parse the source code of Linux v5.5-rc4 and Linux
v5.6-rc7. Coccinelle currently manages attributes similar to comments, so
to explicity state what the attributes are to the C parser, a
MACROANNOTATION hint was used in Coccinelle's standard.h file. The hint
enables the parser to correctly identify attributes, and thus potentially
handle them differently in the AST.

Upon collection of these parsing errors, The GNU C Compiler's
grammar was taken as a reference for introducing attributes in correct
places in Coccinelle's C parser.

Upon applying the MACROANNOTATION hint to a majority of the attributes in
Coccinelle's standard.h file and parsing the source code of Linux
v5.6-rc7, the difference between the stats (of --parse-c) before and
after applying this patch series are as follows:

Before:

NB total files = 28268; perfect = 25697; pbs = 2570; timeout = 0; 
=> 90%
nb good = 19160664,  nb passed = 135235 => 0.70% passed
nb good = 19160664,  nb bad = 129685 => 99.33% good or passed

After:

NB total files = 28268; perfect = 25699; pbs = 2568; timeout = 0; 
=> 90%
nb good = 19160856,  nb passed = 71716 => 0.37% passed
nb good = 19160856,  nb bad = 129493 => 99.33% good or passed

Fixes for a few test case failures that arise from applying the new
productions are also included. The test cases that failed were:

unstruct
nocast

What this patch series does not do:
- Add attributes from all the new productions into the C AST. Some of
  these are dropped.
- Reflect changes from the C parser in the SmPL parser.

Separate patches will be sent for the above.

Jaskaran Singh (25):
  parsing_c: parse_c: Ignore TMacroAttr and TMacroEndAttr in passed tokens
  parsing_c: parsing_hacks: Label end attributes correctly
  parsing_c: parsing_hacks: Commentize attributes before qualif/type
  parsing_c: parser: Add rule for multiple end attributes
  parsing_c: parser: Add expression statement attributes
  parsing_c: parser: Add attribute production in spec_qualif_list
  parsing_c: parser: Add init_declarator_attrs rule
  parsing_c: parser: Add field declaration end attributes production
  parsing_c: parser: Handle struct/union/enum end attributes
  parsing_c: parser: Add MacroDecl end attributes production
  parsing_c: parser: cpp_other end attributes production
  parsing_c: cpp_token_c: Introduce MACROANNOTATION hint
  cocci: standard.h: Annotate attributes with MACROANNOTATION
  parsing_c: visitor_c: Add vk_attribute and vk_attribute_s
  parsing_c: lib_parsing_c: Add ii_of_attr
  engine: Add distrf_attr to PARAM functor
  engine: cocci_vs_c: Add allminus argument to attribute_list
  parsing_c: parser: Make abstract_declarator pass attributes
  cocci: Add parameter attributes to C AST
  parsing_c: parser: Place parameter attributes in C AST
  parsing_c: visitor_c: Visit parameter attributes
  parsing_c: unparse_hrule: Add parameter attributes in record
  parsing_c: type_c: Add parameter attributes to record
  engine: cocci_vs_c: "Match" parameter attributes
  engine: c_vs_c: Match parameter attributes

 engine/c_vs_c.ml|   12 ++-
 engine/cocci_vs_c.ml|   85 +-
 engine/cocci_vs_c.mli   |3 
 engine/pattern_c.ml |1 
 engine/transformation_c.ml  |5 +
 ocaml/coccilib.mli  |1 
 parsing_c/ast_c.ml  |1 
 parsing_c/ast_c.mli |1 
 parsing_c/cpp_token_c.ml|2 
 parsing_c/lib_parsing_c.ml  |1 
 parsing_c/lib_parsing_c.mli |1 
 parsing_c/parse_c.ml|4 -
 parsing_c/parser_c.mly  |  165 +---
 parsing_c/parsing_hacks.ml  |   37 +
 parsing_c/type_c.ml |1 
 parsing_c/unparse_hrule.ml  |3 
 parsing_c/visitor_c.ml  |7 +
 parsing_c/visitor_c.mli |3 
 standard.h  |  116 +++---
 19 files changed, 342 insertions(+), 107 deletions(-)



___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 12/25] parsing_c: cpp_token_c: Introduce MACROANNOTATION hint

2020-04-24 Thread Jaskaran Singh
A better way of denoting attributes is to pass attribute information
from SmPL to the C parser. However, a temporary solution is to introduce
a MACROANNOTATION hint to cpp_token_c.ml so that the parser can identify
attributes easily.

This hint can be used as follows in standard.h, the user provided
macro-defs file or the given C file itself:

#define __attribute_name MACROANNOTATION

By default, __attribute_name would be identified as a comment. Using the
above hint, __attribute_name would be identified as an attribute and
transformations from SmPL would be performed as if __attribute_name is
an attribute, not a comment.

Signed-off-by: Jaskaran Singh 
---
 parsing_c/cpp_token_c.ml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/parsing_c/cpp_token_c.ml b/parsing_c/cpp_token_c.ml
index 425234e8..0654be26 100644
--- a/parsing_c/cpp_token_c.ml
+++ b/parsing_c/cpp_token_c.ml
@@ -81,6 +81,8 @@ let assoc_hint_string = [
   "YACFE_END_ATTRIBUTE" , HintEndAttribute;
   "YACFE_IDENT_BUILDER" , HintMacroIdentBuilder;
 
+  "MACROANNOTATION"   , HintAttribute;
+
   "MACROSTATEMENT"   , HintMacroStatement; (* backward compatibility *)
 ]
 
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 11/25] parsing_c: parser: cpp_other end attributes production

2020-04-24 Thread Jaskaran Singh
Add a production for a macro call in the cpp_other rule of Coccinelle's
C parser. This parses the following C code from Linux v5.6-rc7
successfully:

  arch/x86/kernel/irq_64.c:

DEFINE_PER_CPU_PAGE_ALIGNED(struct irq_stack, irq_stack_backing_store) 
__visible;

Signed-off-by: Jaskaran Singh 
---
 parsing_c/parser_c.mly | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index eb22cbcf..da6b9c7b 100644
--- a/parsing_c/parser_c.mly
+++ b/parsing_c/parser_c.mly
@@ -2262,6 +2262,37 @@ cpp_other:
(* old: MacroTop (fst $1, $3,[snd $1;$2;$4;$5])  *)
  }
 
+ | identifier TOPar argument_list TCPar end_attributes TPtVirg
+ {
+   if args_are_params $3
+   then
+(* if all args are params, assume it is a prototype of a function
+   with no return type *)
+let parameters = args_to_params $3 None in
+let paramlist = (parameters, (false, [])) in (* no varargs *)
+let id = RegularName (mk_string_wrap $1) in
+let ret =
+  warning "type defaults to 'int'"
+(mk_ty defaultInt [fakeInfo fake_pi]) in
+let ty =
+  fixOldCDecl (mk_ty (FunctionType (ret, paramlist)) [$2;$4]) in
+let attrs = Ast_c.noattr in
+let sto = (NoSto, false), [] in
+let iistart = Ast_c.fakeInfo () in
+Declaration(
+DeclList ([{v_namei = Some (id,NoInit); v_type = ty;
+  v_storage = unwrap sto; v_local = NotLocalDecl;
+  v_attr = attrs; v_endattr = $5;
+ v_type_bis = ref None;
+},[]],
+   ($6::iistart::snd sto)))
+   else
+Declaration
+  (MacroDecl((NoSto, fst $1, $3, true), [snd $1;$2;$4;$6;fakeInfo()]))
+   (* old: MacroTop (fst $1, $3,[snd $1;$2;$4;$5])  *)
+ }
+
+
  /* cheap solution for functions with no return type.  Not really a
cpp_other, but avoids conflicts */
  | identifier TOPar argument_list TCPar compound {
-- 
2.21.1

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [RFC PATCH 06/25] parsing_c: parser: Add attribute production in spec_qualif_list

2020-04-24 Thread Jaskaran Singh
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 
---
 parsing_c/parser_c.mly | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly
index a858db56..a5b0d214 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,13 @@ 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 (attrs2, fn) = $2 in
+   let (returnType, _) = fixDeclSpecForDecl ds in
+   fn returnType }
 
 
 
@@ -1808,7 +1814,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 +1830,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

___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


Re: [Cocci] console: Complete exception handling in newport_probe()

2020-04-24 Thread Markus Elfring
> Sorry, I do not know how to use the SmPL script.

I would like to try again to make you more familiar with applications
of the Coccinelle software.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/dev-tools/coccinelle.rst?id=b4f633221f0aeac102e463a4be46a643b2e3b819#n9

Another small example according to a script for the semantic patch language:
@display@
expression e, x;
statement is, es;
type t;
@@
*e = (t) ioremap(...)
 ... when != if( \( !e \| e == NULL \| unlikely( \( !e \| e == NULL \) ) \| 
WARN_ON( \( !e \| e == NULL \) ) \) ) is else es
 when != iounmap(e)
 return x;



>> Would you like to let any more source code analysis tools help you
>> to find remaining update candidates?
>>
> yes, but I think the source code analysis tools only can found the simple
> repetitive issue.

The shown analysis approach can point 127 source files out from
the software “Linux next-20200423”. These files contain function implementations
which might need further development considerations.


> and need spend some time learning to use it.

You came along a few files where you noticed questionable source code.
Would you become interested to find similar places for another check?


elfring@Sonne:~/Projekte/Linux/next-patched> XX=$(date) && spatch --no-loops 
--timeout 12 -j 4 --chunksize 1 -dir ~/Projekte/Linux/next-patched 
~/Projekte/Coccinelle/janitor/show_questionable_ioremap_usage3.cocci > 
~/Projekte/Bau/Linux/scripts/Coccinelle/ioremap/20200423/show_questionable_ioremap_usage3.diff
 2> 
~/Projekte/Bau/Linux/scripts/Coccinelle/ioremap/20200423/show_questionable_ioremap_usage3-errors.txt;
 YY=$(date) && echo "$XX | $YY"
Fr 24. Apr 09:08:44 CEST 2020 | Fr 24. Apr 09:10:37 CEST 2020

Would you like to extend your learning experiences accordingly?


> now, I think the best for me may be that read and check the source code.

How do you think about to reduce efforts for manual code inspection?

Regards,
Markus
___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci