This is the mail archive of the gcc-bugs@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]

[Bug c/13856] [3.4/3.5 Regression] hidden support broken with builtin functions


------- Additional Comments From zack at codesourcery dot com  2004-02-08 01:53 -------
Subject: c-decl.c rewrite: fix bug 13856


Bug 13856 reports that a visibility:hidden attribute gets lost when
applied to the definition of a built-in function (in glibc).  The fix
is regrettably more invasive than it ought to be.  First, don't give
special treatment in duplicate_decls to functions that have been
explicitly declared just because they're built-in.  Second, do not
forget that functions are built-in just because they've been defined
(assuming compatible signatures).  Third, don't ignore builtins in
dwarf2out.c (they will get ignored below if they have no definitions,
anyway).  Last, do not overwrite DECL_FUNCTION_CODE from language-
independent code. DECL_ESTIMATED_INSNS turns out to be write-only, so
this is no hardship.

bootstrapped i686-linux, applied 3.4 branch and shortly to mainline.

zw

        Bug 13856
        * c-decl.c (diagnose_mismatched_decls): Only give special
        treatment when olddecl is DECL_BUILT_IN, if C_DECL_INVISIBLE 
        is also true.
        (merge_decls): Don't clear DECL_BUILT_IN_CLASS and
        DECL_FUNCTION_CODE when defining a built-in function.
        Don't update DECL_ESTIMATED_INSNS.
        * dwarf2out.c (dwarf2out_decl): Don't ignore built-in
        FUNCTION_DECLs.
        * tree.h: Delete DECL_ESTIMATED_INSNS.
        * tree-inline.c (struct inline_data): Delete inlined_insns field.
        (expand_call_inline, optimize_inline_calls): Don't update
        DECL_ESTIMATED_INSNS nor inlined_insns.
        * cgraphunit.c (cgraph_analyze_function): Don't update
        DECL_ESTIMATED_INSNS.
cp:
        * optimize.c (maybe_clone_body): Don't update DECL_ESTIMATED_INSNS.
        * decl.c (duplicate_decls, start_function): Likewise.
testsuite:
        * gcc.dg/visibility-8.c: New testcase.

