Skip to content
  • Milian Wolff's avatar
    Fake malloc attribute to improve compatibility with GCC 11 and higher · ce41c99b
    Milian Wolff authored
    On my system I regularly see bogus compiler warnings reported by clang
    within KDevelop, such as:
    
    ```
    /usr/include/stdlib.h:566:5: error: use of undeclared identifier '__builtin_free'; did you mean '__builtin_frexp'?
    /usr/include/stdlib.h:566:5: note: '__builtin_frexp' declared here
    /usr/include/stdlib.h:566:5: error: '__malloc__' attribute takes no arguments
    /usr/include/stdlib.h:570:14: error: '__malloc__' attribute takes no arguments
    /usr/include/stdlib.h:799:6: error: use of undeclared identifier '__builtin_free'; did you mean '__builtin_frexp'?
    /usr/include/stdlib.h:566:5: note: '__builtin_frexp' declared here
    /usr/include/stdlib.h:799:6: error: '__malloc__' attribute takes no arguments
    ```
    
    The reason is that e.g. `/usr/include/sys/cdefs.h` contains:
    
    ```
    #if __GNUC_PREREQ (11, 0)
    /* Designates dealloc as a function to call to deallocate objects
       allocated by the declared function.  */
    # define __attr_dealloc(dealloc, argno) \
        __attribute__ ((__malloc__ (dealloc, argno)))
    # define __attr_dealloc_free __attr_dealloc (__builtin_free, 1)
    #else
    # define __attr_dealloc(dealloc, argno)
    # define __attr_dealloc_free
    #endif
    ```
    
    In KDevelop, we ask cmake to tell us the compiler (in my case GCC)
    and then query it for its defines. Then we parse the code with
    libclang which then tries to parse the above (as it thinks we are GCC)
    but fails because clang does not yet support a malloc attribute with
    positional arguments, contrary to GCC.
    
    By injecting a fake `__malloc__` define we can silence this error,
    seemingly without side effects. As `__*__` is a reserved identifier
    I don't think we can break user code with this and should be
    relatively safe.
    ce41c99b