https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84843
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- I think if we have a definition we need to use newdecl ... Now consider extern "C" int __atomic_compare_exchange (int x, int y); void bar() { __atomic_compare_exchange (1, 2); } extern "C" int __atomic_compare_exchange (int x, int y) { return x + y; } with -fpermissive and things get even more complicated. > ./cc1plus -quiet t.ii -fpermissive t.ii:1:16: warning: new declaration ‘int __atomic_compare_exchange(int, int)’ ambiguates built-in declaration ‘bool __atomic_compare_exchange(long unsigned int, volatile void*, void*, void*, int, int)’ [-fpermissive] extern "C" int __atomic_compare_exchange (int x, int y); ^~~~~~~~~~~~~~~~~~~~~~~~~ t.ii:1:16: note: ignoring the ‘int __atomic_compare_exchange(int, int)’ declaration t.ii: In function ‘void bar()’: t.ii:3:45: error: incorrect number of arguments to function ‘__atomic_compare_exchange’ void bar() { __atomic_compare_exchange (1, 2); } ^ t.ii: At global scope: t.ii:5:16: warning: new declaration ‘int __atomic_compare_exchange(int, int)’ ambiguates built-in declaration ‘bool __atomic_compare_exchange(long unsigned int, volatile void*, void*, void*, int, int)’ [-fpermissive] extern "C" int __atomic_compare_exchange (int x, int y) ^~~~~~~~~~~~~~~~~~~~~~~~~ t.ii:5:16: note: ignoring the ‘int __atomic_compare_exchange(int, int)’ declaration t.ii: In function ‘bool __atomic_compare_exchange(long unsigned int, volatile void*, void*, void*, int, int)’: t.ii:5:55: internal compiler error: in start_preparsed_function, at cp/decl.c:15060 extern "C" int __atomic_compare_exchange (int x, int y) ^ 0x93685e start_preparsed_function(tree_node*, tree_node*, int) ...