Statically inferring symbol types in C

2

As part of a regression test, I want to use static analysis to ensure that a C symbol defined in a header is of the same type as the base type of a typedef, which is also defined in the same header.

Given that I am using gcc (along with its extensions) and can generate DWARF debugging information, my strategy to achieve this is as follows:

test.c:

#include <my/header.h>

my_type x;
typeof (MY_SYMBOL) y;

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

Then execute:

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

Here is a relevant snippet from 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>

If you follow the addresses for DW_AT_type in the DWARF information, you will see that the typedef (my_type) and the symbol (MY_SYMBOL) are indeed of the the same type (int). i.e. this test passes.

Of course, I need to parse this debug information (maybe hack together a perl/python script) to prove that automatically each time the test case runs. My question is: Is there a cleaner/easier way to do this?

c
gcc
types
static-analysis
dwarf
asked on Stack Overflow Sep 25, 2014 by ArjunShankar

1 Answer

2

Since you are using GCC, you can use the __builtin_types_compatible_p builtin:

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

Quoting from the GCC builtin manual:

You can use the built-in function __builtin_types_compatible_p to determine whether two types are the same.

This built-in function returns 1 if the unqualified versions of the types type1 and type2 (which are types, not expressions) are compatible, 0 otherwise. The result of this built-in function can be used in integer constant expressions.

This built-in function ignores top level qualifiers (e.g., const, volatile). For example, int is equivalent to const int.

The type int[] and int[5] are compatible. On the other hand, int and char * are not compatible, even if the size of their types, on the particular architecture are the same. Also, the amount of pointer indirection is taken into account when determining similarity. Consequently, short * is not similar to short **. Furthermore, two types that are typedefed are considered compatible if their underlying types are compatible.

answered on Stack Overflow Sep 25, 2014 by Blagovest Buyukliev • edited Jun 20, 2020 by Community

User contributions licensed under CC BY-SA 3.0