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

Reply via email to