decl2.c (determine_visibility): Make anonymous types internal.

* decl2.c (determine_visibility): Make anonymous types internal.
	(mark_used): Complain about types without linkage used in
	decls with internal linkage.
	(vague_linkage_fn_p): Split out from...
	* decl.c (maybe_commonize_var): ...here.
	(grokdeclarator): Adjust linkage when a typedef gives linkage name.
	* tree.c (no_linkage_check): Check the enclosing class and template
	arguments.

	* cp-tree.h (TYPE_NAMESPACE_SCOPE_P): New.

From-SVN: r151868
This commit is contained in:
Jason Merrill 2009-09-18 17:25:18 -04:00 committed by Jason Merrill
parent 5f5babf18b
commit ecc607fc08
9 changed files with 127 additions and 15 deletions

View File

@ -1,5 +1,16 @@
2009-09-18 Jason Merrill <jason@redhat.com>
* decl2.c (determine_visibility): Make anonymous types internal.
(mark_used): Complain about types without linkage used in
decls with internal linkage.
(vague_linkage_fn_p): Split out from...
* decl.c (maybe_commonize_var): ...here.
(grokdeclarator): Adjust linkage when a typedef gives linkage name.
* tree.c (no_linkage_check): Check the enclosing class and template
arguments.
* cp-tree.h (TYPE_NAMESPACE_SCOPE_P): New.
* pt.c (get_pattern_parm): New.
(listify): Split out from...
(listify_autos): ...here.

View File

