]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/69657
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Feb 2016 22:07:54 +0000 (22:07 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Feb 2016 22:07:54 +0000 (22:07 +0000)
* name-lookup.c (do_nonmember_using_decl): Leave anticipated
built-ins alone.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233229 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/testsuite/g++.dg/lookup/builtin6.C [new file with mode: 0644]

index f7a76ffab0ec4f65af7dd10ec8493c816b9b96eb..563a1b37c8cca109067b8e917bfc8fe8d6345463 100644 (file)
@@ -1,3 +1,9 @@
+2016-02-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/69657
+       * name-lookup.c (do_nonmember_using_decl): Leave anticipated
+       built-ins alone.
+
 2016-02-08  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/59627
index 92d99aa53d3db118d74f6572152e99e18b82a81a..227d6f22f44f53a8f0a2e04ae86eed68ee69310f 100644 (file)
@@ -2583,15 +2583,6 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
       decls.value = NULL_TREE;
     }
 
-  /* It is impossible to overload a built-in function; any explicit
-     declaration eliminates the built-in declaration.  So, if OLDVAL
-     is a built-in, then we can just pretend it isn't there.  */
-  if (oldval
-      && TREE_CODE (oldval) == FUNCTION_DECL
-      && DECL_ANTICIPATED (oldval)
-      && !DECL_HIDDEN_FRIEND_P (oldval))
-    oldval = NULL_TREE;
-
   if (decls.value)
     {
       /* Check for using functions.  */
@@ -2610,6 +2601,10 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
            {
              tree new_fn = OVL_CURRENT (tmp);
 
+             /* Don't import functions that haven't been declared.  */
+             if (DECL_ANTICIPATED (new_fn))
+               continue;
+
              /* [namespace.udecl]
 
                 If a function declaration in namespace scope or block
@@ -2627,13 +2622,13 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
                    continue; /* this is a using decl */
                  else if (compparms_for_decl_and_using_decl (new_fn, old_fn))
                    {
-                     gcc_assert (!DECL_ANTICIPATED (old_fn)
-                                 || DECL_HIDDEN_FRIEND_P (old_fn));
-
                      /* There was already a non-using declaration in
                         this scope with the same parameter types. If both
                         are the same extern "C" functions, that's ok.  */
-                     if (decls_match (new_fn, old_fn))
+                     if (DECL_ANTICIPATED (old_fn)
+                         && !DECL_HIDDEN_FRIEND_P (old_fn))
+                       /* Ignore anticipated built-ins.  */;
+                     else if (decls_match (new_fn, old_fn))
                        break;
                      else
                        {
@@ -2669,6 +2664,14 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
        }
       else
        {
+         /* If we're declaring a non-function and OLDVAL is an anticipated
+            built-in, just pretend it isn't there.  */
+         if (oldval
+             && TREE_CODE (oldval) == FUNCTION_DECL
+             && DECL_ANTICIPATED (oldval)
+             && !DECL_HIDDEN_FRIEND_P (oldval))
+           oldval = NULL_TREE;
+
          *newval = decls.value;
          if (oldval && !decls_match (*newval, oldval))
            error ("%qD is already declared in this scope", name);
diff --git a/gcc/testsuite/g++.dg/lookup/builtin6.C b/gcc/testsuite/g++.dg/lookup/builtin6.C
new file mode 100644 (file)
index 0000000..456ade7
--- /dev/null
@@ -0,0 +1,23 @@
+// PR c++/69657
+// { dg-options -fdump-tree-gimple }
+// { dg-final { scan-tree-dump "ABS_EXPR" "gimple" } }
+
+namespace foo
+{
+  inline double
+  abs(double x)
+  { return __builtin_fabs(x); }
+}
+using foo::abs;
+
+extern "C" int abs(int);
+
+namespace bar {
+  using ::abs;
+}
+
+int
+wrapper (int x)
+{
+  return bar::abs (x) + bar::abs(x);
+}