All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests
@ 2016-05-18 21:42 Luis R. Rodriguez
  2016-05-18 21:42 ` [Cocci] [RFC 1/3] tests: add test to remove single statement from branch Luis R. Rodriguez
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Luis R. Rodriguez @ 2016-05-18 21:42 UTC (permalink / raw)
  To: cocci

This adds some initial control flow documentation, I wanted to add some
basic control flow diagrams as well with self generated diagrams from
Coccinelle however I had issues figuring out what to use with dot to
make it fit within the margins. We can skip that, but I thought adding it
would also help document support and example use case for that feature
as well.

The tests/remove-code-in-branch1* was more collateral effort as I
saw a removal of a statement from a branch that only had one statement
left an empty brace. I hope we can discuss here what the expected
outcome should be. I figured removing the empty code may be an
optional optimization, however it was still unclear how to resolve this
if that's desirable. Would it be up to Coccinelle or would that be
an optional isomorphism ? I noticed no current isomorphisms seem to
remove code like this so it was unclear what to do.

The following rule for instnace can deal with it.

@ remove_empty_branch @
expression E;
@@
                                                                                
-if (E) {}

Luis R. Rodriguez (3):
  tests: add test to remove single statement from branch
  tests: add basic series of tests for exists and forall
  coccinelle: add control flow documentation

 docs/manual/Makefile               |   6 +-
 docs/manual/cocci_syntax.tex       | 249 +++++++++++++++++++++++++++++++++++++
 docs/manual/flow1.c                |  10 ++
 docs/manual/flow2.c                |  11 ++
 tests/exists1.c                    |  20 +++
 tests/exists1.cocci                |   9 ++
 tests/exists1.res                  |  21 ++++
 tests/exists2.c                    |  21 ++++
 tests/exists2.cocci                |  13 ++
 tests/exists2.res                  |  23 ++++
 tests/exists3.c                    |  21 ++++
 tests/exists3.cocci                |  12 ++
 tests/exists3.res                  |  23 ++++
 tests/exists4.c                    |  22 ++++
 tests/exists4.cocci                |  13 ++
 tests/exists4.res                  |  21 ++++
 tests/remove-code-in-branch1.c     |   7 ++
 tests/remove-code-in-branch1.cocci |   4 +
 tests/remove-code-in-branch1.res   |   4 +
 19 files changed, 509 insertions(+), 1 deletion(-)
 create mode 100644 docs/manual/flow1.c
 create mode 100644 docs/manual/flow2.c
 create mode 100644 tests/exists1.c
 create mode 100644 tests/exists1.cocci
 create mode 100644 tests/exists1.res
 create mode 100644 tests/exists2.c
 create mode 100644 tests/exists2.cocci
 create mode 100644 tests/exists2.res
 create mode 100644 tests/exists3.c
 create mode 100644 tests/exists3.cocci
 create mode 100644 tests/exists3.res
 create mode 100644 tests/exists4.c
 create mode 100644 tests/exists4.cocci
 create mode 100644 tests/exists4.res
 create mode 100644 tests/remove-code-in-branch1.c
 create mode 100644 tests/remove-code-in-branch1.cocci
 create mode 100644 tests/remove-code-in-branch1.res

-- 
2.7.2

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

* [Cocci] [RFC 1/3] tests: add test to remove single statement from branch
  2016-05-18 21:42 [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests Luis R. Rodriguez
@ 2016-05-18 21:42 ` Luis R. Rodriguez
  2016-05-19 10:34   ` Julia Lawall
  2016-05-18 21:42 ` [Cocci] [RFC 2/3] tests: add basic series of tests for exists and forall Luis R. Rodriguez
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Luis R. Rodriguez @ 2016-05-18 21:42 UTC (permalink / raw)
  To: cocci

At leaset with coccinelle 1.0.4 this test fails with
two issues, one is the return statement is shifted,
another is debatable -- an empty branch statement is
left. This is funtional however its debatable if this
is desirable by default.

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 tests/remove-code-in-branch1.c     | 7 +++++++
 tests/remove-code-in-branch1.cocci | 4 ++++
 tests/remove-code-in-branch1.res   | 4 ++++
 3 files changed, 15 insertions(+)
 create mode 100644 tests/remove-code-in-branch1.c
 create mode 100644 tests/remove-code-in-branch1.cocci
 create mode 100644 tests/remove-code-in-branch1.res

diff --git a/tests/remove-code-in-branch1.c b/tests/remove-code-in-branch1.c
new file mode 100644
index 000000000000..83840bdd99ac
--- /dev/null
+++ b/tests/remove-code-in-branch1.c
@@ -0,0 +1,7 @@
+int main(void)
+{
+	if (a > 1)
+		c();
+
+	return 0;
+}
diff --git a/tests/remove-code-in-branch1.cocci b/tests/remove-code-in-branch1.cocci
new file mode 100644
index 000000000000..b3f03523ac92
--- /dev/null
+++ b/tests/remove-code-in-branch1.cocci
@@ -0,0 +1,4 @@
+ at r@
+@@
+
+-c();
diff --git a/tests/remove-code-in-branch1.res b/tests/remove-code-in-branch1.res
new file mode 100644
index 000000000000..31dbf45bf99c
--- /dev/null
+++ b/tests/remove-code-in-branch1.res
@@ -0,0 +1,4 @@
+int main(void)
+{
+	return 0;
+}
-- 
2.7.2

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

