diff options
author | Jason Merrill <jason@redhat.com> | 2020-02-13 16:42:04 +0100 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-02-13 22:29:25 +0100 |
commit | abc79c6498a99e9c39e6056f432796c6dde3a887 (patch) | |
tree | 1093a665d33c96e5f27b37b70894361574830d42 | |
parent | 613c932f5e5c0cc2e4b88e21d9870fa7b1a6ce5d (diff) | |
download | gcc-abc79c6498a99e9c39e6056f432796c6dde3a887.zip gcc-abc79c6498a99e9c39e6056f432796c6dde3a887.tar.gz gcc-abc79c6498a99e9c39e6056f432796c6dde3a887.tar.bz2 |
c++: Fix static local vars in extern "C".
Since my patch for PR 91476 moved visibility determination sooner, a local
static in a vague linkage function now gets TREE_PUBLIC set before
retrofit_lang_decl calls set_decl_linkage, which was making decl_linkage
think that it has external linkage. It still has no linkage according to
the standard.
gcc/cp/ChangeLog
2020-02-13 Jason Merrill <jason@redhat.com>
PR c++/93643
PR c++/91476
* tree.c (decl_linkage): Always lk_none for locals.
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/tree.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/extern-c-static1.C | 27 |
3 files changed, 37 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e0dd038..8d7d91c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-02-13 Jason Merrill <jason@redhat.com> + + PR c++/93643 + PR c++/91476 + * tree.c (decl_linkage): Always lk_none for locals. + 2020-02-12 Jason Merrill <jason@redhat.com> PR c++/92583 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 736ef6f..72b3a72 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -5266,6 +5266,10 @@ decl_linkage (tree decl) if (TREE_CODE (decl) == FIELD_DECL) return lk_none; + /* Things in local scope do not have linkage. */ + if (decl_function_context (decl)) + return lk_none; + /* Things that are TREE_PUBLIC have external linkage. */ if (TREE_PUBLIC (decl)) return lk_external; @@ -5285,11 +5289,6 @@ decl_linkage (tree decl) if (TREE_CODE (decl) == CONST_DECL) return decl_linkage (TYPE_NAME (DECL_CONTEXT (decl))); - /* Things in local scope do not have linkage, if they don't have - TREE_PUBLIC set. */ - if (decl_function_context (decl)) - return lk_none; - /* Members of the anonymous namespace also have TREE_PUBLIC unset, but are considered to have external linkage for language purposes, as do template instantiations on targets without weak symbols. DECLs really diff --git a/gcc/testsuite/g++.dg/lookup/extern-c-static1.C b/gcc/testsuite/g++.dg/lookup/extern-c-static1.C new file mode 100644 index 0000000..0ba8d67 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/extern-c-static1.C @@ -0,0 +1,27 @@ +// PR c++/93643 + +void* callback(const char* name); + +extern "C" { + + inline void f1() + { + static void (*f)(); + f = (void(*)()) callback("f1"); + f(); + } + + inline void f2() + { + static void (*f)(); + f = (void(*)()) callback("f2"); + f(); + } + +} // extern "C" + +int main() +{ + f1(); + f2(); +} |