静态推断C中的符号类型

时间:2014-09-25 13:41:30

标签: c gcc types static-analysis dwarf

作为回归测试的一部分,我想使用静态分析来确保标头中定义的C符号与typedef的基本类型具有相同的类型,它也定义在同一类型中报头中。

鉴于我正在使用gcc(及其扩展)并且可以生成DWARF调试信息,我实现此目标的策略如下:

test.c

#include <my/header.h>

my_type x;
typeof (MY_SYMBOL) y;

/* MY_SYMBOL should be of the same type as my_type.  */

然后执行:

$ gcc -O0 -g -c test.c -o test.o
$ dwarfdump test.o > test.dump

以下是test.dump的相关摘录:

LOCAL_SYMBOLS:
< 1><0x00000032>    DW_TAG_typedef
                      DW_AT_name                  my_type
                      DW_AT_decl_file             0x00000002 my/header.h
                      DW_AT_decl_line             0x00000145
                      DW_AT_type                  <0x0000003e>
< 1><0x0000003e>    DW_TAG_base_type
                      DW_AT_byte_size             0x00000004
                      DW_AT_encoding              DW_ATE_signed
                      DW_AT_name                  int
< 1><0x00000053>    DW_TAG_variable
                      DW_AT_name                  x
                      DW_AT_decl_file             0x00000001 test.c
                      DW_AT_decl_line             0x00000003
                      DW_AT_type                  <0x00000032>
                      DW_AT_external              yes(1)
< 1><0x00000068>    DW_TAG_variable
                      DW_AT_name                  y
                      DW_AT_decl_file             0x00000001 test.c
                      DW_AT_decl_line             0x00000004
                      DW_AT_type                  <0x0000003e>

如果您在DWARF信息中关注DW_AT_type的地址,您会看到typedefmy_type)和符号(MY_SYMBOL)确实属于相同的类型(int)。即该测试通过。

当然,我需要解析这个调试信息(可能是一个perl / python脚本),以便每次测试用例运行时自动证明。我的问题是:有更清洁/更简单的方法吗?

1 个答案:

答案 0 :(得分:2)

由于您使用的是GCC,因此可以使用__builtin_types_compatible_p内置:

if (__builtin_types_compatible_p(typeof(x), typeof(y))) {
    // x and y are of the same type
}

引用GCC builtin manual

  

您可以使用内置函数__builtin_types_compatible_p来确定两种类型是否相同。

     

如果类型为type1和type2的非限定版本(类型,而不是表达式)兼容,则此内置函数返回1,否则返回0。此内置函数的结果可用于整型常量表达式。

     

此内置函数忽略顶级限定符(例如,const,volatile)。例如,int等效于const int。

     

int []和int [5]类型是兼容的。另一方面,即使特定体系结构上的类型大小相同,int和char *也不兼容。此外,在确定相似性时考虑指针间接量。因此,short *与short **不相似。此外,如果基础类型兼容,则两种类型为typedefed的类型被认为是兼容的。