On Mon, 14 Apr 2025 at 12:57, Jonathan Wakely <jwakely....@gmail.com> wrote:
>
> 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);

Oops sorry, that should be gnu::error not error.

>
> 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