@ -2129,6 +2129,9 @@ struct GTY(()) lang_decl {
(!DECL_TEMPLATE_PARM_P (NODE) \
&& TREE_CODE (CP_DECL_CONTEXT (NODE)) == NAMESPACE_DECL)
#define TYPE_NAMESPACE_SCOPE_P(NODE) \
(TREE_CODE (CP_TYPE_CONTEXT (NODE)) == NAMESPACE_DECL)
/* 1 iff NODE is a class member. */
#define DECL_CLASS_SCOPE_P(NODE) \
(DECL_CONTEXT (NODE) && TYPE_P (DECL_CONTEXT (NODE)))
@ -4457,6 +4460,7 @@ extern bool check_java_method (tree);
extern tree build_memfn_type (tree, tree, cp_cv_quals);
extern void maybe_retrofit_in_chrg (tree);
extern void maybe_make_one_only (tree);
extern bool vague_linkage_fn_p (tree);
extern void grokclassfn (tree, tree,
enum overload_flags);
extern tree grok_array_decl (tree, tree);

View File

@ -4615,13 +4615,7 @@ maybe_commonize_var (tree decl)
/* Don't mess with __FUNCTION__. */
&& ! DECL_ARTIFICIAL (decl)
&& DECL_FUNCTION_SCOPE_P (decl)
/* Unfortunately, import_export_decl has not always been called
before the function is processed, so we cannot simply check
DECL_COMDAT. */
&& (DECL_COMDAT (DECL_CONTEXT (decl))
|| ((DECL_DECLARED_INLINE_P (DECL_CONTEXT (decl))
|| DECL_TEMPLATE_INSTANTIATION (DECL_CONTEXT (decl)))
&& TREE_PUBLIC (DECL_CONTEXT (decl)))))
&& vague_linkage_fn_p (DECL_CONTEXT (decl)))
{
if (flag_weak)
{
@ -8845,6 +8839,10 @@ grokdeclarator (const cp_declarator *declarator,
DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
= TYPE_IDENTIFIER (type);
/* Adjust linkage now that we aren't anonymous anymore. */
set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
determine_visibility (TYPE_MAIN_DECL (type));
/* FIXME remangle member functions; member functions of a
type with external linkage have external linkage. */
}

View File

@ -1605,6 +1605,22 @@ maybe_make_one_only (tree decl)
}
}
/* Returns true iff DECL, a FUNCTION_DECL, has vague linkage. This
predicate will give the right answer during parsing of the function,
which other tests may not. */
bool
vague_linkage_fn_p (tree fn)
{
/* Unfortunately, import_export_decl has not always been called
before the function is processed, so we cannot simply check
DECL_COMDAT. */
return (DECL_COMDAT (fn)
|| ((DECL_DECLARED_INLINE_P (fn)
|| DECL_TEMPLATE_INSTANTIATION (fn))
&& TREE_PUBLIC (fn)));
}
/* Determine whether or not we want to specifically import or export CTYPE,
using various heuristics. */
@ -2075,6 +2091,16 @@ determine_visibility (tree decl)
|| ! DECL_VISIBILITY_SPECIFIED (decl))
constrain_visibility (decl, tvis);
}
else if (no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/true))
/* DR 757: A type without linkage shall not be used as the type of a
variable or function with linkage, unless
o the variable or function has extern "C" linkage (7.5 [dcl.link]), or
o the variable or function is not used (3.2 [basic.def.odr]) or is
defined in the same translation unit.
Since non-extern "C" decls need to be defined in the same
translation unit, we can make the type internal. */
constrain_visibility (decl, VISIBILITY_ANON);
/* If visibility changed and DECL already has DECL_RTL, ensure
symbol flags are updated. */
@ -3966,7 +3992,7 @@ mark_used (tree decl)
o the variable or function has extern "C" linkage (7.5 [dcl.link]), or
o the variable or function is not used (3.2 [basic.def.odr]) or is
defined in the same translation unit. */
if (TREE_PUBLIC (decl)
if (decl_linkage (decl) != lk_none
&& !DECL_EXTERN_C_P (decl)
&& !DECL_ARTIFICIAL (decl)
&& !decl_defined_p (decl)

View File

@ -1513,7 +1513,7 @@ verify_stmt_tree (tree t)
/* Check if the type T depends on a type with no linkage and if so, return
it. If RELAXED_P then do not consider a class type declared within
a TREE_PUBLIC function to have no linkage. */
a vague-linkage function to have no linkage. */
tree
no_linkage_check (tree t, bool relaxed_p)
@ -1527,8 +1527,6 @@ no_linkage_check (tree t, bool relaxed_p)
switch (TREE_CODE (t))
{
tree fn;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
goto ptrmem;
@ -1536,13 +1534,42 @@ no_linkage_check (tree t, bool relaxed_p)
case UNION_TYPE:
if (!CLASS_TYPE_P (t))
return NULL_TREE;
/* Check template type-arguments. I think that types with no linkage
can't occur in non-type arguments, though that might change with
constexpr. */
r = CLASSTYPE_TEMPLATE_INFO (t);
if (r)
{
tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (r));
int i;
for (i = TREE_VEC_LENGTH (args); i-- > 0; )
{
tree elt = TREE_VEC_ELT (args, i);
if (TYPE_P (elt)
&& (r = no_linkage_check (elt, relaxed_p), r))
return r;
}
}
/* Fall through. */
case ENUMERAL_TYPE:
if (TYPE_ANONYMOUS_P (t))
return t;
fn = decl_function_context (TYPE_MAIN_DECL (t));
if (fn && (!relaxed_p || !TREE_PUBLIC (fn)))
/* Only treat anonymous types as having no linkage if they're at
namespace scope. This doesn't have a core issue number yet. */
if (TYPE_ANONYMOUS_P (t) && TYPE_NAMESPACE_SCOPE_P (t))
return t;
r = CP_TYPE_CONTEXT (t);
if (TYPE_P (r))
return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
else if (TREE_CODE (r) == FUNCTION_DECL)
{
if (!relaxed_p || !TREE_PUBLIC (r) || !vague_linkage_fn_p (r))
return t;
else
return no_linkage_check (CP_DECL_CONTEXT (r), relaxed_p);
}
return NULL_TREE;
case ARRAY_TYPE:

View File

@ -1,5 +1,7 @@
2009-09-18 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/nolinkage1{.C,.h,a.cc}: New.
* g++.dg/cpp0x/initlist-deduce.C: New.
2009-09-18 Janis Johnson <janis187@us.ibm.com>

View File

@ -0,0 +1,21 @@
// DR 757 allows using types without linkage in declarations with linkage.
// Test that this doesn't lead to link-time collisions.
// { dg-additional-sources "nolinkage1a.cc" }
// { dg-do link }
#include "nolinkage1.h"
typedef struct { int i; } *AP;
void f(AP) { }
A<AP> a;
static void g()
{
struct B { };
A<B> a;
}
int main() { g(); f(0); }

View File

@ -0,0 +1,8 @@
template <class T>
struct A
{
A();
};
template <class T>
A<T>::A() { }

View File

@ -0,0 +1,15 @@
#include "nolinkage1.h"
typedef struct { double d; } *BP;
void f(BP) { }
A<BP> b;
static void g()
{
struct B { };
A<B> a;
}
int dummy() { g(); f(0); }