This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/69657 (abs not inlined)


The issue in this bug was that due to changes in the libstdc++ headers, the built-in abs declaration was getting hidden by a using-declaration, so that then when the built-in got an explicit declaration, the original declaration wasn't there anymore and so the new declaration didn't get marked as built-in.

Fixed by overloading an anticipated built-in rather than clobbering it when we see a using-declaration of the same name.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 8f47c80051a73a75fb44900d9edb1444142c3d5f
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Feb 8 16:39:42 2016 -0500

    	PR c++/69657
    	* name-lookup.c (do_nonmember_using_decl): Leave anticipated
    	built-ins alone.

diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 92d99aa..227d6f2 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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
index 0000000..456ade7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/builtin6.C
@@ -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);
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]