===================================================================
Index: c-decl.c
--- c-decl.c	8 Feb 2004 00:52:42 -0000
+++ c-decl.c	8 Feb 2004 01:09:37 -0000
@@ -939,7 +939,8 @@
      unless OLDDECL is a builtin.  OLDDECL will be discarded in any case.  */
   if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
     {
-      if (TREE_CODE (olddecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
+      if (TREE_CODE (olddecl) != FUNCTION_DECL
+          || !DECL_BUILT_IN (olddecl) || !C_DECL_INVISIBLE (olddecl))
 	{
 	  error ("%J'%D' redeclared as different kind of symbol",
 		 newdecl, newdecl);
@@ -956,7 +957,8 @@
 
   if (!comptypes (oldtype, newtype, COMPARE_STRICT))
     {
-      if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_BUILT_IN (olddecl))
+      if (TREE_CODE (olddecl) == FUNCTION_DECL
+	  && DECL_BUILT_IN (olddecl) && C_DECL_INVISIBLE (olddecl))
 	{
 	  /* Accept harmless mismatch in function types.
 	     This is for the ffs and fprintf builtins.  */
@@ -1034,6 +1036,7 @@
 	 can't validate the argument list) the built-in definition is
 	 overridden, but optionally warn this was a bad choice of name.  */
       if (DECL_BUILT_IN (olddecl)
+	  && C_DECL_INVISIBLE (olddecl)
 	  && (!TREE_PUBLIC (newdecl)
 	      || (DECL_INITIAL (newdecl)
 		  && !TYPE_ARG_TYPES (TREE_TYPE (newdecl)))))
@@ -1428,20 +1431,9 @@
 
       if (DECL_BUILT_IN (olddecl))
 	{
-	  /* Get rid of any built-in function if we have a function
-	     definition.  */
-	  if (new_is_definition)
-	    {
-	      TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
-	      DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
-	    }
-	  else
-	    {
-	      /* If redeclaring a builtin function, and not a definition,
-		 it stays built in.  */
-	      DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
-	      DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
-	    }
+	  /* If redeclaring a builtin function, it stays built in.  */
+	  DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
+	  DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
 	}
 
       /* Also preserve various other info from the definition.  */
@@ -1451,7 +1443,6 @@
 	  DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
 	  DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
 	  DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
-	  DECL_ESTIMATED_INSNS (newdecl) = DECL_ESTIMATED_INSNS (olddecl);
 	  DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
 
 	  /* Set DECL_INLINE on the declaration if we've got a body
===================================================================
Index: dwarf2out.c
--- dwarf2out.c	5 Feb 2004 22:01:33 -0000	1.478.2.3
+++ dwarf2out.c	8 Feb 2004 01:09:38 -0000
@@ -12153,12 +12153,6 @@ dwarf2out_decl (tree decl)
       return;
 
     case FUNCTION_DECL:
-      /* Ignore this FUNCTION_DECL if it refers to a builtin declaration of a
-	 builtin function.  Explicit programmer-supplied declarations of
-	 these same functions should NOT be ignored however.  */
-      if (DECL_EXTERNAL (decl) && DECL_BUILT_IN (decl))
-	return;
-
       /* What we would really like to do here is to filter out all mere
 	 file-scope declarations of file-scope functions which are never
 	 referenced later within this translation unit (and keep all of ones
===================================================================
Index: tree.h
--- tree.h	5 Feb 2004 22:01:36 -0000	1.458.2.3
+++ tree.h	8 Feb 2004 01:09:39 -0000
@@ -1627,13 +1627,6 @@ struct tree_type GTY(())
 #define DECL_POINTER_ALIAS_SET_KNOWN_P(NODE) \
   (DECL_POINTER_ALIAS_SET (NODE) != - 1)
 
-/* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this is
-   the approximate number of statements in this function.  There is
-   no need for this number to be exact; it is only used in various
-   heuristics regarding optimization.  */
-#define DECL_ESTIMATED_INSNS(NODE) \
-  (FUNCTION_DECL_CHECK (NODE)->decl.u1.i)
-
 /* Nonzero for a decl which is at file scope.  */
 #define DECL_FILE_SCOPE_P(EXP) 					\
   (! DECL_CONTEXT (EXP)						\
===================================================================
Index: tree-inline.c
--- tree-inline.c	23 Jan 2004 23:36:03 -0000	1.90.4.1
+++ tree-inline.c	8 Feb 2004 01:09:39 -0000
@@ -95,9 +95,6 @@ typedef struct inline_data
   int in_target_cleanup_p;
   /* A list of the functions current function has inlined.  */
   varray_type inlined_fns;
-  /* The approximate number of instructions we have inlined in the
-     current call stack.  */
-  int inlined_insns;
   /* We use the same mechanism to build clones that we do to perform
      inlining.  However, there are a few places where we need to
      distinguish between those two situations.  This flag is true if
@@ -1569,11 +1566,6 @@ expand_call_inline (tree *tp, int *walk_
      the equivalent inlined version either.  */
   TREE_USED (*tp) = 1;
 
-  /* Our function now has more statements than it did before.  */
-  DECL_ESTIMATED_INSNS (VARRAY_TREE (id->fns, 0)) += DECL_ESTIMATED_INSNS (fn);
-  /* For accounting, subtract one for the saved call/ret.  */
-  id->inlined_insns += DECL_ESTIMATED_INSNS (fn) - 1;
-
   /* Update callgraph if needed.  */
   if (id->decl)
     {
@@ -1590,11 +1582,6 @@ expand_call_inline (tree *tp, int *walk_
   }
   VARRAY_POP (id->fns);
 
-  /* If we've returned to the top level, clear out the record of how
-     much inlining has been done.  */
-  if (VARRAY_ACTIVE_SIZE (id->fns) == id->first_inlined_fn)
-    id->inlined_insns = 0;
-
   /* Don't walk into subtrees.  We've already handled them above.  */
   *walk_subtrees = 0;
 
@@ -1634,9 +1621,6 @@ optimize_inline_calls (tree fn)
   /* Don't allow recursion into FN.  */
   VARRAY_TREE_INIT (id.fns, 32, "fns");
   VARRAY_PUSH_TREE (id.fns, fn);
-  if (!DECL_ESTIMATED_INSNS (fn))
-    DECL_ESTIMATED_INSNS (fn) 
-      = (*lang_hooks.tree_inlining.estimate_num_insns) (fn);
   /* Or any functions that aren't finished yet.  */
   prev_fn = NULL_TREE;
   if (current_function_decl)
===================================================================
Index: cgraphunit.c
--- cgraphunit.c	1 Feb 2004 13:01:09 -0000	1.46.2.4
+++ cgraphunit.c	8 Feb 2004 01:09:38 -0000
@@ -327,10 +327,9 @@ cgraph_analyze_function (struct cgraph_n
   cgraph_create_edges (decl, DECL_SAVED_TREE (decl));
 
   node->local.inlinable = tree_inlinable_function_p (decl);
-  if (!DECL_ESTIMATED_INSNS (decl))
-    DECL_ESTIMATED_INSNS (decl)
+  if (!node->local.self_insns)
+    node->local.self_insns
       = (*lang_hooks.tree_inlining.estimate_num_insns) (decl);
-  node->local.self_insns = DECL_ESTIMATED_INSNS (decl);
   if (node->local.inlinable)
     node->local.disregard_inline_limits
       = (*lang_hooks.tree_inlining.disregard_inline_limits) (decl);
===================================================================
Index: cp/optimize.c
--- cp/optimize.c	25 Jan 2004 02:52:32 -0000	1.103.4.1
+++ cp/optimize.c	8 Feb 2004 01:09:39 -0000
@@ -232,10 +232,6 @@ maybe_clone_body (tree fn)
       /* Clone the body.  */
       clone_body (clone, fn, decl_map);
 
-      /* There are as many statements in the clone as in the
-	 original.  */
-      DECL_ESTIMATED_INSNS (clone) = DECL_ESTIMATED_INSNS (fn);
-
       /* Clean up.  */
       splay_tree_delete (decl_map);
 
===================================================================
Index: cp/decl.c
--- cp/decl.c	7 Feb 2004 09:43:01 -0000	1.1174.2.7
+++ cp/decl.c	8 Feb 2004 01:09:39 -0000
@@ -1853,8 +1853,6 @@ duplicate_decls (tree newdecl, tree oldd
 		 regardless of declaration matches.  */
 	      SET_DECL_RTL (newdecl, DECL_RTL (olddecl));
 	    }
-	  else
-	    DECL_ESTIMATED_INSNS (newdecl) = DECL_ESTIMATED_INSNS (olddecl);
 
 	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
 	  /* Don't clear out the arguments if we're redefining a function.  */
@@ -10257,9 +10255,6 @@ start_function (tree declspecs, tree dec
 
   /* Start the statement-tree, start the tree now.  */
   begin_stmt_tree (&DECL_SAVED_TREE (decl1));
-
-  /* Don't double-count statements in templates.  */
-  DECL_ESTIMATED_INSNS (decl1) = 0;
 
   /* Let the user know we're compiling this function.  */
   announce_function (decl1);
===================================================================
Index: testsuite/gcc.dg/visibility-8.c
--- testsuite/gcc.dg/visibility-8.c	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/visibility-8.c	8 Feb 2004 01:09:41 -0000
@@ -0,0 +1,16 @@
+/* Test hidden visibility on built-in functions (for libc).  PR 13856.  */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-assembler "\\.hidden.*__GI_fputs_unlocked" } } */
+
+int fputs_unlocked (const char *restrict, int *restrict)
+   __asm__ ("__GI_fputs_unlocked")
+   __attribute__ ((visibility ("hidden")));
+
+int
+fputs_unlocked (str, fp)
+     const char *str;
+     int *fp;
+{
+}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13856


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