Search code examples
cvolatilepost-processingtms

identify volatile declaration in debug information / disassembly


I'm looking for a creative solution for making sure that variables delivered to a specific macro are declared with type volatile in C language, with TMS470 compiler. meaning:

good method:

volatile int   *_p_reg;
VOLATILE_MACRO(_p_reg);

compilation failure:

int   *_p_reg;
VOLATILE_MACRO(_p_reg);

I wish to perform the verification after the compilation, meaning going over the disassembly or the debug information and identify those calls. I can't seem to find any evidence for the volatile in the debug info.

any ideas?

thanks!


Solution

  • Two possible solutions using gcc extensions. The run-time version uses __builtin_types_compatible_p and an assert. The compile-time version is similar but uses a hack to get a static assert which fires at compile-time (albeit with a rather cryptic error message):

    Run-time

    #include <stdio.h>
    #include <assert.h>
    
    #define VOLATILE_MACRO(p) \
        assert (__builtin_types_compatible_p(typeof(p), typeof(volatile int *)))
    
    int main()
    {
        volatile int * x;
        int * y;
    
        VOLATILE_MACRO(x);  // <<< OK
        VOLATILE_MACRO(y);  // <<< run-time error
    
        return 0;
    }
    

    Compile-time

    #include <stdio.h>
    #include <assert.h>
    
    #define A                      BUILD_NAME(__LINE__)
    #define BUILD_NAME(line)       BUILD_NAME2(line)
    #define BUILD_NAME2(line)      assert_ ## line
    #define STATIC_ASSERT(test)    typedef char A[(test) ? 1 : -1]
    
    #define VOLATILE_MACRO(p) \
        STATIC_ASSERT (__builtin_types_compatible_p(typeof(p), typeof(volatile int *)))
    
    int main()
    {
        volatile int * x;
        int * y;
    
        VOLATILE_MACRO(x);  // <<< OK
        VOLATILE_MACRO(y);  // <<< compile error
    
        return 0;
    }
    

    Note that if you need to support other volatile types then the macro can simply be extended with multiple chained __builtin_types_compatible_p tests, e.g.

    #define VOLATILE_MACRO(p) \
        assert (__builtin_types_compatible_p(typeof(p), typeof(volatile int *)) ||
                __builtin_types_compatible_p(typeof(p), typeof(volatile short *)))