From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2709 invoked by alias); 8 Feb 2004 01:54:10 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 2174 invoked by alias); 8 Feb 2004 01:54:06 -0000 Date: Sun, 08 Feb 2004 01:54:00 -0000 Message-ID: <20040208015406.2172.qmail@sources.redhat.com> From: "zack at codesourcery dot com" To: gcc-bugs@gcc.gnu.org In-Reply-To: <20040125122814.13856.aj@gcc.gnu.org> References: <20040125122814.13856.aj@gcc.gnu.org> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug c/13856] [3.4/3.5 Regression] hidden support broken with builtin functions X-Bugzilla-Reason: CC X-SW-Source: 2004-02/txt/msg00915.txt.bz2 List-Id: ------- 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