Hi! If we return olddecl on an (invalid) builtin function redefinition rather than redeclaration, we ICE shortly afterwards, because we assume we have non-NULL DECL_INITIAL on whatever is returned (except for error_mark_node).
The following patch errors unconditionally for definitions of builtin functions, and also makes sure to return error_mark_node if we've emitted an error from the permerror. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2018-03-13 Jakub Jelinek <ja...@redhat.com> PR c++/84843 * decl.c (duplicate_decls): For redefinition of built-in, use error and return error_mark_node. For redeclaration, return error_mark_node rather than olddecl if !flag_permissive. * g++.dg/ext/pr84843-1.C: New test. * g++.dg/ext/pr84843-2.C: New test. --- gcc/cp/decl.c.jj 2018-03-09 19:00:44.350969146 +0100 +++ gcc/cp/decl.c 2018-03-13 14:56:45.244872506 +0100 @@ -1583,13 +1583,20 @@ next_arg:; || memcmp (name + len - strlen ("_chk"), "_chk", strlen ("_chk") + 1) != 0)) { + if (DECL_INITIAL (newdecl)) + { + error_at (DECL_SOURCE_LOCATION (newdecl), + "definition of %q#D ambiguates built-in " + "declaration %q#D", newdecl, olddecl); + return error_mark_node; + } if (permerror (DECL_SOURCE_LOCATION (newdecl), "new declaration %q#D ambiguates built-in" " declaration %q#D", newdecl, olddecl) && flag_permissive) inform (DECL_SOURCE_LOCATION (newdecl), "ignoring the %q#D declaration", newdecl); - return olddecl; + return flag_permissive ? olddecl : error_mark_node; } } --- gcc/testsuite/g++.dg/ext/pr84843-1.C.jj 2018-03-13 14:55:15.927831678 +0100 +++ gcc/testsuite/g++.dg/ext/pr84843-1.C 2018-03-13 14:57:51.652902862 +0100 @@ -0,0 +1,9 @@ +// PR c++/84843 +// { dg-do compile } +// { dg-options "-fpermissive" } + +extern "C" int +__atomic_compare_exchange (int x, int y) // { dg-error "ambiguates built-in declaration" } +{ + return x + y; +} --- gcc/testsuite/g++.dg/ext/pr84843-2.C.jj 2018-03-13 14:55:19.349833246 +0100 +++ gcc/testsuite/g++.dg/ext/pr84843-2.C 2018-03-13 14:57:58.205905859 +0100 @@ -0,0 +1,9 @@ +// PR c++/84843 +// { dg-do compile } +// { dg-options "" } + +extern "C" int +__atomic_compare_exchange (int x, int y) // { dg-error "ambiguates built-in declaration" } +{ + return x + y; +} Jakub