From: elfring@users.sourceforge.net (SF Markus Elfring)
To: cocci@systeme.lip6.fr
Subject: [Cocci] Finding function implementations that call only a single function.
Date: Fri, 05 Dec 2014 21:05:03 +0100 [thread overview]
Message-ID: <54820FEF.4080901@users.sourceforge.net> (raw)
In-Reply-To: <alpine.DEB.2.10.1412051633240.2360@hadrien>
> OK, you hve two choices:
>
> 1. Use the position variables
I might consider their use more for other data processing tasks.
> 2. Extend Coccinelle to handle constraints on types
Would you like to acknowledge that this implementation area
is still an open issue?
https://github.com/coccinelle/coccinelle/issues/32
How do you think about do document corresponding limitations?
> Or I guess a third choice which is to use some other tool.
I can also fiddle with SmPL rules which try to circumvent current
software limitations as a fourth choice, can't we?
I guess that it should work at least to filter on function
implementations which call only a single function.
The missing support for constraints on metavariables with
the data type "type" might not really matter in this specific
use case.
Example:
@non_void_single_function_call@
identifier caller, input, result, work;
type data_type, input_type, return_type;
@@
*return_type caller(..., input_type input, ...)
{
(
return work(input);
|
data_type result = work(input);
return result;
)
}
elfring at Sonne:~/Projekte/Coccinelle/Probe> spatch.opt -sp-file find_non-void_function2.cocci /usr/src/linux-stable/drivers/gpu/drm/ast/ast_ttm.c
init_defs_builtins: /usr/local/share/coccinelle/standard.h
HANDLING: /usr/src/linux-stable/drivers/gpu/drm/ast/ast_ttm.c
diff =
--- /usr/src/linux-stable/drivers/gpu/drm/ast/ast_ttm.c
+++ /tmp/cocci-output-20396-ddaa9b-ast_ttm.c
@@ -225,7 +225,6 @@ static struct ttm_tt *ast_ttm_tt_create(
return tt;
}
-static int ast_ttm_tt_populate(struct ttm_tt *ttm)
{
return ttm_pool_populate(ttm);
}
A wrapper function was found here which has got also the property "static".
I am trying to improve my source code analysis scripts especially for
this function type.
How do you think about the following differences in the results?
elfring at Sonne:~/Projekte/Coccinelle/Probe> spatch.opt -sp-file list_functions_with_single_function_call3.cocci /usr/src/linux-stable/drivers/gpu/drm/ast/ast_ttm.c
init_defs_builtins: /usr/local/share/coccinelle/standard.h
warning: void_find_static: inherited metavariable caller not used in the -, +, or context code
warning: non_void_find_static: inherited metavariable caller not used in the -, +, or context code
HANDLING: /usr/src/linux-stable/drivers/gpu/drm/ast/ast_ttm.c
static|function|"data type"|"parameter"|"source file"|line|column
0|ast_ttm_tt_unpopulate|"struct ttm_tt *"|ttm|"/usr/src/linux-stable/drivers/gpu/drm/ast/ast_ttm.c"|233|13
elfring at Sonne:~/Projekte/Coccinelle/Probe> spatch.opt -sp-file list_functions_with_single_function_call4.cocci /usr/src/linux-stable/drivers/gpu/drm/ast/ast_ttm.c
init_defs_builtins: /usr/local/share/coccinelle/standard.h
warning: find_static: inherited metavariable caller not used in the -, +, or context code
HANDLING: /usr/src/linux-stable/drivers/gpu/drm/ast/ast_ttm.c
static|function|"data type"|"parameter"|"source file"|line|column
0|ast_ttm_tt_populate|"struct ttm_tt *"|ttm|"/usr/src/linux-stable/drivers/gpu/drm/ast/ast_ttm.c"|228|12
0|ast_ttm_tt_unpopulate|"struct ttm_tt *"|ttm|"/usr/src/linux-stable/drivers/gpu/drm/ast/ast_ttm.c"|233|13
* Both approaches should find more functions here, shouldn't they?
(See attachments ...)
* It seems that my python function "store_static" is not called so far.
Is that strange?
Regards,
Markus
-------------- next part --------------
@initialize:python@
@@
import sys
import sqlite3 as SQLite
connection = SQLite.connect(":memory:")
c = connection.cursor()
c.execute("""
create table positions
(static integer default 0,
function text,
data_type text,
parameter text,
source_file text,
line integer,
column integer,
constraint c
primary key (function, source_file, line, column)
)
without rowid""")
build_index=True
def store_positions(fun, typ, point, places):
"""Add source code positions to an internal list."""
for place in places:
c.execute("""insert into positions
(function,
data_type,
parameter,
source_file,
line,
column
)
values (?, ?, ?, ?, ?, ?)""",
(fun,
typ,
point,
place.file,
place.line,
int(place.column) + 1
)
)
def store_static(fun, places):
"""Record that a function is static."""
for place in places:
fields = []
fields.append("fun:")
fields.append(fun)
fields.append("file:")
fields.append(place.file)
fields.append("line:")
fields.append(place.line)
fields.append("column:")
fields.append(int(place.column) + 1)
sys.stderr.write("\n".join())
sys.stderr.write("\n")
c.execute("""update positions
set static=1
where function = ?
and source_file = ?
and line = ?
and column = ?""",
(fun, place.file, place.line, int(place.column) + 1)
)
@void_single_function_call@
identifier caller, input, work;
type input_type;
position pos;
@@
void caller at pos(input_type input)
{
(
work(input);
|
work(input);
return;
)
}
@script:python void_collection depends on void_single_function_call@
typ << void_single_function_call.input_type;
fun << void_single_function_call.caller;
point << void_single_function_call.input;
places << void_single_function_call.pos;
@@
store_positions(fun, typ, point, places)
@non_void_single_function_call@
identifier caller, input, result, work;
type data_type, input_type, return_type;
position pos;
@@
return_type caller at pos(input_type input)
{
(
return work(input);
|
data_type result = work(input);
return result;
)
}
@script:python non_void_collection depends on non_void_single_function_call@
typ << non_void_single_function_call.data_type;
fun << non_void_single_function_call.caller;
point << non_void_single_function_call.input;
places << non_void_single_function_call.pos;
@@
store_positions(fun, typ, point, places)
@void_find_static depends on void_single_function_call@
identifier void_single_function_call.caller;
position void_single_function_call.pos;
@@
static void callerk at pos(...)
{
...
}
@non_void_find_static depends on non_void_single_function_call@
identifier non_void_single_function_call.caller;
type non_void_single_function_call.return_type;
position non_void_single_function_call.pos;
@@
static return_type callerk@pos(...)
{
...
}
@script:python index_creation@
@@
if build_index:
c.execute("""
create unique index x
on positions(function, source_file, line, column)""")
build_index=False
@script:python void_addition depends on void_find_static@
fun << void_single_function_call.caller;
places << void_single_function_call.pos;
@@
store_static(fun, places)
@script:python non_void_addition depends on non_void_find_static@
fun << non_void_single_function_call.caller;
places << non_void_single_function_call.pos;
@@
store_static(fun, places)
@finalize:python@
@@
c.execute("select count(*) nr from positions")
entry = c.fetchone()
if entry[0] > 0:
c.execute("""
select *
from positions
order by source_file, function, line, column""")
mark1 = ['"', '', '"']
mark2 = ['"', '', '"']
delimiter = '|'
sys.stdout.write(delimiter.join(("static",
"function",
'"data type"',
'"parameter"',
'"source file"',
"line",
"column"
)))
sys.stdout.write("\r\n")
for entry in c:
mark1[1] = entry[2]
mark2[1] = entry[4].replace('"', '""')
sys.stdout.write(delimiter.join((str(entry[0]),
entry[1],
''.join(mark1),
entry[3],
''.join(mark2),
str(entry[5]),
str(entry[6])
)))
sys.stdout.write("\r\n")
else:
sys.stderr.write("No result for this analysis!\n")
connection.close()
-------------- next part --------------
@initialize:python@
@@
import sys
import sqlite3 as SQLite
connection = SQLite.connect(":memory:")
c = connection.cursor()
c.execute("""
create table positions
(static integer default 0,
function text,
data_type text,
parameter text,
source_file text,
line integer,
column integer,
constraint c
primary key (function, source_file, line, column)
)
without rowid""")
build_index=True
def store_positions(fun, typ, point, places):
"""Add source code positions to an internal list."""
for place in places:
c.execute("""insert into positions
(function,
data_type,
parameter,
source_file,
line,
column
)
values (?, ?, ?, ?, ?, ?)""",
(fun,
typ,
point,
place.file,
place.line,
int(place.column) + 1
)
)
def store_static(fun, places):
"""Record that a function is static."""
for place in places:
c.execute("""update positions
set static=1
where function = ?
and source_file = ?
and line = ?
and column = ?""",
(fun, place.file, place.line, int(place.column) + 1)
)
@single_function_call@
identifier caller, input, result, work;
type data_type, input_type, return_type;
position pos;
@@
return_type caller at pos(input_type input)
{
(
work(input);
|
return work(input);
|
data_type result = work(input);
return result;
|
work(input);
return;
)
}
@script:python collection depends on single_function_call@
typ << single_function_call.input_type;
fun << single_function_call.caller;
point << single_function_call.input;
places << single_function_call.pos;
@@
store_positions(fun, typ, point, places)
@find_static depends on single_function_call@
identifier single_function_call.caller;
type single_function_call.return_type;
position single_function_call.pos;
@@
static return_type callerk@pos(...)
{
...
}
@script:python index_creation@
@@
if build_index:
c.execute("""
create unique index x
on positions(function, source_file, line, column)""")
build_index=False
@script:python addition depends on find_static@
fun << single_function_call.caller;
places << single_function_call.pos;
@@
store_static(fun, places)
@finalize:python@
@@
c.execute("select count(*) nr from positions")
entry = c.fetchone()
if entry[0] > 0:
c.execute("""
select *
from positions
order by source_file, function, line, column""")
mark1 = ['"', '', '"']
mark2 = ['"', '', '"']
delimiter = '|'
sys.stdout.write(delimiter.join(("static",
"function",
'"data type"',
'"parameter"',
'"source file"',
"line",
"column"
)))
sys.stdout.write("\r\n")
for entry in c:
mark1[1] = entry[2]
mark2[1] = entry[4].replace('"', '""')
sys.stdout.write(delimiter.join((str(entry[0]),
entry[1],
''.join(mark1),
entry[3],
''.join(mark2),
str(entry[5]),
str(entry[6])
)))
sys.stdout.write("\r\n")
else:
sys.stderr.write("No result for this analysis!\n")
connection.close()
next prev parent reply other threads:[~2014-12-05 20:05 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-28 22:33 [Cocci] Finding function implementations that call only a single function SF Markus Elfring
[not found] ` <alpine.DEB.2.02.1412032218310.2303@localhost6.localdomain6>
[not found] ` <547F8C2B.5090601@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1412032334330.2303@localhost6.localdomain6>
2014-12-05 14:20 ` SF Markus Elfring
[not found] ` <alpine.DEB.2.10.1412051633240.2360@hadrien>
2014-12-05 20:05 ` SF Markus Elfring [this message]
[not found] ` <54834F76.1090104@users.sourceforge.net>
[not found] ` <alpine.DEB.2.10.1412061955440.2042@hadrien>
[not found] ` <548358DE.6020409@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1412062139570.2256@localhost6.localdomain6>
[not found] ` <548371FB.9060402@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1412062219530.2256@localhost6.localdomain6>
[not found] ` <54837413.8000902@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1412062232470.2256@localhost6.localdomain6>
[not found] ` <5483806D.3070805@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1412062342540.2256@localhost6.localdomain6>
[not found] ` <5483902E.8060109@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1412070749130.2044@localhost6.localdomain6>
2014-12-07 9:15 ` SF Markus Elfring
2014-12-07 9:31 ` Julia Lawall
2014-12-07 10:22 ` SF Markus Elfring
2014-12-07 10:28 ` Julia Lawall
2014-12-07 10:37 ` SF Markus Elfring
2014-12-07 11:45 ` Julia Lawall
2014-12-07 12:00 ` SF Markus Elfring
2014-12-07 12:38 ` Julia Lawall
2014-12-07 14:41 ` SF Markus Elfring
2014-12-17 15:30 ` SF Markus Elfring
2014-12-17 19:20 ` Julia Lawall
2014-12-17 20:30 ` [Cocci] Distinguishing pointer data types with SmPL SF Markus Elfring
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54820FEF.4080901@users.sourceforge.net \
--to=elfring@users.sourceforge.net \
--cc=cocci@systeme.lip6.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.