From ba12ea31b1c211d2aa9d3f9c35f34156adbe5634 Mon Sep 17 00:00:00 2001 From: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Thu, 17 Aug 2006 11:52:26 +0000 Subject: [PATCH] PR c/28744 * cgraph.h (struct cgraph_node): Remove externally_visible bitfield. * cgraphunit.c (process_function_and_variable_attributes): Set local.externally_visible rather than externally_visible. PR c/28744 * c-common.c (handle_externally_visible_attribute): First look at TREE_CODE and only if it is function or var decl, check for non-public objects. Don't warn for DECL_EXTERNAL. * cgraphunit.c (process_function_and_variable_attributes): Warn if externally_visible attribute is used on non-public object. * gcc.dg/attr-externally-visible-1.c: New test. * gcc.dg/attr-externally-visible-2.c: New test. * g++.dg/parse/attr-externally-visible-1.C: New test. * g++.dg/parse/attr-externally-visible-2.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@116222 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 15 ++++++ gcc/c-common.c | 16 +++---- gcc/cgraph.h | 2 - gcc/cgraphunit.c | 26 +++++++--- gcc/testsuite/ChangeLog | 8 ++++ .../g++.dg/parse/attr-externally-visible-1.C | 48 +++++++++++++++++++ .../g++.dg/parse/attr-externally-visible-2.C | 38 +++++++++++++++ .../gcc.dg/attr-externally-visible-1.c | 48 +++++++++++++++++++ .../gcc.dg/attr-externally-visible-2.c | 33 +++++++++++++ 9 files changed, 218 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/attr-externally-visible-1.C create mode 100644 gcc/testsuite/g++.dg/parse/attr-externally-visible-2.C create mode 100644 gcc/testsuite/gcc.dg/attr-externally-visible-1.c create mode 100644 gcc/testsuite/gcc.dg/attr-externally-visible-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6b36ab8a95fc..61d5fe0d7e88 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2006-08-17 Jakub Jelinek <jakub@redhat.com> + + PR c/28744 + * cgraph.h (struct cgraph_node): Remove externally_visible + bitfield. + * cgraphunit.c (process_function_and_variable_attributes): Set + local.externally_visible rather than externally_visible. + + PR c/28744 + * c-common.c (handle_externally_visible_attribute): First look + at TREE_CODE and only if it is function or var decl, check for + non-public objects. Don't warn for DECL_EXTERNAL. + * cgraphunit.c (process_function_and_variable_attributes): Warn + if externally_visible attribute is used on non-public object. + 2006-08-17 Jan Hubicka <jh@suse.cz> PR tree-optimization/27865 diff --git a/gcc/c-common.c b/gcc/c-common.c index 17643f0b5abc..a6b329997b4d 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -4301,16 +4301,16 @@ handle_externally_visible_attribute (tree *pnode, tree name, { tree node = *pnode; - if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL) - || !TREE_PUBLIC (node)) + if (TREE_CODE (node) == FUNCTION_DECL || TREE_CODE (node) == VAR_DECL) { - warning (OPT_Wattributes, - "%qE attribute have effect only on public objects", name); - *no_add_attrs = true; + if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL + && !DECL_EXTERNAL (node)) || !TREE_PUBLIC (node)) + { + warning (OPT_Wattributes, + "%qE attribute have effect only on public objects", name); + *no_add_attrs = true; + } } - else if (TREE_CODE (node) == FUNCTION_DECL - || TREE_CODE (node) == VAR_DECL) - ; else { warning (OPT_Wattributes, "%qE attribute ignored", name); diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 31ddfe37d0ae..7b69611ddcd0 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -160,8 +160,6 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) unsigned analyzed : 1; /* Set when function is scheduled to be assembled. */ unsigned output : 1; - /* Set when function is visible by other units. */ - unsigned externally_visible : 1; /* Set for aliases once they got through assemble_alias. */ unsigned alias : 1; diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index ddaecd3aa1c6..64b3891df7bc 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -985,9 +985,16 @@ process_function_and_variable_attributes (struct cgraph_node *first, } if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) { - if (node->local.finalized) - cgraph_mark_needed_node (node); - node->externally_visible = true; + if (! TREE_PUBLIC (node->decl)) + warning (OPT_Wattributes, + "%J%<externally_visible%> attribute have effect only on public objects", + node->decl); + else + { + if (node->local.finalized) + cgraph_mark_needed_node (node); + node->local.externally_visible = true; + } } } for (vnode = cgraph_varpool_nodes; vnode != first_var; vnode = vnode->next) @@ -1001,9 +1008,16 @@ process_function_and_variable_attributes (struct cgraph_node *first, } if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) { - if (vnode->finalized) - cgraph_varpool_mark_needed_node (vnode); - vnode->externally_visible = true; + if (! TREE_PUBLIC (vnode->decl)) + warning (OPT_Wattributes, + "%J%<externally_visible%> attribute have effect only on public objects", + vnode->decl); + else + { + if (vnode->finalized) + cgraph_varpool_mark_needed_node (vnode); + vnode->externally_visible = true; + } } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3ccd52def7b9..3c65908443f9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2006-08-17 Jakub Jelinek <jakub@redhat.com> + + PR c/28744 + * gcc.dg/attr-externally-visible-1.c: New test. + * gcc.dg/attr-externally-visible-2.c: New test. + * g++.dg/parse/attr-externally-visible-1.C: New test. + * g++.dg/parse/attr-externally-visible-2.C: New test. + 2006-08-17 Volker Reichelt <reichelt@igpm.rwth-aachen.de> PR c++/28606 diff --git a/gcc/testsuite/g++.dg/parse/attr-externally-visible-1.C b/gcc/testsuite/g++.dg/parse/attr-externally-visible-1.C new file mode 100644 index 000000000000..9016bc4225af --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/attr-externally-visible-1.C @@ -0,0 +1,48 @@ +// { dg-do compile } +// { dg-options "-O3 -fwhole-program" } +// { dg-final { scan-assembler "foo1" } } +// { dg-final { scan-assembler "foo2" } } +// { dg-final { scan-assembler "foo3" } } +// { dg-final { scan-assembler "foo4" } } +// { dg-final { scan-assembler "foo5" } } +// { dg-final { scan-assembler-not "foo6" } } +// { dg-final { scan-assembler "bar1" } } +// { dg-final { scan-assembler "bar2" } } +// { dg-final { scan-assembler "bar3" } } +// { dg-final { scan-assembler "bar4" } } +// { dg-final { scan-assembler "bar5" } } +// { dg-final { scan-assembler-not "bar6" } } + +extern void foo1 (void) __attribute__((externally_visible)); +void foo1 (void) { } + +extern void foo2 (void) __attribute__((externally_visible)); +__attribute__((externally_visible)) void foo2 (void) { } + +extern void foo3 (void); +__attribute__((externally_visible)) void foo3 (void) { } + +__attribute__((externally_visible)) void foo4 (void) { } + +void foo5 (void) { } +extern void foo5 (void) __attribute__((externally_visible)); + +void foo6 (void) { } + +extern char *bar1 __attribute__((externally_visible)); +char *bar1; + +extern char *bar2 __attribute__((externally_visible)); +char *bar2 __attribute__((externally_visible)); + +extern char *bar3; +char *bar3 __attribute__((externally_visible)); + +char *bar4 __attribute__((externally_visible)); + +char *bar5; +extern char *bar5 __attribute__((externally_visible)); + +char *bar6; + +int main (void) { } diff --git a/gcc/testsuite/g++.dg/parse/attr-externally-visible-2.C b/gcc/testsuite/g++.dg/parse/attr-externally-visible-2.C new file mode 100644 index 000000000000..d7feaabb2d11 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/attr-externally-visible-2.C @@ -0,0 +1,38 @@ +// { dg-do compile } +// { dg-options "-O -fwhole-program" } + +static void foo1 (void) { } // { dg-warning "have effect only on public" } +extern void foo1 (void) __attribute__((externally_visible)); + +struct C +{ + __attribute__((externally_visible)) void foo3 (void) { } +}; + +__attribute__((externally_visible)) static void foo3 (void) { } // { dg-warning "have effect only on public" } + +static int bar1; +extern int bar1 __attribute__((externally_visible)); // { dg-warning "have effect only on public" } + +static int bar2 __attribute__((externally_visible)); // { dg-warning "have effect only on public" } + +void fn1 (void) +{ + static int bar3 __attribute__((externally_visible)); // { dg-warning "have effect only on public" } +} + +void fn2 (void) +{ + int bar4 __attribute__((externally_visible)); // { dg-warning "have effect only on public" } +} + +struct A +{ +} __attribute__((externally_visible)); // { dg-warning "does not apply to types" } + +typedef int B __attribute__((externally_visible)); // { dg-warning "attribute ignored" } + +struct D +{ + static int d __attribute__((externally_visible)); +}; diff --git a/gcc/testsuite/gcc.dg/attr-externally-visible-1.c b/gcc/testsuite/gcc.dg/attr-externally-visible-1.c new file mode 100644 index 000000000000..e1db6923a484 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-externally-visible-1.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fwhole-program" } */ +/* { dg-final { scan-assembler "foo1" } } */ +/* { dg-final { scan-assembler "foo2" } } */ +/* { dg-final { scan-assembler "foo3" } } */ +/* { dg-final { scan-assembler "foo4" } } */ +/* { dg-final { scan-assembler "foo5" } } */ +/* { dg-final { scan-assembler-not "foo6" } } */ +/* { dg-final { scan-assembler "bar1" } } */ +/* { dg-final { scan-assembler "bar2" } } */ +/* { dg-final { scan-assembler "bar3" } } */ +/* { dg-final { scan-assembler "bar4" } } */ +/* { dg-final { scan-assembler "bar5" } } */ +/* { dg-final { scan-assembler-not "bar6" } } */ + +extern void foo1 (void) __attribute__((externally_visible)); +void foo1 (void) { } + +extern void foo2 (void) __attribute__((externally_visible)); +__attribute__((externally_visible)) void foo2 (void) { } + +extern void foo3 (void); +__attribute__((externally_visible)) void foo3 (void) { } + +__attribute__((externally_visible)) void foo4 (void) { } + +void foo5 (void) { } +extern void foo5 (void) __attribute__((externally_visible)); + +void foo6 (void) { } + +extern char *bar1 __attribute__((externally_visible)); +char *bar1; + +extern char *bar2 __attribute__((externally_visible)); +char *bar2 __attribute__((externally_visible)); + +extern char *bar3; +char *bar3 __attribute__((externally_visible)); + +char *bar4 __attribute__((externally_visible)); + +char *bar5; +extern char *bar5 __attribute__((externally_visible)); + +char *bar6; + +int main (void) { } diff --git a/gcc/testsuite/gcc.dg/attr-externally-visible-2.c b/gcc/testsuite/gcc.dg/attr-externally-visible-2.c new file mode 100644 index 000000000000..0a925bab3d94 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-externally-visible-2.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fwhole-program" } */ + +static void foo1 (void) { } /* { dg-warning "have effect only on public" } */ +extern void foo1 (void) __attribute__((externally_visible)); + +void foo2 (void) +{ + __attribute__((externally_visible)) void foo3 (void) { } /* { dg-warning "have effect only on public" } */ +} + +__attribute__((externally_visible)) static void foo3 (void) { } /* { dg-warning "have effect only on public" } */ + +static int bar1; +extern int bar1 __attribute__((externally_visible)); /* { dg-warning "have effect only on public" } */ + +static int bar2 __attribute__((externally_visible)); /* { dg-warning "have effect only on public" } */ + +void fn1 (void) +{ + static int bar3 __attribute__((externally_visible)); /* { dg-warning "have effect only on public" } */ +} + +void fn2 (void) +{ + int bar4 __attribute__((externally_visible)); /* { dg-warning "have effect only on public" } */ +} + +struct A +{ +} __attribute__((externally_visible)); /* { dg-warning "does not apply to types" } */ + +typedef int B __attribute__((externally_visible)); /* { dg-warning "attribute ignored" } */ -- GitLab