On Mon, 14 Apr 2025 at 11:53, Julian Waters wrote:
>
> Hi Jonathan,
>
> Yep, unfortunately #pragma GCC poison is far too restrictive, it
> doesn't check if it is a function call to that particular banned
> function, it restricts any and all use of that identifier in the code
> altogether. Not only does this mean you can't use overloads of a
> banned function, you can't use that identifier whatsoever, not even in
> naming your own function. This presents some trouble, for example this
> codebase has the following snippets in it:
>
> void* outerp = os::malloc(total_sz, mtInternal);
>
> And the declaration and definitions for os::malloc as well:
>
> // General allocation (must be MT-safe)
> static void* malloc  (size_t size, MemTag mem_tag, const
> NativeCallStack& stack);
> static void* malloc  (size_t size, MemTag mem_tag);
>
> This is not the standard library malloc of course, but had I put
> #pragma GCC poison malloc into a general header, these areas would've
> immediately been flagged and the compilation would've been terminated
> in an error. It's also prohibitively difficult to unpoison an
> identifier poisoned this way, making it unsuitable for use in this
> codebase, unfortunately

I think this works, but is ugly (and I wouldn't accept it as a
workaround personally):

#define OS_MALLOC(a, b) os::malloc((a), (b))
#pragma GCC poison malloc

Now you can use OS_MALLOC everywhere instead of os::malloc. That's
horrible though, and all uses of os::malloc need to be changed.

You could just add the error attribute to existing functions:

extern "C" [[error("use os::malloc instead")]] void* malloc(size_t);

This seems to do exactly what you want:
del.cc:9:21: error: call to ‘malloc’ declared with attribute error:
use os::malloc instead

The C++ standard doesn't allow redeclaring anything in namespace std,
but I think it's less clear about C functions in the global namespace.
In any case, it might be morally questionable, but it works. And since
what you want is to prevent the function being called, the usual
concerns about redeclaring it don't really apply.

You can probably come up with some macro-based solution to allow
calling it in specific places, such as simply arranging for the
redeclaration with gnu::error to not be visible where you need to use
it.

Reply via email to