* [Cocci] [RFC 2/3] tests: add basic series of tests for exists and forall
  2016-05-18 21:42 [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests Luis R. Rodriguez
  2016-05-18 21:42 ` [Cocci] [RFC 1/3] tests: add test to remove single statement from branch Luis R. Rodriguez
@ 2016-05-18 21:42 ` Luis R. Rodriguez
  2016-05-19 10:35   ` Julia Lawall
  2016-05-18 21:42 ` [Cocci] [RFC 3/3] coccinelle: add control flow documentation Luis R. Rodriguez
  2016-05-19 10:30 ` [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests Julia Lawall
  3 siblings, 1 reply; 12+ messages in thread
From: Luis R. Rodriguez @ 2016-05-18 21:42 UTC (permalink / raw)
  To: cocci

This should not only help test but also demo use of exists
and forall.

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 tests/exists1.c     | 20 ++++++++++++++++++++
 tests/exists1.cocci |  9 +++++++++
 tests/exists1.res   | 21 +++++++++++++++++++++
 tests/exists2.c     | 21 +++++++++++++++++++++
 tests/exists2.cocci | 13 +++++++++++++
 tests/exists2.res   | 23 +++++++++++++++++++++++
 tests/exists3.c     | 21 +++++++++++++++++++++
 tests/exists3.cocci | 12 ++++++++++++
 tests/exists3.res   | 23 +++++++++++++++++++++++
 tests/exists4.c     | 22 ++++++++++++++++++++++
 tests/exists4.cocci | 13 +++++++++++++
 tests/exists4.res   | 21 +++++++++++++++++++++
 12 files changed, 219 insertions(+)
 create mode 100644 tests/exists1.c
 create mode 100644 tests/exists1.cocci
 create mode 100644 tests/exists1.res
 create mode 100644 tests/exists2.c
 create mode 100644 tests/exists2.cocci
 create mode 100644 tests/exists2.res
 create mode 100644 tests/exists3.c
 create mode 100644 tests/exists3.cocci
 create mode 100644 tests/exists3.res
 create mode 100644 tests/exists4.c
 create mode 100644 tests/exists4.cocci
 create mode 100644 tests/exists4.res

diff --git a/tests/exists1.c b/tests/exists1.c
new file mode 100644
index 000000000000..5cc37415bfef
--- /dev/null
+++ b/tests/exists1.c
@@ -0,0 +1,20 @@
+void bar(void)
+{
+	int a;
+
+	a = 300;
+	b();
+}
+
+int main(void)
+{
+	int a;
+
+	a = 10;
+	b();
+
+	c = 400;
+	c();
+
+	return 0;
+}
diff --git a/tests/exists1.cocci b/tests/exists1.cocci
new file mode 100644
index 000000000000..af95363de18f
--- /dev/null
+++ b/tests/exists1.cocci
@@ -0,0 +1,9 @@
+// this rule lacks exists, without exists, all control flows possible
+// must match the rule when + or - is used. In the case of exists1.c only
+// one possible control flow exists, the flow is completely linear.
+ at r@
+@@
+
+b();
+...
+-c();
diff --git a/tests/exists1.res b/tests/exists1.res
new file mode 100644
index 000000000000..cd83e4b2b6b1
--- /dev/null
+++ b/tests/exists1.res
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int bar(void)
+{
+	int a;
+
+	a = 300;
+	b();
+}
+
+int main(void)
+{
+	int a;
+
+	a = 10;
+	b();
+
+	c = 400;
+
+	return 0;
+}
diff --git a/tests/exists2.c b/tests/exists2.c
new file mode 100644
index 000000000000..486a8f5633d9
--- /dev/null
+++ b/tests/exists2.c
@@ -0,0 +1,21 @@
+void bar(void)
+{
+	int a;
+
+	a = 300;
+	b();
+}
+
+int main(void)
+{
+	int a;
+
+	a = 10;
+	b();
+
+	c = 400;
+	if (a > 5)
+		c();
+
+	return 0;
+}
diff --git a/tests/exists2.cocci b/tests/exists2.cocci
new file mode 100644
index 000000000000..576b3cd3af24
--- /dev/null
+++ b/tests/exists2.cocci
@@ -0,0 +1,13 @@
+// this rule lacks exists, without exists, all control flows possible
+// must match the rule. In the case of exists2.c two possible control
+// flows exists on main():
+// 1. b() --> a > 5 --> c();
+// 2. b() --> a <= 5 ---> no c();
+// Not all control flows match, so no changes are made.
+// To visualize the control graph use: spatch --control-flow exists2.c
+ at r@
+@@
+
+b();
+...
+-c();
diff --git a/tests/exists2.res b/tests/exists2.res
new file mode 100644
index 000000000000..9d6401eb7d05
--- /dev/null
+++ b/tests/exists2.res
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+int bar(void)
+{
+	int a;
+
+	a = 300;
+	b();
+}
+
+int main(void)
+{
+	int a;
+
+	a = 10;
+	b();
+
+	c = 400;
+	if (a > 5)
+		c();
+
+	return 0;
+}
diff --git a/tests/exists3.c b/tests/exists3.c
new file mode 100644
index 000000000000..486a8f5633d9
--- /dev/null
+++ b/tests/exists3.c
@@ -0,0 +1,21 @@
+void bar(void)
+{
+	int a;
+
+	a = 300;
+	b();
+}
+
+int main(void)
+{
+	int a;
+
+	a = 10;
+	b();
+
+	c = 400;
+	if (a > 5)
+		c();
+
+	return 0;
+}
diff --git a/tests/exists3.cocci b/tests/exists3.cocci
new file mode 100644
index 000000000000..64cb43aa8ec4
--- /dev/null
+++ b/tests/exists3.cocci
@@ -0,0 +1,12 @@
+// this rule uses exists, with it, the rule is successful if at least
+// one of the possible control flows possible match.
+// exists3.c has two possible control flows on main():
+// 1. b() --> a > 5 --> c();
+// 2. b() --> a <= 5 ---> no c();
+// The match on 1. enables the changes to take place.
+ at r exists @
+@@
+
+b();
+...
+-c();
diff --git a/tests/exists3.res b/tests/exists3.res
new file mode 100644
index 000000000000..f6b53c361fa5
--- /dev/null
+++ b/tests/exists3.res
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+int bar(void)
+{
+	int a;
+
+	a = 300;
+	b();
+}
+
+int main(void)
+{
+	int a;
+
+	a = 10;
+	b();
+
+	c = 400;
+	if (a > 5)
+		{}
+
+	return 0;
+}
diff --git a/tests/exists4.c b/tests/exists4.c
new file mode 100644
index 000000000000..0b3dab08e6e1
--- /dev/null
+++ b/tests/exists4.c
@@ -0,0 +1,22 @@
+void bar(void)
+{
+	int a;
+
+	a = 300;
+	b();
+	c();
+}
+
+int main(void)
+{
+	int a;
+
+	a = 10;
+	b();
+
+	c = 400;
+	if (a > 5)
+		c();
+
+	return 0;
+}
diff --git a/tests/exists4.cocci b/tests/exists4.cocci
new file mode 100644
index 000000000000..d80c71a9d3f3
--- /dev/null
+++ b/tests/exists4.cocci
@@ -0,0 +1,13 @@
+// this rule uses forall, with it, all control flows must match.
+//
+// The exists4.c was extended to add a c() in comparison to exists2.c
+// this is done to show that using forall will still have an effect
+// on bar() even though it does not match on main()
+//
+// This is the default behaviour when + or - is used as well.
+ at r forall@
+@@
+
+b();
+...
+-c();
diff --git a/tests/exists4.res b/tests/exists4.res
new file mode 100644
index 000000000000..486a8f5633d9
--- /dev/null
+++ b/tests/exists4.res
@@ -0,0 +1,21 @@
+void bar(void)
+{
+	int a;
+
+	a = 300;
+	b();
+}
+
+int main(void)
+{
+	int a;
+
+	a = 10;
+	b();
+
+	c = 400;
+	if (a > 5)
+		c();
+
+	return 0;
+}
-- 
2.7.2

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

* [Cocci] [RFC 3/3] coccinelle: add control flow documentation
  2016-05-18 21:42 [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests Luis R. Rodriguez
  2016-05-18 21:42 ` [Cocci] [RFC 1/3] tests: add test to remove single statement from branch Luis R. Rodriguez
  2016-05-18 21:42 ` [Cocci] [RFC 2/3] tests: add basic series of tests for exists and forall Luis R. Rodriguez
@ 2016-05-18 21:42 ` Luis R. Rodriguez
  2016-05-19  7:36   ` SF Markus Elfring
  2016-05-19 10:30 ` [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests Julia Lawall
  3 siblings, 1 reply; 12+ messages in thread
From: Luis R. Rodriguez @ 2016-05-18 21:42 UTC (permalink / raw)
  To: cocci

From: "Luis R. Rodriguez" <mcgrof@suse.com>

Add control flow documentation.

Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
---
 docs/manual/Makefile         |   6 +-
 docs/manual/cocci_syntax.tex | 249 +++++++++++++++++++++++++++++++++++++++++++
 docs/manual/flow1.c          |  10 ++
 docs/manual/flow2.c          |  11 ++
 4 files changed, 275 insertions(+), 1 deletion(-)
 create mode 100644 docs/manual/flow1.c
 create mode 100644 docs/manual/flow2.c

diff --git a/docs/manual/Makefile b/docs/manual/Makefile
index 98e397ac5b69..c0a28bd9bd4b 100644
--- a/docs/manual/Makefile
+++ b/docs/manual/Makefile
@@ -36,7 +36,11 @@ manual.pdf: $(SRC)
 	$(PDFLATEX_CMD) manual.tex
 	$(PDFLATEX_CMD) manual.tex
 
-main_grammar.pdf: main_grammar.tex cocci_syntax.tex  macros_listing_cocci.tex macros_grammar.tex macros_common.tex examples.tex tips.tex
+main_grammar.pdf: main_grammar.tex cocci_syntax.tex flow1.c macros_listing_cocci.tex macros_grammar.tex macros_common.tex examples.tex tips.tex
+	#spatch --control-flow-to-file flow1.c
+	#spatch --control-flow-to-file flow2.c
+	#dot -Gsize="0.5,0.5" -Tpdf flow1:main.dot > flow1.pdf
+	#dot -Gsize="0.5,0.5" -Tpdf flow1:main.dot > flow2.pdf
 	$(PDFLATEX_CMD) main_grammar.tex
 	$(PDFLATEX_CMD) main_grammar.tex
 
diff --git a/docs/manual/cocci_syntax.tex b/docs/manual/cocci_syntax.tex
index 2c0f622251f6..4c0c3b3b84b1 100644
--- a/docs/manual/cocci_syntax.tex
+++ b/docs/manual/cocci_syntax.tex
@@ -584,6 +584,255 @@ rule is only applied if all of the metavariables for which there are no
 default values have values.  See demos/defaultscript.cocci for examples of
 the use of this feature.
 
+\section{Control Flow}
+
+Rules describe a property which Coccinelle must match, when the property
+described is matched the rule is considered successful. Program control
+flows vary, a control flow describes a possible run time path taken by
+a program.
+
+When using Coccinelle you often want to be able to express certain code
+within certain types of control flows. Typically you will use ellipses
+("...") to indicate to Coccinelle anything can be present between
+consecutive statements. For instance the following SmPL patch tells Coccinelle
+that rule r0 wishes to remove call calls to function c().
+
+\begin{center}
+\begin{tabular}{c}
+\begin{lstlisting}[language=Cocci]
+ at r0@
+@@
+
+-c();
+
+\end{lstlisting}\\
+\end{tabular}
+\end{center}
+
+The context of the rule provides no other guidlines to Coccinelle to hint
+about any possible control flow other than this is a statement, and that
+c() must be called. We can modify the required control flow required for
+this rule by providing additional requirements and usign ellipses in between.
+For instance, if we only wanted to remove call calls to c() but which also
+had a prior call to foo() we'd use the following SmPL patch:
+
+\begin{center}
+\begin{tabular}{c}
+\begin{lstlisting}[language=Cocci]
+ at r1@
+@@
+
+foo()
+...
+-c();
+\end{lstlisting}\\
+\end{tabular}
+\end{center}
+
+There are two possible modifiers to the control flow for ellipses, one
+is to annotate that statements in between ellipses are optional (<... ...>),
+or that the statements in between must be present at leaset once (<+... ...+).
+For instance the following SmPL patch tells Coccinelle to remove all
+calls to c() but foo() must be present at least once.
+
+\begin{center}
+\begin{tabular}{c}
+\begin{lstlisting}[language=Cocci]
+@r2@
+@@
+
+<+...
+foo()
+...+>
+-c();
+
+\end{lstlisting}\\
+\end{tabular}
+\end{center}
+
+Alternatively, if you wanted to be explicit that foo() was optional,
+you could use the following SmPL rule.
+
+\begin{center}
+\begin{tabular}{c}
+\begin{lstlisting}[language=Cocci]
+ at r3@
+@@
+
+<...
+foo()
+...>
+-c();
+
+\end{lstlisting}\\
+\end{tabular}
+\end{center}
+
+Let's consider some sample code to review, this is flow1.c.
+
+\begin{center}
+\begin{tabular}{c}
+\begin{lstlisting}[language=C]
+
+int main(void)
+{
+	int ret, a = 2;
+
+	a = foo(a);
+	ret = bar(a);
+	c();
+
+	return ret;
+}
+\end{lstlisting}\\
+\end{tabular}
+\end{center}
+
+Applying the SmPL rule r0 to flow1.c would remove the c() line as the control
+flow provides no specific context requirements. Applying rule r1 would also
+succeed as the call to foo() is present. Likewise rules r2 and r3 would also
+succeed. If the foo() call is removed from flow1.c only rules r0 and r3 would
+succeed, as foo() would not be present and only rules r0 and r3 allow for
+foo() to not be present.
+
+The program flow1.1 has a linear control flow, it has no branches. The main
+routine has a McCabe cyclomatic complexity of 1. The McCabe cyclomatic
+complexity can be computed using
+{\tt pmccabe} (https://www.gnu.org/software/complexity/manual/html\_node/pmccabe-parsing.html).
+
+\begin{center}
+\begin{tabular}{c}
+\begin{lstlisting}[language=C]
+pmccabe /flow1.c
+1       1       5       1       10      flow1.c(1): main
+\end{lstlisting}\\
+\end{tabular}
+\end{center}
+
+Since programs can use branches, often times you may also wish to annotate
+requirements for control flows in consideration for branches, for when
+the McCabe cyclomatic complexity is > 1. The following program, flow2.c,
+enables the control flow to diverge on line 7 due to the branch, if (a) --
+one control flow possible is if (a) is true, another when if (a) is false.
+
+\begin{center}
+\begin{tabular}{c}
+\begin{lstlisting}[language=C]
+int main(void)
+{
+	int ret, a = 2;
+
+	a = foo(a);
+	ret = bar(a);
+	if (a)
+		c();
+
+	return ret;
+}
+\end{lstlisting}\\
+\end{tabular}
+\end{center}
+
+This program has a McCabe cyclomatic complexity of 2.
+
+\begin{center}
+\begin{tabular}{c}
+\begin{lstlisting}[language=C]
+pmccabe flow2.c
+2       2       6       1       11      flow2.c(1): main
+\end{lstlisting}\\
+\end{tabular}
+\end{center}
+
+Using the McCabe cyclomatic complexity is one way to get an idea of
+the complexity of the control graph for a function, another way is
+to visualize all possible paths. Coccinelle provides a way to visualize
+control flows of programs, this however requires {\tt dot}
+(http://www.graphviz.org/) and {\tt gv} to be installed (typically provided
+by a package called graphviz). To visualize control flow or a program
+using Coccinelle you use:
+
+\begin{center}
+\begin{tabular}{c}
+spatch --control-flow-to-file flow1.c
+spatch --control-flow-to-file flow2.c
+\end{tabular}
+\end{center}
+
+Below are the two generated control flow graphs for flow1.c and flow2.c
+respectively.
+
+%\begin{figure}
+%	\[\includegraphics[width=\linewidth]{flow1.pdf}\]
+%	\caption{Linear flow example}
+%	\label{devmodel}
+%\end{figure}
+
+%\begin{figure}
+%	\[\includegraphics[width=\linewidth]{flow2.pdf}\]
+%	\caption{Linear flow example}
+%	\label{devmodel}
+%\end{figure}
+
+Behind the scenes this generates a dot file and uses gv to generate
+a PDF file for viewing. To generate and inspect these manually you
+can use the following:
+
+\begin{center}
+\begin{tabular}{c}
+spatch --control-flow-to-file flow2.c
+dot -Tpdf flow1:main.dot > flow1.pdf
+\end{tabular}
+\end{center}
+
+By default properties described in a rule must match all control
+flows possible within a code section being inspected by Coccinelle.
+So for instance, in the following SmPL patch rule r1 would match all
+the control flow possible on flow1.c as its linear, however it would
+not match the control possible on flow2.c. The rule r1 would not
+be successful in flow2.c
+
+\begin{center}
+\begin{tabular}{c}
+\begin{lstlisting}[language=Cocci]
+ at r1@
+@@
+
+foo()
+...
+-c();
+
+\end{lstlisting}\\
+\end{tabular}
+\end{center}
+
+The default control flow can be modified by using the keyword "exists"
+following the rule name. In the following SmPL patch the rule r2 would
+be successful on both flow1.c and flow2.c
+
+\begin{center}
+\begin{tabular}{c}
+\begin{lstlisting}[language=Cocci]
+ at r2 exists@
+@@
+
+foo()
+...
+-c();
+
+\end{lstlisting}\\
+\end{tabular}
+\end{center}
+
+If the rule is followed by the "forall" keyword, then all control flow
+paths must match in order for the rule to succeed. By default when one
+has "-" and "+", or when one has no annotations at all and only script
+code, ellipses ("...") uses the forall semantics.  And when one uses
+context annotation ("*"), the ellipses ("...") uses the exists semantics.
+Using the keyword "forall" or "exists" in the rule header affects
+all ellipses ("...") uses in the rule. You can also annotate each
+ellipses ("...") with "when exists" or "when forall" individually.
+
 \section{Transformation}
 
 The transformation specification essentially has the form of C code, except
diff --git a/docs/manual/flow1.c b/docs/manual/flow1.c
new file mode 100644
index 000000000000..43e45ed32843
--- /dev/null
+++ b/docs/manual/flow1.c
@@ -0,0 +1,10 @@
+int main(void)
+{
+	int ret, a = 2;
+
+	a = foo(a);
+	ret = bar(a);
+	c();
+
+	return ret;
+}
diff --git a/docs/manual/flow2.c b/docs/manual/flow2.c
new file mode 100644
index 000000000000..bb0d95e4c310
--- /dev/null
+++ b/docs/manual/flow2.c
@@ -0,0 +1,11 @@
+int main(void)
+{
+	int ret, a = 2;
+
+	a = foo(a);
+	ret = bar(a);
+	if (a)
+		c();
+
+	return ret;
+}
-- 
2.7.2

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

* [Cocci] [RFC 3/3] coccinelle: add control flow documentation
  2016-05-18 21:42 ` [Cocci] [RFC 3/3] coccinelle: add control flow documentation Luis R. Rodriguez
@ 2016-05-19  7:36   ` SF Markus Elfring
  2016-05-19 22:53     ` Luis R. Rodriguez
  0 siblings, 1 reply; 12+ messages in thread
From: SF Markus Elfring @ 2016-05-19  7:36 UTC (permalink / raw)
  To: cocci

> +this rule by providing additional requirements and usign ellipses in between.

Will the wording "using" be better here?


> +or that the statements in between must be present at leaset once (<+... ...+).

Please fix another typo: least.


How do you think about to add any references (or links) for this functionality?

Regards,
Markus

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

* [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests
  2016-05-18 21:42 [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests Luis R. Rodriguez
                   ` (2 preceding siblings ...)
  2016-05-18 21:42 ` [Cocci] [RFC 3/3] coccinelle: add control flow documentation Luis R. Rodriguez
@ 2016-05-19 10:30 ` Julia Lawall
  2016-05-19 22:45   ` Luis R. Rodriguez
  3 siblings, 1 reply; 12+ messages in thread
From: Julia Lawall @ 2016-05-19 10:30 UTC (permalink / raw)
  To: cocci



On Wed, 18 May 2016, Luis R. Rodriguez wrote:

> This adds some initial control flow documentation, I wanted to add some
> basic control flow diagrams as well with self generated diagrams from
> Coccinelle however I had issues figuring out what to use with dot to
> make it fit within the margins. We can skip that, but I thought adding it
> would also help document support and example use case for that feature
> as well.
>
> The tests/remove-code-in-branch1* was more collateral effort as I
> saw a removal of a statement from a branch that only had one statement
> left an empty brace. I hope we can discuss here what the expected
> outcome should be. I figured removing the empty code may be an
> optional optimization, however it was still unclear how to resolve this
> if that's desirable. Would it be up to Coccinelle or would that be
> an optional isomorphism ? I noticed no current isomorphisms seem to
> remove code like this so it was unclear what to do.
>
> The following rule for instnace can deal with it.
>
> @ remove_empty_branch @
> expression E;
> @@
>
> -if (E) {}

I don't think this is desirable as a general rule.  E might contain
function calls that perform side effects.

julia

>
> Luis R. Rodriguez (3):
>   tests: add test to remove single statement from branch
>   tests: add basic series of tests for exists and forall
>   coccinelle: add control flow documentation
>
>  docs/manual/Makefile               |   6 +-
>  docs/manual/cocci_syntax.tex       | 249 +++++++++++++++++++++++++++++++++++++
>  docs/manual/flow1.c                |  10 ++
>  docs/manual/flow2.c                |  11 ++
>  tests/exists1.c                    |  20 +++
>  tests/exists1.cocci                |   9 ++
>  tests/exists1.res                  |  21 ++++
>  tests/exists2.c                    |  21 ++++
>  tests/exists2.cocci                |  13 ++
>  tests/exists2.res                  |  23 ++++
>  tests/exists3.c                    |  21 ++++
>  tests/exists3.cocci                |  12 ++
>  tests/exists3.res                  |  23 ++++
>  tests/exists4.c                    |  22 ++++
>  tests/exists4.cocci                |  13 ++
>  tests/exists4.res                  |  21 ++++
>  tests/remove-code-in-branch1.c     |   7 ++
>  tests/remove-code-in-branch1.cocci |   4 +
>  tests/remove-code-in-branch1.res   |   4 +
>  19 files changed, 509 insertions(+), 1 deletion(-)
>  create mode 100644 docs/manual/flow1.c
>  create mode 100644 docs/manual/flow2.c
>  create mode 100644 tests/exists1.c
>  create mode 100644 tests/exists1.cocci
>  create mode 100644 tests/exists1.res
>  create mode 100644 tests/exists2.c
>  create mode 100644 tests/exists2.cocci
>  create mode 100644 tests/exists2.res
>  create mode 100644 tests/exists3.c
>  create mode 100644 tests/exists3.cocci
>  create mode 100644 tests/exists3.res
>  create mode 100644 tests/exists4.c
>  create mode 100644 tests/exists4.cocci
>  create mode 100644 tests/exists4.res
>  create mode 100644 tests/remove-code-in-branch1.c
>  create mode 100644 tests/remove-code-in-branch1.cocci
>  create mode 100644 tests/remove-code-in-branch1.res
>
> --
> 2.7.2
>
> _______________________________________________
> Cocci mailing list
> Cocci at systeme.lip6.fr
> https://systeme.lip6.fr/mailman/listinfo/cocci
>

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

* [Cocci] [RFC 1/3] tests: add test to remove single statement from branch
  2016-05-18 21:42 ` [Cocci] [RFC 1/3] tests: add test to remove single statement from branch Luis R. Rodriguez
@ 2016-05-19 10:34   ` Julia Lawall
  2016-05-19 22:46     ` Luis R. Rodriguez
  0 siblings, 1 reply; 12+ messages in thread
From: Julia Lawall @ 2016-05-19 10:34 UTC (permalink / raw)
  To: cocci

On Wed, 18 May 2016, Luis R. Rodriguez wrote:

> At leaset with coccinelle 1.0.4 this test fails with
> two issues, one is the return statement is shifted,
> another is debatable -- an empty branch statement is
> left. This is funtional however its debatable if this
> is desirable by default.

The return statement should not move, but the if should not be removed
either.  Please send a second version.

Note the type mentioned by Markus as well (leaset, funtional)

thanks,
julia

>
> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> ---
>  tests/remove-code-in-branch1.c     | 7 +++++++
>  tests/remove-code-in-branch1.cocci | 4 ++++
>  tests/remove-code-in-branch1.res   | 4 ++++
>  3 files changed, 15 insertions(+)
>  create mode 100644 tests/remove-code-in-branch1.c
>  create mode 100644 tests/remove-code-in-branch1.cocci
>  create mode 100644 tests/remove-code-in-branch1.res
>
> diff --git a/tests/remove-code-in-branch1.c b/tests/remove-code-in-branch1.c
> new file mode 100644
> index 000000000000..83840bdd99ac
> --- /dev/null
> +++ b/tests/remove-code-in-branch1.c
> @@ -0,0 +1,7 @@
> +int main(void)
> +{
> +	if (a > 1)
> +		c();
> +
> +	return 0;
> +}
> diff --git a/tests/remove-code-in-branch1.cocci b/tests/remove-code-in-branch1.cocci
> new file mode 100644
> index 000000000000..b3f03523ac92
> --- /dev/null
> +++ b/tests/remove-code-in-branch1.cocci
> @@ -0,0 +1,4 @@
> + at r@
> +@@
> +
> +-c();
> diff --git a/tests/remove-code-in-branch1.res b/tests/remove-code-in-branch1.res
> new file mode 100644
> index 000000000000..31dbf45bf99c
> --- /dev/null
> +++ b/tests/remove-code-in-branch1.res
> @@ -0,0 +1,4 @@
> +int main(void)
> +{
> +	return 0;
> +}
> --
> 2.7.2
>
> _______________________________________________
> Cocci mailing list
> Cocci at systeme.lip6.fr
> https://systeme.lip6.fr/mailman/listinfo/cocci
>

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

* [Cocci] [RFC 2/3] tests: add basic series of tests for exists and forall
  2016-05-18 21:42 ` [Cocci] [RFC 2/3] tests: add basic series of tests for exists and forall Luis R. Rodriguez
@ 2016-05-19 10:35   ` Julia Lawall
  2016-05-19 22:47     ` Luis R. Rodriguez
  0 siblings, 1 reply; 12+ messages in thread
From: Julia Lawall @ 2016-05-19 10:35 UTC (permalink / raw)
  To: cocci

On Wed, 18 May 2016, Luis R. Rodriguez wrote:

> This should not only help test but also demo use of exists
> and forall.

Thanks for the examples.  But should it go in tests or in demos?  Demos
could be better if the main purpose is to help the user understand exists
and forall.

julia

>
> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> ---
>  tests/exists1.c     | 20 ++++++++++++++++++++
>  tests/exists1.cocci |  9 +++++++++
>  tests/exists1.res   | 21 +++++++++++++++++++++
>  tests/exists2.c     | 21 +++++++++++++++++++++
>  tests/exists2.cocci | 13 +++++++++++++
>  tests/exists2.res   | 23 +++++++++++++++++++++++
>  tests/exists3.c     | 21 +++++++++++++++++++++
>  tests/exists3.cocci | 12 ++++++++++++
>  tests/exists3.res   | 23 +++++++++++++++++++++++
>  tests/exists4.c     | 22 ++++++++++++++++++++++
>  tests/exists4.cocci | 13 +++++++++++++
>  tests/exists4.res   | 21 +++++++++++++++++++++
>  12 files changed, 219 insertions(+)
>  create mode 100644 tests/exists1.c
>  create mode 100644 tests/exists1.cocci
>  create mode 100644 tests/exists1.res
>  create mode 100644 tests/exists2.c
>  create mode 100644 tests/exists2.cocci
>  create mode 100644 tests/exists2.res
>  create mode 100644 tests/exists3.c
>  create mode 100644 tests/exists3.cocci
>  create mode 100644 tests/exists3.res
>  create mode 100644 tests/exists4.c
>  create mode 100644 tests/exists4.cocci
>  create mode 100644 tests/exists4.res
>
> diff --git a/tests/exists1.c b/tests/exists1.c
> new file mode 100644
> index 000000000000..5cc37415bfef
> --- /dev/null
> +++ b/tests/exists1.c
> @@ -0,0 +1,20 @@
> +void bar(void)
> +{
> +	int a;
> +
> +	a = 300;
> +	b();
> +}
> +
> +int main(void)
> +{
> +	int a;
> +
> +	a = 10;
> +	b();
> +
> +	c = 400;
> +	c();
> +
> +	return 0;
> +}
> diff --git a/tests/exists1.cocci b/tests/exists1.cocci
> new file mode 100644
> index 000000000000..af95363de18f
> --- /dev/null
> +++ b/tests/exists1.cocci
> @@ -0,0 +1,9 @@
> +// this rule lacks exists, without exists, all control flows possible
> +// must match the rule when + or - is used. In the case of exists1.c only
> +// one possible control flow exists, the flow is completely linear.
> + at r@
> +@@
> +
> +b();
> +...
> +-c();
> diff --git a/tests/exists1.res b/tests/exists1.res
> new file mode 100644
> index 000000000000..cd83e4b2b6b1
> --- /dev/null
> +++ b/tests/exists1.res
> @@ -0,0 +1,21 @@
> +#include <stdio.h>
> +
> +int bar(void)
> +{
> +	int a;
> +
> +	a = 300;
> +	b();
> +}
> +
> +int main(void)
> +{
> +	int a;
> +
> +	a = 10;
> +	b();
> +
> +	c = 400;
> +
> +	return 0;
> +}
> diff --git a/tests/exists2.c b/tests/exists2.c
> new file mode 100644
> index 000000000000..486a8f5633d9
> --- /dev/null
> +++ b/tests/exists2.c
> @@ -0,0 +1,21 @@
> +void bar(void)
> +{
> +	int a;
> +
> +	a = 300;
> +	b();
> +}
> +
> +int main(void)
> +{
> +	int a;
> +
> +	a = 10;
> +	b();
> +
> +	c = 400;
> +	if (a > 5)
> +		c();
> +
> +	return 0;
> +}
> diff --git a/tests/exists2.cocci b/tests/exists2.cocci
> new file mode 100644
> index 000000000000..576b3cd3af24
> --- /dev/null
> +++ b/tests/exists2.cocci
> @@ -0,0 +1,13 @@
> +// this rule lacks exists, without exists, all control flows possible
> +// must match the rule. In the case of exists2.c two possible control
> +// flows exists on main():
> +// 1. b() --> a > 5 --> c();
> +// 2. b() --> a <= 5 ---> no c();
> +// Not all control flows match, so no changes are made.
> +// To visualize the control graph use: spatch --control-flow exists2.c
> + at r@
> +@@
> +
> +b();
> +...
> +-c();
> diff --git a/tests/exists2.res b/tests/exists2.res
> new file mode 100644
> index 000000000000..9d6401eb7d05
> --- /dev/null
> +++ b/tests/exists2.res
> @@ -0,0 +1,23 @@
> +#include <stdio.h>
> +
> +int bar(void)
> +{
> +	int a;
> +
> +	a = 300;
> +	b();
> +}
> +
> +int main(void)
> +{
> +	int a;
> +
> +	a = 10;
> +	b();
> +
> +	c = 400;
> +	if (a > 5)
> +		c();
> +
> +	return 0;
> +}
> diff --git a/tests/exists3.c b/tests/exists3.c
> new file mode 100644
> index 000000000000..486a8f5633d9
> --- /dev/null
> +++ b/tests/exists3.c
> @@ -0,0 +1,21 @@
> +void bar(void)
> +{
> +	int a;
> +
> +	a = 300;
> +	b();
> +}
> +
> +int main(void)
> +{
> +	int a;
> +
> +	a = 10;
> +	b();
> +
> +	c = 400;
> +	if (a > 5)
> +		c();
> +
> +	return 0;
> +}
> diff --git a/tests/exists3.cocci b/tests/exists3.cocci
> new file mode 100644
> index 000000000000..64cb43aa8ec4
> --- /dev/null
> +++ b/tests/exists3.cocci
> @@ -0,0 +1,12 @@
> +// this rule uses exists, with it, the rule is successful if at least
> +// one of the possible control flows possible match.
> +// exists3.c has two possible control flows on main():
> +// 1. b() --> a > 5 --> c();
> +// 2. b() --> a <= 5 ---> no c();
> +// The match on 1. enables the changes to take place.
> + at r exists @
> +@@
> +
> +b();
> +...
> +-c();
> diff --git a/tests/exists3.res b/tests/exists3.res
> new file mode 100644
> index 000000000000..f6b53c361fa5
> --- /dev/null
> +++ b/tests/exists3.res
> @@ -0,0 +1,23 @@
> +#include <stdio.h>
> +
> +int bar(void)
> +{
> +	int a;
> +
> +	a = 300;
> +	b();
> +}
> +
> +int main(void)
> +{
> +	int a;
> +
> +	a = 10;
> +	b();
> +
> +	c = 400;
> +	if (a > 5)
> +		{}
> +
> +	return 0;
> +}
> diff --git a/tests/exists4.c b/tests/exists4.c
> new file mode 100644
> index 000000000000..0b3dab08e6e1
> --- /dev/null
> +++ b/tests/exists4.c
> @@ -0,0 +1,22 @@
> +void bar(void)
> +{
> +	int a;
> +
> +	a = 300;
> +	b();
> +	c();
> +}
> +
> +int main(void)
> +{
> +	int a;
> +
> +	a = 10;
> +	b();
> +
> +	c = 400;
> +	if (a > 5)
> +		c();
> +
> +	return 0;
> +}
> diff --git a/tests/exists4.cocci b/tests/exists4.cocci
> new file mode 100644
> index 000000000000..d80c71a9d3f3
> --- /dev/null
> +++ b/tests/exists4.cocci
> @@ -0,0 +1,13 @@
> +// this rule uses forall, with it, all control flows must match.
> +//
> +// The exists4.c was extended to add a c() in comparison to exists2.c
> +// this is done to show that using forall will still have an effect
> +// on bar() even though it does not match on main()
> +//
> +// This is the default behaviour when + or - is used as well.
> + at r forall@
> +@@
> +
> +b();
> +...
> +-c();
> diff --git a/tests/exists4.res b/tests/exists4.res
> new file mode 100644
> index 000000000000..486a8f5633d9
> --- /dev/null
> +++ b/tests/exists4.res
> @@ -0,0 +1,21 @@
> +void bar(void)
> +{
> +	int a;
> +
> +	a = 300;
> +	b();
> +}
> +
> +int main(void)
> +{
> +	int a;
> +
> +	a = 10;
> +	b();
> +
> +	c = 400;
> +	if (a > 5)
> +		c();
> +
> +	return 0;
> +}
> --
> 2.7.2
>
> _______________________________________________
> Cocci mailing list
> Cocci at systeme.lip6.fr
> https://systeme.lip6.fr/mailman/listinfo/cocci
>

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

* [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests
  2016-05-19 10:30 ` [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests Julia Lawall
@ 2016-05-19 22:45   ` Luis R. Rodriguez
  0 siblings, 0 replies; 12+ messages in thread
From: Luis R. Rodriguez @ 2016-05-19 22:45 UTC (permalink / raw)
  To: cocci

On Thu, May 19, 2016 at 12:30:06PM +0200, Julia Lawall wrote:
> 
> 
> On Wed, 18 May 2016, Luis R. Rodriguez wrote:
> 
> > This adds some initial control flow documentation, I wanted to add some
> > basic control flow diagrams as well with self generated diagrams from
> > Coccinelle however I had issues figuring out what to use with dot to
> > make it fit within the margins. We can skip that, but I thought adding it
> > would also help document support and example use case for that feature
> > as well.
> >
> > The tests/remove-code-in-branch1* was more collateral effort as I
> > saw a removal of a statement from a branch that only had one statement
> > left an empty brace. I hope we can discuss here what the expected
> > outcome should be. I figured removing the empty code may be an
> > optional optimization, however it was still unclear how to resolve this
> > if that's desirable. Would it be up to Coccinelle or would that be
> > an optional isomorphism ? I noticed no current isomorphisms seem to
> > remove code like this so it was unclear what to do.
> >
> > The following rule for instnace can deal with it.
> >
> > @ remove_empty_branch @
> > expression E;
> > @@
> >
> > -if (E) {}
> 
> I don't think this is desirable as a general rule.  E might contain
> function calls that perform side effects.

Ah, yes good point.

  Luis

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

* [Cocci] [RFC 1/3] tests: add test to remove single statement from branch
  2016-05-19 10:34   ` Julia Lawall
@ 2016-05-19 22:46     ` Luis R. Rodriguez
  0 siblings, 0 replies; 12+ messages in thread
From: Luis R. Rodriguez @ 2016-05-19 22:46 UTC (permalink / raw)
  To: cocci

On Thu, May 19, 2016 at 12:34:09PM +0200, Julia Lawall wrote:
> On Wed, 18 May 2016, Luis R. Rodriguez wrote:
> 
> > At leaset with coccinelle 1.0.4 this test fails with
> > two issues, one is the return statement is shifted,
> > another is debatable -- an empty branch statement is
> > left. This is funtional however its debatable if this
> > is desirable by default.
> 
> The return statement should not move,

Great!
> but the if should not be removed either. 

Agreed now..


> Please send a second version.

Will do!

> Note the type mentioned by Markus as well (leaset, funtional)

Sure thing.

  Luis

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

* [Cocci] [RFC 2/3] tests: add basic series of tests for exists and forall
  2016-05-19 10:35   ` Julia Lawall
@ 2016-05-19 22:47     ` Luis R. Rodriguez
  0 siblings, 0 replies; 12+ messages in thread
From: Luis R. Rodriguez @ 2016-05-19 22:47 UTC (permalink / raw)
  To: cocci

On Thu, May 19, 2016 at 12:35:58PM +0200, Julia Lawall wrote:
> On Wed, 18 May 2016, Luis R. Rodriguez wrote:
> 
> > This should not only help test but also demo use of exists
> > and forall.
> 
> Thanks for the examples.  But should it go in tests or in demos?  Demos
> could be better if the main purpose is to help the user understand exists
> and forall.

Sure thing, will move!

  Luis

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

* [Cocci] [RFC 3/3] coccinelle: add control flow documentation
  2016-05-19  7:36   ` SF Markus Elfring
@ 2016-05-19 22:53     ` Luis R. Rodriguez
  0 siblings, 0 replies; 12+ messages in thread
From: Luis R. Rodriguez @ 2016-05-19 22:53 UTC (permalink / raw)
  To: cocci

On Thu, May 19, 2016 at 09:36:50AM +0200, SF Markus Elfring wrote:
> > +this rule by providing additional requirements and usign ellipses in between.
> 
> Will the wording "using" be better here?

Fixed.

> > +or that the statements in between must be present at leaset once (<+... ...+).
> 
> Please fix another typo: least.

Fixed.

> How do you think about to add any references (or links) for this functionality?

Please feel free to follow up with patches, preferably examples.

  Luis

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

end of thread, other threads:[~2016-05-19 22:53 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-18 21:42 [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests Luis R. Rodriguez
2016-05-18 21:42 ` [Cocci] [RFC 1/3] tests: add test to remove single statement from branch Luis R. Rodriguez
2016-05-19 10:34   ` Julia Lawall
2016-05-19 22:46     ` Luis R. Rodriguez
2016-05-18 21:42 ` [Cocci] [RFC 2/3] tests: add basic series of tests for exists and forall Luis R. Rodriguez
2016-05-19 10:35   ` Julia Lawall
2016-05-19 22:47     ` Luis R. Rodriguez
2016-05-18 21:42 ` [Cocci] [RFC 3/3] coccinelle: add control flow documentation Luis R. Rodriguez
2016-05-19  7:36   ` SF Markus Elfring
2016-05-19 22:53     ` Luis R. Rodriguez
2016-05-19 10:30 ` [Cocci] [RFC 0/3] coccinelle: add initial control flow documentation and extend tests Julia Lawall
2016-05-19 22:45   ` Luis R. Rodriguez

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.