All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cocci] Surprising parsing error occuring when casting C string
@ 2017-08-01 13:04 Yann Droneaud
  2017-08-01 13:46 ` Julia Lawall
  0 siblings, 1 reply; 4+ messages in thread
From: Yann Droneaud @ 2017-08-01 13:04 UTC (permalink / raw)
  To: cocci

Hi,

I'm wondering why coccinelle seems not to be able to apply simple
semantic patch when code source contains casted C string.

Given simple source file (note the lack of definition for types,
assuming they're somewhere in an included header):

$ cat test.c
static structure_t array[] =
{
        { (pointer_t)"a string", 32 },
        { (pointer_t)DEFINED, 23 }
};

void function(void)
{
        if (!other(1, (pointer_t)"value", 3))
                foo();
        else
                bar();
}

And very simple semantic patch:

$ cat test.cocci
@@
@@
- foo()
+ FOO()

Here's the result:

$ spatch --verbose-parsing --sp-file test.cocci test.c
init_defs_builtins: /usr/lib64/coccinelle/standard.h
HANDLING: test.c
ERROR-RECOV: found sync '}' at line 5
ERROR-RECOV: found sync bis, eating } and ;
parsing pass2: try again
ERROR-RECOV: found sync '}' at line 5
ERROR-RECOV: found sync bis, eating } and ;
parse error 
 = File "test.c", line 3, column 21, charpos = 52
  around = '"a string"',
  whole content =         { (pointer_t)"a string", 32 },
badcount: 4
bad: static structure_t array[] =
bad: {
BAD:!!!!!         { (pointer_t)"a string", 32 },
bad:         { (pointer_t)DEFINED, 23 }
bad: };
ERROR-RECOV: found sync '}' at line 13
parsing pass2: try again
ERROR-RECOV: found sync '}' at line 13
parse error 
 = File "test.c", line 9, column 33, charpos = 164
  around = '"value"',
  whole content =         if (!other(1, (pointer_t)"value", 3))
badcount: 8
bad: };
bad: 
bad: void function(void)
bad: {
BAD:!!!!!         if (!other(1, (pointer_t)"value", 3))
bad:                 foo();
bad:         else
bad:                 bar();
bad: }

Modifying a bit the semantic patch to make "pointer_t" a known type
doesn't help:

$ cat test-typedef.cocci
@@
typedef pointer_t;
@@
- foo()
+ FOO()

$ spatch --verbose-parsing --sp-file test-typedef.cocci test.c
init_defs_builtins: /usr/lib64/coccinelle/standard.h
HANDLING: test.c
ERROR-RECOV: found sync '}' at line 5
ERROR-RECOV: found sync bis, eating } and ;
parsing pass2: try again
ERROR-RECOV: found sync '}' at line 5
ERROR-RECOV: found sync bis, eating } and ;
parse error 
 = File "test.c", line 3, column 21, charpos = 52
  around = '"a string"',
  whole content =         { (pointer_t)"a string", 32 },
badcount: 4
bad: static structure_t array[] =
bad: {
BAD:!!!!!         { (pointer_t)"a string", 32 },
bad:         { (pointer_t)DEFINED, 23 }
bad: };
ERROR-RECOV: found sync '}' at line 13
parsing pass2: try again
ERROR-RECOV: found sync '}' at line 13
parse error 
 = File "test.c", line 9, column 33, charpos = 164
  around = '"value"',
  whole content =         if (!other(1, (pointer_t)"value", 3))
badcount: 8
bad: };
bad: 
bad: void function(void)
bad: {
BAD:!!!!!         if (!other(1, (pointer_t)"value", 3))
bad:                 foo();
bad:         else
bad:                 bar();
bad: }

In other hand, if I modify the source file to have definition for
pointer_t type, and reuse the initial semantic patch, everything is
fine:

$ diff -u test.c test-typedef.c
--- test.c	2017-08-01 14:31:03.773388889 +0200
+++ test-typedef.c	2017-08-01 14:32:15.958502964 +0200
@@ -1,3 +1,5 @@
+typedef unsigned char *pointer_t;
+
 static structure_t array[] =
 {
         { (pointer_t)"a string", 32 },

$ spatch --verbose-parsing --sp-file test.cocci test-typedef.c
init_defs_builtins: /usr/lib64/coccinelle/standard.h
HANDLING: test-typedef.c
diff = 
--- test-typedef.c
+++ /tmp/cocci-output-15390-91b50a-test-typedef.c
@@ -9,7 +9,7 @@ static structure_t array[] =
 void function(void)
 {
         if (!other(1, (pointer_t)"value", 3))
-                foo();
+                FOO();
         else
                 bar();
 }

While I cannot explained why it works, defining "structure_t" type in
source code also makes spatch happy (I belive coccinelle is able to
infer pointer_t is a type):

$ diff -u test.c test-struct.c
--- test.c	2017-08-01 14:31:03.773388889 +0200
+++ test-struct.c	2017-08-01 14:31:29.788430001 +0200
@@ -1,3 +1,11 @@
+struct structure
+{
+        pointer_t p;
+        int i;
+};
+
+typedef structure structure_t;
+
 static structure_t array[] =
 {
         { (pointer_t)"a string", 32 },


$ spatch --verbose-parsing --sp-file test.cocci test-struct.c
init_defs_builtins: /usr/lib64/coccinelle/standard.h
HANDLING: test-struct.c
diff = 
--- test-struct.c
+++ /tmp/cocci-output-15527-0af6db-test-struct.c
@@ -15,7 +15,7 @@ static structure_t array[] =
 void function(void)
 {
         if (!other(1, (pointer_t)"value", 3))
-                foo();
+                FOO();
         else
                 bar();
 }



Why `(pointer_t) "string"' is considered bad, when no proper type is
defined in the current source file ?

As soon as such construct is located in a function, the whole function
get skipped by coccinelle, which is a pity when something has to be
patched in the function.

When applying semantic patches on large code base, it's sad to have to
go through all files to check and apply patch manually.

What can I do to work around this issue ?

Regards.

-- 
Yann Droneaud
OPTEYA

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Cocci] Surprising parsing error occuring when casting C string
  2017-08-01 13:04 [Cocci] Surprising parsing error occuring when casting C string Yann Droneaud
@ 2017-08-01 13:46 ` Julia Lawall
  2017-08-01 14:23   ` Yann Droneaud
  0 siblings, 1 reply; 4+ messages in thread
From: Julia Lawall @ 2017-08-01 13:46 UTC (permalink / raw)
  To: cocci



On Tue, 1 Aug 2017, Yann Droneaud wrote:

> Hi,
>
> I'm wondering why coccinelle seems not to be able to apply simple
> semantic patch when code source contains casted C string.

Fixed.  Take the github version.

Basically, Coccinelle makes some inferences during parsin about what maybe
a typedef.  That explains the examples you have below about some cases
working.  I extended those rules to take some more kinds of constants into
account.

julia

>
> Given simple source file (note the lack of definition for types,
> assuming they're somewhere in an included header):
>
> $ cat test.c
> static structure_t array[] =
> {
>         { (pointer_t)"a string", 32 },
>         { (pointer_t)DEFINED, 23 }
> };
>
> void function(void)
> {
>         if (!other(1, (pointer_t)"value", 3))
>                 foo();
>         else
>                 bar();
> }
>
> And very simple semantic patch:
>
> $ cat test.cocci
> @@
> @@
> - foo()
> + FOO()
>
> Here's the result:
>
> $ spatch --verbose-parsing --sp-file test.cocci test.c
> init_defs_builtins: /usr/lib64/coccinelle/standard.h
> HANDLING: test.c
> ERROR-RECOV: found sync '}' at line 5
> ERROR-RECOV: found sync bis, eating } and ;
> parsing pass2: try again
> ERROR-RECOV: found sync '}' at line 5
> ERROR-RECOV: found sync bis, eating } and ;
> parse error
>  = File "test.c", line 3, column 21, charpos = 52
>   around = '"a string"',
>   whole content =         { (pointer_t)"a string", 32 },
> badcount: 4
> bad: static structure_t array[] =
> bad: {
> BAD:!!!!!         { (pointer_t)"a string", 32 },
> bad:         { (pointer_t)DEFINED, 23 }
> bad: };
> ERROR-RECOV: found sync '}' at line 13
> parsing pass2: try again
> ERROR-RECOV: found sync '}' at line 13
> parse error
>  = File "test.c", line 9, column 33, charpos = 164
>   around = '"value"',
>   whole content =         if (!other(1, (pointer_t)"value", 3))
> badcount: 8
> bad: };
> bad:
> bad: void function(void)
> bad: {
> BAD:!!!!!         if (!other(1, (pointer_t)"value", 3))
> bad:                 foo();
> bad:         else
> bad:                 bar();
> bad: }
>
> Modifying a bit the semantic patch to make "pointer_t" a known type
> doesn't help:
>
> $ cat test-typedef.cocci
> @@
> typedef pointer_t;
> @@
> - foo()
> + FOO()
>
> $ spatch --verbose-parsing --sp-file test-typedef.cocci test.c
> init_defs_builtins: /usr/lib64/coccinelle/standard.h
> HANDLING: test.c
> ERROR-RECOV: found sync '}' at line 5
> ERROR-RECOV: found sync bis, eating } and ;
> parsing pass2: try again
> ERROR-RECOV: found sync '}' at line 5
> ERROR-RECOV: found sync bis, eating } and ;
> parse error
>  = File "test.c", line 3, column 21, charpos = 52
>   around = '"a string"',
>   whole content =         { (pointer_t)"a string", 32 },
> badcount: 4
> bad: static structure_t array[] =
> bad: {
> BAD:!!!!!         { (pointer_t)"a string", 32 },
> bad:         { (pointer_t)DEFINED, 23 }
> bad: };
> ERROR-RECOV: found sync '}' at line 13
> parsing pass2: try again
> ERROR-RECOV: found sync '}' at line 13
> parse error
>  = File "test.c", line 9, column 33, charpos = 164
>   around = '"value"',
>   whole content =         if (!other(1, (pointer_t)"value", 3))
> badcount: 8
> bad: };
> bad:
> bad: void function(void)
> bad: {
> BAD:!!!!!         if (!other(1, (pointer_t)"value", 3))
> bad:                 foo();
> bad:         else
> bad:                 bar();
> bad: }
>
> In other hand, if I modify the source file to have definition for
> pointer_t type, and reuse the initial semantic patch, everything is
> fine:
>
> $ diff -u test.c test-typedef.c
> --- test.c	2017-08-01 14:31:03.773388889 +0200
> +++ test-typedef.c	2017-08-01 14:32:15.958502964 +0200
> @@ -1,3 +1,5 @@
> +typedef unsigned char *pointer_t;
> +
>  static structure_t array[] =
>  {
>          { (pointer_t)"a string", 32 },
>
> $ spatch --verbose-parsing --sp-file test.cocci test-typedef.c
> init_defs_builtins: /usr/lib64/coccinelle/standard.h
> HANDLING: test-typedef.c
> diff =
> --- test-typedef.c
> +++ /tmp/cocci-output-15390-91b50a-test-typedef.c
> @@ -9,7 +9,7 @@ static structure_t array[] =
>  void function(void)
>  {
>          if (!other(1, (pointer_t)"value", 3))
> -                foo();
> +                FOO();
>          else
>                  bar();
>  }
>
> While I cannot explained why it works, defining "structure_t" type in
> source code also makes spatch happy (I belive coccinelle is able to
> infer pointer_t is a type):
>
> $ diff -u test.c test-struct.c
> --- test.c	2017-08-01 14:31:03.773388889 +0200
> +++ test-struct.c	2017-08-01 14:31:29.788430001 +0200
> @@ -1,3 +1,11 @@
> +struct structure
> +{
> +        pointer_t p;
> +        int i;
> +};
> +
> +typedef structure structure_t;
> +
>  static structure_t array[] =
>  {
>          { (pointer_t)"a string", 32 },
>
>
> $ spatch --verbose-parsing --sp-file test.cocci test-struct.c
> init_defs_builtins: /usr/lib64/coccinelle/standard.h
> HANDLING: test-struct.c
> diff =
> --- test-struct.c
> +++ /tmp/cocci-output-15527-0af6db-test-struct.c
> @@ -15,7 +15,7 @@ static structure_t array[] =
>  void function(void)
>  {
>          if (!other(1, (pointer_t)"value", 3))
> -                foo();
> +                FOO();
>          else
>                  bar();
>  }
>
>
>
> Why `(pointer_t) "string"' is considered bad, when no proper type is
> defined in the current source file ?
>
> As soon as such construct is located in a function, the whole function
> get skipped by coccinelle, which is a pity when something has to be
> patched in the function.
>
> When applying semantic patches on large code base, it's sad to have to
> go through all files to check and apply patch manually.
>
> What can I do to work around this issue ?
>
> Regards.
>
> --
> Yann Droneaud
> OPTEYA
>
> _______________________________________________
> Cocci mailing list
> Cocci at systeme.lip6.fr
> https://systeme.lip6.fr/mailman/listinfo/cocci
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Cocci] Surprising parsing error occuring when casting C string
  2017-08-01 13:46 ` Julia Lawall
@ 2017-08-01 14:23   ` Yann Droneaud
  2017-08-01 14:23     ` Julia Lawall
  0 siblings, 1 reply; 4+ messages in thread
From: Yann Droneaud @ 2017-08-01 14:23 UTC (permalink / raw)
  To: cocci

Hi,

Le mardi 01 ao?t 2017 ? 15:46 +0200, Julia Lawall a ?crit :
> On Tue, 1 Aug 2017, Yann Droneaud wrote:
> 
> > I'm wondering why coccinelle seems not to be able to apply simple
> > semantic patch when code source contains casted C string.
> 
> Fixed.  Take the github version.
> 
> Basically, Coccinelle makes some inferences during parsin about what
> maybe a typedef.  That explains the examples you have below about
> some cases working.  I extended those rules to take some more kinds
> of constants into account.
> 

It works ! Thanks a lot for this very quick fix.

$ ../../UPSTREAM/coccinelle/spatch.opt --version
spatch version 1.0.6-00186-g0acd38eed4e5 compiled with OCaml version
4.04.0
Flags passed to the configure script: [none]
Python scripting support: yes
Syntax of regular expresssions: PCRE

$ ../../UPSTREAM/coccinelle/spatch.opt --verbose-parsing --sp-file
test.cocci test.c
init_defs_builtins: ../../UPSTREAM/coccinelle/standard.h
HANDLING: test.c
diff = 
--- test.c
+++ /tmp/cocci-output-20045-ee70d9-test.c
@@ -7,7 +7,7 @@ static structure_t array[] =
 void function(void)
 {
         if (!other(1, (pointer_t)"value", 3))
-                foo();
+                FOO();
         else
                 bar();
 }


Regards.

-- 
Yann Droneaud
OPTEYA

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Cocci] Surprising parsing error occuring when casting C string
  2017-08-01 14:23   ` Yann Droneaud
@ 2017-08-01 14:23     ` Julia Lawall
  0 siblings, 0 replies; 4+ messages in thread
From: Julia Lawall @ 2017-08-01 14:23 UTC (permalink / raw)
  To: cocci



On Tue, 1 Aug 2017, Yann Droneaud wrote:

> Hi,
>
> Le mardi 01 ao?t 2017 ? 15:46 +0200, Julia Lawall a ?crit :
> > On Tue, 1 Aug 2017, Yann Droneaud wrote:
> >
> > > I'm wondering why coccinelle seems not to be able to apply simple
> > > semantic patch when code source contains casted C string.
> >
> > Fixed.  Take the github version.
> >
> > Basically, Coccinelle makes some inferences during parsin about what
> > maybe a typedef.  That explains the examples you have below about
> > some cases working.  I extended those rules to take some more kinds
> > of constants into account.
> >
>
> It works ! Thanks a lot for this very quick fix.

Thanks for the report :)

julia

>
> $ ../../UPSTREAM/coccinelle/spatch.opt --version
> spatch version 1.0.6-00186-g0acd38eed4e5 compiled with OCaml version
> 4.04.0
> Flags passed to the configure script: [none]
> Python scripting support: yes
> Syntax of regular expresssions: PCRE
>
> $ ../../UPSTREAM/coccinelle/spatch.opt --verbose-parsing --sp-file
> test.cocci test.c
> init_defs_builtins: ../../UPSTREAM/coccinelle/standard.h
> HANDLING: test.c
> diff =
> --- test.c
> +++ /tmp/cocci-output-20045-ee70d9-test.c
> @@ -7,7 +7,7 @@ static structure_t array[] =
>  void function(void)
>  {
>          if (!other(1, (pointer_t)"value", 3))
> -                foo();
> +                FOO();
>          else
>                  bar();
>  }
>
>
> Regards.
>
> --
> Yann Droneaud
> OPTEYA
>
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-08-01 14:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-01 13:04 [Cocci] Surprising parsing error occuring when casting C string Yann Droneaud
2017-08-01 13:46 ` Julia Lawall
2017-08-01 14:23   ` Yann Droneaud
2017-08-01 14:23     ` Julia Lawall

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.