触发 Clang 静态分析器的示例代码

发布于 2024-09-13 23:52:54 字数 240 浏览 12 评论 0原文

我希望看到一小段完整的代码,它会导致 Clang 的静态分析器抱怨。我的动机主要是我试图让它在我的 PIC32 代码上工作,并且我需要一种方法来区分“所有代码都很好”和“它实际上没有做任何事情”。这也部分是出于好奇,因为我自己似乎无法想出一个简单的例子。

C89/ANSI 或 C99 都可以,理想情况下我希望看到它发现一个简单的内存泄漏。我的用法是

clang --analyze test.c

I would like to see a small but complete snippet of code that will cause Clang's static analyser to complain. My motivation is mostly that I'm trying to get it to work on my PIC32 code, and I need a way to distinguish between "all the code is fine" and "it's not actually doing anything". It's also partly curiosity, since I can't seem to come up with a simple example myself.

C89/ANSI or C99 is fine, and ideally I'd like to see it pick up a simple memory leak. My usage is

clang --analyze test.c

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏至、离别 2024-09-20 23:52:54

我在我的代码中发现了一个“错误”(唯一的一个;-),它会由此触发,但 -Wall 无法检测到该错误。我将其简化为以下内容

struct elem {
  struct elem *prev;
  struct elem *next;
};

#define ELEM_INITIALIZER(NAME) { .prev = &(NAME), .next = &(NAME), }

struct head {
  struct elem header;
};

#define HEAD_INITIALIZER(NAME) { .header = ELEM_INITIALIZER(NAME.header) }

int main(int argc, char ** argv) {
  struct head myhead = HEAD_INITIALIZER(myhead);
}

这是链表的相对直接的实现,但这在这里并不重要。变量myhead 在该术语的常识应用中未使用,但对于编译器来说,它会被使用,因为在初始化程序内部会获取字段的地址。

clang 正确地将其分析为

/tmp 11:58 <722>% clang --analyze test-clang.c
test-clang.c:25:15: warning: Value stored to 'myhead' during its initialization is never read
  struct head myhead = HEAD_INITIALIZER(myhead);
              ^        ~~~~~~~~~~~~~~~~~~~~~~~~
1 diagnostic generated.

编辑:我发现了另一个也可以检测堆栈内存增殖的代码

char const* myBuggyFunction(void) {
  return (char[len + 1]){ 0 };
}

gccopen64未检测到此情况clang-Wall 一起使用,但通过 clang--analyze 一起使用。

I found a "bug" in my code (the only one ;-) that triggers by that, and that is not detected by -Wall. I cooked it down to the following

struct elem {
  struct elem *prev;
  struct elem *next;
};

#define ELEM_INITIALIZER(NAME) { .prev = &(NAME), .next = &(NAME), }

struct head {
  struct elem header;
};

#define HEAD_INITIALIZER(NAME) { .header = ELEM_INITIALIZER(NAME.header) }

int main(int argc, char ** argv) {
  struct head myhead = HEAD_INITIALIZER(myhead);
}

This is a relatively straight forward implementation of a linked list, but this is not important here. The variable myhead is unused in a common sense application of the term, but for the compiler it is used since inside the initializer the address of a field is taken.

clang correctly analyzes this as

/tmp 11:58 <722>% clang --analyze test-clang.c
test-clang.c:25:15: warning: Value stored to 'myhead' during its initialization is never read
  struct head myhead = HEAD_INITIALIZER(myhead);
              ^        ~~~~~~~~~~~~~~~~~~~~~~~~
1 diagnostic generated.

Edit: I found another one that also detects stack memory proliferation

char const* myBuggyFunction(void) {
  return (char[len + 1]){ 0 };
}

This is not detected by gcc, open64 or clang with -Wall, but by clang with --analyze.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文