Commit abc79c64 by Jason Merrill

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.
parent 613c932f
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> 2020-02-12 Jason Merrill <jason@redhat.com>
PR c++/92583 PR c++/92583
......
...@@ -5266,6 +5266,10 @@ decl_linkage (tree decl) ...@@ -5266,6 +5266,10 @@ decl_linkage (tree decl)
if (TREE_CODE (decl) == FIELD_DECL) if (TREE_CODE (decl) == FIELD_DECL)
return lk_none; 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. */ /* Things that are TREE_PUBLIC have external linkage. */
if (TREE_PUBLIC (decl)) if (TREE_PUBLIC (decl))
return lk_external; return lk_external;
...@@ -5285,11 +5289,6 @@ decl_linkage (tree decl) ...@@ -5285,11 +5289,6 @@ decl_linkage (tree decl)
if (TREE_CODE (decl) == CONST_DECL) if (TREE_CODE (decl) == CONST_DECL)
return decl_linkage (TYPE_NAME (DECL_CONTEXT (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 /* Members of the anonymous namespace also have TREE_PUBLIC unset, but
are considered to have external linkage for language purposes, as do are considered to have external linkage for language purposes, as do
template instantiations on targets without weak symbols. DECLs really template instantiations on targets without weak symbols. DECLs really
......
// 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();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment