Created attachment 54156 [details] test case The attached code, i1.cc, contains two equivalent function declarations for the function 'free'. They are equivalent because they have the same signature and both have "C" linkage. In lines 9, 10, 12, 13, referencing the function 'free' works fine. However, referencing it in line 17, as part of a __attribute__ ((__malloc__ (free, 1))) attribute, leads to an error "‘malloc’ attribute argument 1 is ambiguous". I would expect no error, no warning. How to reproduce: $ g++ -S i1.cc i1.cc:17:67: error: ‘malloc’ attribute argument 1 is ambiguous 17 | __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (free, 1))); | ^ i1.cc:17:67: note: use a cast to the expected type to disambiguate
A little more reduced: ``` namespace g { extern "C" void free(void *); } using g::free; extern "C" void free (void *); void foo1 (void *p) { free (p); } void (*foo2) (void *) = free; extern "C" { void foo3 (void *p) { free (p); } void (*foo4) (void *) = free; } extern "C" wchar_t * wcsdup (const wchar_t *s) __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (free, 1))); ```
The problem is related to that free is a builtin rather than the extern "C" really. -fno-builtin fixes the error too.
Here is another example of the same issue but with cleanup attribute instead: ``` namespace std { extern "C" int printf (const char*, ...); } using std::printf; extern "C" int printf (const char*, ...); void foo (const char *) { printf ("%s\n", __PRETTY_FUNCTION__); } void bar () { const char a __attribute__ ((cleanup (printf))) = 0; printf ("%s calling ", __PRETTY_FUNCTION__); foo (&a); printf ("cleanup calling "); } int main () { bar (); } ``` Note if you order swap the order of declarations of printf it works. Same with free in the original testcase for malloc.