diff options
author | Jan Hubicka <jh@suse.cz> | 2006-07-24 02:16:16 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2006-07-24 00:16:16 +0000 |
commit | 386b46cf78f852e82fb1f37ba271858b1f1040b3 (patch) | |
tree | 20047ee6f873662157a0d8d8f27ffbacb9260691 /gcc | |
parent | 3201e73d96ae8bd6425828a807987f35f1f7bd32 (diff) | |
download | gcc-386b46cf78f852e82fb1f37ba271858b1f1040b3.zip gcc-386b46cf78f852e82fb1f37ba271858b1f1040b3.tar.gz gcc-386b46cf78f852e82fb1f37ba271858b1f1040b3.tar.bz2 |
re PR c/25795 (Proccessing the attribute externally_visible too early)
PR c/25795
PR c++/27369
* cgraph.c (cgraph_varpool_nodes): Export.
(decide_is_variable_needed): Ignored "used" attribute in
unit-at-a-time mode.
* cgraph.h (cgraph_varpool_nodes): Declare.
* cgraphunit.c (decide_is_function_needed): Ignored "used" attribute in
unit-at-a-time mode.
* gcc.dg/pr25795.c: New test.
* gcc.dg/pr25795-1.c: New test.
From-SVN: r115693
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/c-common.c | 17 | ||||
-rw-r--r-- | gcc/c-decl.c | 2 | ||||
-rw-r--r-- | gcc/cgraph.c | 11 | ||||
-rw-r--r-- | gcc/cgraph.h | 1 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 74 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr25795-1.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr25795.c | 10 |
9 files changed, 122 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 995e399..d23808d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2006-07-23 Jan Hubicka <jh@suse.cz> + + PR c/25795 + PR c++/27369 + * cgraph.c (cgraph_varpool_nodes): Export. + (decide_is_variable_needed): Ignored "used" attribute in + unit-at-a-time mode. + * cgraph.h (cgraph_varpool_nodes): Declare. + * cgraphunit.c (decide_is_function_needed): Ignored "used" attribute in + unit-at-a-time mode. + 2006-07-23 Roger Sayle <roger@eyesopen.com> PR target/28247 diff --git a/gcc/c-common.c b/gcc/c-common.c index 9c26061..71f8ce6 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -4308,20 +4308,9 @@ handle_externally_visible_attribute (tree *pnode, tree name, "%qE attribute have effect only on public objects", name); *no_add_attrs = true; } - else if (TREE_CODE (node) == FUNCTION_DECL) - { - struct cgraph_node *n = cgraph_node (node); - n->local.externally_visible = true; - if (n->local.finalized) - cgraph_mark_needed_node (n); - } - else if (TREE_CODE (node) == VAR_DECL) - { - struct cgraph_varpool_node *n = cgraph_varpool_node (node); - n->externally_visible = true; - if (n->finalized) - cgraph_varpool_mark_needed_node (n); - } + else if (TREE_CODE (node) == FUNCTION_DECL + || TREE_CODE (node) == VAR_DECL) + ; else { warning (OPT_Wattributes, "%qE attribute ignored", name); diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 6ad6a69..b900e8a 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -3554,7 +3554,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) } /* If this was marked 'used', be sure it will be output. */ - if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) + if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl))) mark_decl_referenced (decl); if (TREE_CODE (decl) == TYPE_DECL) diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 04ff094..5dd0afb 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -137,7 +137,7 @@ static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash; struct cgraph_varpool_node *cgraph_varpool_nodes_queue, *cgraph_varpool_first_unanalyzed_node; /* The linked list of cgraph varpool nodes. */ -static GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes; +struct cgraph_varpool_node *cgraph_varpool_nodes; /* End of the varpool queue. Needs to be QTYed to work with PCH. */ static GTY(()) struct cgraph_varpool_node *cgraph_varpool_last_needed_node; @@ -843,8 +843,10 @@ bool decide_is_variable_needed (struct cgraph_varpool_node *node, tree decl) { /* If the user told us it is used, then it must be so. */ - if (node->externally_visible - || lookup_attribute ("used", DECL_ATTRIBUTES (decl))) + if (node->externally_visible) + return true; + if (!flag_unit_at_a_time + && lookup_attribute ("used", DECL_ATTRIBUTES (decl))) return true; /* ??? If the assembler name is set by hand, it is possible to assemble @@ -861,7 +863,8 @@ decide_is_variable_needed (struct cgraph_varpool_node *node, tree decl) /* Externally visible variables must be output. The exception is COMDAT variables that must be output only when they are needed. */ - if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) + if (TREE_PUBLIC (decl) && !flag_whole_program && !DECL_COMDAT (decl) + && !DECL_EXTERNAL (decl)) return true; /* When not reordering top level variables, we have to assume that diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 3a1665f..31ddfe3 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -249,6 +249,7 @@ extern GTY(()) struct cgraph_node *cgraph_expand_queue; extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_first_unanalyzed_node; extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue; +extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes; extern GTY(()) struct cgraph_asm_node *cgraph_asm_nodes; extern GTY(()) int cgraph_order; diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index d02ead5..c0e4149 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -198,8 +198,10 @@ decide_is_function_needed (struct cgraph_node *node, tree decl) } /* If the user told us it is used, then it must be so. */ - if (node->local.externally_visible - || lookup_attribute ("used", DECL_ATTRIBUTES (decl))) + if (node->local.externally_visible) + return true; + + if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl))) return true; /* ??? If the assembler name is set by hand, it is possible to assemble @@ -937,6 +939,71 @@ cgraph_analyze_function (struct cgraph_node *node) current_function_decl = NULL; } +/* Look for externally_visible and used attributes and mark cgraph nodes + accordingly. + + We cannot mark the nodes at the point the attributes are processed (in + handle_*_attribute) because the copy of the declarations available at that + point may not be canonical. For example, in: + + void f(); + void f() __attribute__((used)); + + the declaration we see in handle_used_attribute will be the second + declaration -- but the front end will subsequently merge that declaration + with the original declaration and discard the second declaration. + + Furthermore, we can't mark these nodes in cgraph_finalize_function because: + + void f() {} + void f() __attribute__((externally_visible)); + + is valid. + + So, we walk the nodes at the end of the translation unit, applying the + attributes at that point. */ + +static void +process_function_and_variable_attributes (struct cgraph_node *first, + struct cgraph_varpool_node *first_var) +{ + struct cgraph_node *node; + struct cgraph_varpool_node *vnode; + + for (node = cgraph_nodes; node != first; node = node->next) + { + tree decl = node->decl; + if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) + { + mark_decl_referenced (decl); + if (node->local.finalized) + cgraph_mark_needed_node (node); + } + if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) + { + if (node->local.finalized) + cgraph_mark_needed_node (node); + node->externally_visible = true; + } + } + for (vnode = cgraph_varpool_nodes; vnode != first_var; vnode = vnode->next) + { + tree decl = vnode->decl; + if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) + { + mark_decl_referenced (decl); + if (vnode->finalized) + cgraph_varpool_mark_needed_node (vnode); + } + if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) + { + if (vnode->finalized) + cgraph_varpool_mark_needed_node (vnode); + vnode->externally_visible = true; + } + } +} + /* Analyze the whole compilation unit once it is parsed completely. */ void @@ -946,6 +1013,7 @@ cgraph_finalize_compilation_unit (void) /* Keep track of already processed nodes when called multiple times for intermodule optimization. */ static struct cgraph_node *first_analyzed; + static struct cgraph_varpool_node *first_analyzed_var; finish_aliases_1 (); @@ -963,6 +1031,7 @@ cgraph_finalize_compilation_unit (void) } timevar_push (TV_CGRAPH); + process_function_and_variable_attributes (first_analyzed, first_analyzed_var); cgraph_varpool_analyze_pending_decls (); if (cgraph_dump_file) { @@ -1047,6 +1116,7 @@ cgraph_finalize_compilation_unit (void) dump_cgraph (cgraph_dump_file); } first_analyzed = cgraph_nodes; + first_analyzed_var = cgraph_varpool_nodes; ggc_collect (); timevar_pop (TV_CGRAPH); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 310564c..8e92c9b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2006-07-24 Jan Hubicka <jh@suse.cz> + + PR c/25795 + PR c++/27369 + * gcc.dg/pr25795.c: New test. + * gcc.dg/pr25795-1.c: New test. + 2006-07-23 Roger Sayle <roger@eyesopen.com> * gcc.dg/fold-cond-1.c: Increase test case portability by checking diff --git a/gcc/testsuite/gcc.dg/pr25795-1.c b/gcc/testsuite/gcc.dg/pr25795-1.c new file mode 100644 index 0000000..e568b25 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr25795-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fwhole-program" } */ +/* { dg-final { scan-assembler-not "mystr" } } */ + + +extern const char *mystr; /* normally in a header */ +const char *mystr; +main() +{ +} diff --git a/gcc/testsuite/gcc.dg/pr25795.c b/gcc/testsuite/gcc.dg/pr25795.c new file mode 100644 index 0000000..decbe54 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr25795.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fwhole-program" } */ +/* { dg-final { scan-assembler "mystr" } } */ + + +extern const char *mystr; /* normally in a header */ +const char *mystr __attribute__ ((externally_visible)); +main() +{ +} |