- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
有些函数有一个指针参数,指向结果来自哪里应存储调用函数,但函数还要求调用函数时,此指针指向用作输入值的某个值(例如输入/输出参数)。
我想检测调用此类函数并指向未初始化变量的情况。 Coccinelle应该能够做到这一点,但是我为实现这一目标而努力了一点。
示例目标代码:
#include <string.h>
#include <stdio.h>
static void cartoon_random_generator(int *n)
{
switch (*n) {
case 4:
*n = 4; /* http://xkcd.com/221/ */
break;
case 9:
*n = 9; /* http://dilbert.com/strips/comic/2001-10-25/ */
break;
default:
fprintf(stderr, "*n was not initialized before calling this function\n");
break;
}
}
/* alternative links http://i.stack.imgur.com/VvTef.png and http://i.stack.imgur.com/u0iJ7.gif */
static void test(const char *cartoon)
{
// not ok, missing
{
int n1;
cartoon_random_generator(&n1);
printf("Random number = %d\n", n1);
}
// ok, declaration
{
int n2 = 4;
cartoon_random_generator(&n2);
printf("Random number = %d\n", n2);
}
// ok, statement
{
int n3;
n3 = 9;
cartoon_random_generator(&n3);
printf("Random number = %d\n", n3);
}
// both ok and not ok
{
int n4, n9;
n9 = 9;
//strcmp(cartoon, "XKCD") == 0 ? cartoon_random_generator(&n4) : cartoon_random_generator(&n9);
if (strcmp(cartoon, "XKCD") == 0)
cartoon_random_generator(&n4);
else
cartoon_random_generator(&n9);
printf("Random numbers = %d, %d\n", n4, n9);
}
}
我写了下面的七星脚本
/* It is an error to call cartoon_random_generator with an uninitialized
variable. Detect this. */
/*
* This rule matches an OK case where the in variable is initialized when
* declared. No action is performed for this rule other than giving p1 a value.
*/
@rule1@
position p1;
expression init_expression;
identifier n;
@@
int n = init_expression;
...
cartoon_random_generator@p1(&n)
/*
* This rule matches an OK case where the in variable is initialized in a
* separate statement. No action is performed for this rule other than
* giving p2 a value.
*/
@rule2@
position p2;
expression init_expression;
identifier n;
@@
int n;
...
n = init_expression;
...
cartoon_random_generator@p2(&n)
/* If neither rule1 or rule2 have matched so far,
* we have a variable that is uninitialized. */
@rule3@
position p3 != rule1.p1, rule2.p2;
identifier n;
@@
int n;
...
* cartoon_random_generator@p3(&n)
但是没有考虑规则 2,我不明白为什么。运行它给出:
$ /opt/coccinelle/bin/spatch -sp_file cartoon_random.cocci cartoon_random.c
init_defs_builtins: /opt/coccinelle/share/coccinelle/standard.h
warning: rule3: inherited metavariable p2 not used in the -, +, or context code
HANDLING: cartoon_random.c
diff =
--- cartoon_random.c
+++ /tmp/cocci-output-7916-8df75b-cartoon_random.c
@@ -23,7 +23,6 @@ static void test(const char *cartoon)
{
int n1;
- cartoon_random_generator(&n1);
printf("Random number = %d\n", n1);
}
@@ -40,7 +39,6 @@ static void test(const char *cartoon)
int n3;
n3 = 9;
- cartoon_random_generator(&n3);
printf("Random number = %d\n", n3);
}
@@ -51,9 +49,7 @@ static void test(const char *cartoon)
n9 = 9;
//strcmp(cartoon, "XKCD") == 0 ? cartoon_random_generator(&n4) : cartoon_random_generator(&n9);
if (strcmp(cartoon, "XKCD") == 0)
- cartoon_random_generator(&n4);
else
- cartoon_random_generator(&n9);
printf("Random numbers = %d, %d\n", n4, n9);
}
}
最佳答案
我完全是 Coccinelle 用法的初学者,一直想了解它。您提出的问题是检测未初始化变量的一个相当好的要求,这让我进行了一些研究。在做了一些研究之后(& 从 warning: rule3: inherited metavariable p2 not used in the -, +, or context code
中得到线索)其中一种方法(可能有其他/更好的方法) 使你的 coccinelle 脚本工作是结合规则 1 和 2 & 在最终规则中仅对元变量使用单一继承。这些线路上的东西:
@rule1@
position p1;
expression init_expression;
identifier n;
@@
(
int n = init_expression;
|
int n;
...
n = init_expression;
)
...
cartoon_random_generator@p1(&n)
@rule2@
position p2 != rule1.p1;
identifier n;
@@
int n;
...
* cartoon_random_generator@p2(&n)
在这种情况下看到的输出是:
$spatch -sp_file cartoon_random.cocci cartoon_random.c
init_defs_builtins: /usr/share/coccinelle/standard.h
HANDLING: cartoon_random.c
diff =
--- cartoon_random.c
+++ /tmp/cocci-output-7916-8df75b-cartoon_random.c
@@ -23,7 +23,6 @@ static void test(const char *cartoon)
{
int n1;
- cartoon_random_generator(&n1);
printf("Random number = %d\n", n1);
}
@@ -51,9 +50,6 @@ static void test(const char *cartoon)
n9 = 9;
//strcmp(cartoon, "XKCD") == 0 ? cartoon_random_generator(&n4) : cartoon_random_generator(&n9);
if (strcmp(cartoon, "XKCD") == 0)
- cartoon_random_generator(&n4);
else
cartoon_random_generator(&n9);
printf("Random numbers = %d, %d\n", n4, n9);
这是在 FC15 上运行的,使用从 Fedora 存储库安装的 coccinelle 软件包。
希望这对您有所帮助!
关于c - 检测传递指向未初始化变量的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7685898/
有人能给我解释一下我下面程序中的一点吗我编写的以下程序是为了理解 int * const * var 的含义; #include "iostream" using namespace std ; in
我正在摆弄 C 中的指针,但仍然不确定一些非常基础的知识。我想出了以下示例代码: #include int main(void) { int num = 42; /
以下代码产生警告: const char * mystr = "\r\nHello"; void send_str(char * str); void main(void){ send_str
我正在尝试在我的 Linux 计算机上升级 cmake。这是我使用的命令。 删除旧的 cmake: sudo apt purge --auto-remove cmake 从 https://cmake
我试图借助 char 指针来追踪 union 第一个字节的值。我假设 byte1 的输出应该是 ff,但实际上是 ffffffff。如果我错了请纠正我。 #include #include #in
我正在使用微 Controller 进行一些 ADC 测量。当我尝试使用 -O2 优化编译以下代码时遇到问题,当代码中存在 PrintVal() 函数时,MCU 卡住。我做了一些调试,结果发现,当我添
#include #include using namespace std; int main () { vector qwerty; qwerty.push_back(5);
我有我的 woking setup.py 文件;其中包含以下行: home = os.environ["HOME"] # home = /home/dr in my machine; distu
这段代码 #include #include static_assert(std::is_same_v::value_type, volatile int>); 在最新的 GCC 和 clang
我对 C 中的前向声明有疑问。 代码 typedef struct yhash_s t_yhash;// forward declaration struct yhash_s { size_t
我想提取成员指针指向的成员的类型。 template void demo(myClass& instance, void* ptr) { instance.*member = *reinter
我正在尝试使用指针将一段 C 代码转换为 Swift 3。这是 C 代码中的相关部分。 Float32 sampleArray[256] = { // Array is 256 Float value
您可能知道,VLA's haves pros and cons 和它们在 C11 中是可选的。 我想使 VLA 成为可选项的主要原因是:“堆栈可能会爆炸”: int arr[n]; /* where
这段代码有什么错误?为什么我不能按照我尝试的方式取消引用该元素。 #include typedef struct { int value; struct node * left;
有什么方法可以在 JavaScript 中创建\返回指向变量的指针吗? 比如,在 PHP 中: function func() { ..... return &$result; } 我
如果您想使用方法的指针作为参数,则需要将该方法键入作为对象的函数,就像这样好 : type TAcceptor = function(filename:string):boolean of objec
很简单的问题: 我对 C++ 中的智能指针有点陌生。我想我得到了所有权的东西,但我不知道如何访问他们实际指向的内容。当我尝试使用对象的成员函数/变量时,我只是得到了 unique_ptr 类的函数,这
我得到了一个点的方位 Angular 、指南针方向和一个可以将箭头设置到某个方向的 api(0 是顶部,90 是右侧,180 是底部,360 是顶部) 如果我希望箭头指向我采用方位 Angular 形
我正在尝试找到一种方法,从单元格中获取位于当前工作表左侧(托盘下方)的工作表单元格中的数据。 我知道如何通过调用其他工作表 =Sheet1!A1 但现在我需要一些最好的解释 =Sheet[-1]!A1
所以我在 MATLAB 中有一个 for 循环,其中向量 x 将通过一个函数,比如 cos(x).^2,或者不同的选择,比如 sin(x).^2 + 9.*x。用户将在 for 循环之前选择他想使用的
我是一名优秀的程序员,十分优秀!