Commit 7c23c87c by Jason Merrill Committed by Jason Merrill

decl2.c (min_vis_expr_r, [...]): New.

	* decl2.c (min_vis_expr_r, expr_visibility): New.

We weren't properly constraining visibility based on names that appear in
the mangled representation of expressions.  This was made more obvious
by the upcoming unevaluated lambdas patch.

	(min_vis_r): Call expr_visibility.
	(constrain_visibility_for_template): Likewise.

From-SVN: r266054
parent a6bb6b07
2018-11-12 Jason Merrill <jason@redhat.com> 2018-11-12 Jason Merrill <jason@redhat.com>
* decl2.c (min_vis_expr_r, expr_visibility): New.
(min_vis_r): Call expr_visibility.
(constrain_visibility_for_template): Likewise.
Implement P0722R3, destroying operator delete. Implement P0722R3, destroying operator delete.
* call.c (std_destroying_delete_t_p, destroying_delete_p): New. * call.c (std_destroying_delete_t_p, destroying_delete_p): New.
(aligned_deallocation_fn_p, usual_deallocation_fn_p): Use (aligned_deallocation_fn_p, usual_deallocation_fn_p): Use
......
...@@ -2238,6 +2238,9 @@ maybe_emit_vtables (tree ctype) ...@@ -2238,6 +2238,9 @@ maybe_emit_vtables (tree ctype)
enum { VISIBILITY_ANON = VISIBILITY_INTERNAL+1 }; enum { VISIBILITY_ANON = VISIBILITY_INTERNAL+1 };
static int expr_visibility (tree);
static int type_visibility (tree);
/* walk_tree helper function for type_visibility. */ /* walk_tree helper function for type_visibility. */
static tree static tree
...@@ -2257,9 +2260,55 @@ min_vis_r (tree *tp, int *walk_subtrees, void *data) ...@@ -2257,9 +2260,55 @@ min_vis_r (tree *tp, int *walk_subtrees, void *data)
else if (CLASS_TYPE_P (*tp) else if (CLASS_TYPE_P (*tp)
&& CLASSTYPE_VISIBILITY (*tp) > *vis_p) && CLASSTYPE_VISIBILITY (*tp) > *vis_p)
*vis_p = CLASSTYPE_VISIBILITY (*tp); *vis_p = CLASSTYPE_VISIBILITY (*tp);
else if (TREE_CODE (*tp) == ARRAY_TYPE
&& uses_template_parms (TYPE_DOMAIN (*tp)))
{
int evis = expr_visibility (TYPE_MAX_VALUE (TYPE_DOMAIN (*tp)));
if (evis > *vis_p)
*vis_p = evis;
}
return NULL; return NULL;
} }
/* walk_tree helper function for expr_visibility. */
static tree
min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void *data)
{
int *vis_p = (int *)data;
int tpvis = VISIBILITY_DEFAULT;
switch (TREE_CODE (*tp))
{
case CAST_EXPR:
case IMPLICIT_CONV_EXPR:
case STATIC_CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
case NEW_EXPR:
case CONSTRUCTOR:
tpvis = type_visibility (TREE_TYPE (*tp));
break;
case VAR_DECL:
case FUNCTION_DECL:
if (! TREE_PUBLIC (*tp))
tpvis = VISIBILITY_ANON;
else
tpvis = DECL_VISIBILITY (*tp);
break;
default:
break;
}
if (tpvis > *vis_p)
*vis_p = tpvis;
return NULL_TREE;
}
/* Returns the visibility of TYPE, which is the minimum visibility of its /* Returns the visibility of TYPE, which is the minimum visibility of its
component types. */ component types. */
...@@ -2271,6 +2320,18 @@ type_visibility (tree type) ...@@ -2271,6 +2320,18 @@ type_visibility (tree type)
return vis; return vis;
} }
/* Returns the visibility of an expression EXPR that appears in the signature
of a function template, which is the minimum visibility of names that appear
in its mangling. */
static int
expr_visibility (tree expr)
{
int vis = VISIBILITY_DEFAULT;
cp_walk_tree_without_duplicates (&expr, min_vis_expr_r, &vis);
return vis;
}
/* Limit the visibility of DECL to VISIBILITY, if not explicitly /* Limit the visibility of DECL to VISIBILITY, if not explicitly
specified (or if VISIBILITY is static). If TMPL is true, this specified (or if VISIBILITY is static). If TMPL is true, this
constraint is for a template argument, and takes precedence constraint is for a template argument, and takes precedence
...@@ -2329,21 +2390,7 @@ constrain_visibility_for_template (tree decl, tree targs) ...@@ -2329,21 +2390,7 @@ constrain_visibility_for_template (tree decl, tree targs)
if (TYPE_P (arg)) if (TYPE_P (arg))
vis = type_visibility (arg); vis = type_visibility (arg);
else else
{ vis = expr_visibility (arg);
if (REFERENCE_REF_P (arg))
arg = TREE_OPERAND (arg, 0);
if (TREE_TYPE (arg))
STRIP_NOPS (arg);
if (TREE_CODE (arg) == ADDR_EXPR)
arg = TREE_OPERAND (arg, 0);
if (VAR_OR_FUNCTION_DECL_P (arg))
{
if (! TREE_PUBLIC (arg))
vis = VISIBILITY_ANON;
else
vis = DECL_VISIBILITY (arg);
}
}
if (vis) if (vis)
constrain_visibility (decl, vis, true); constrain_visibility (decl, vis, true);
} }
......
// { dg-do compile { target c++11 } }
// { dg-final { scan-assembler-not "weak.*_Z" } }
using P = struct {}*;
template <int N>
void f(int(*)[((P)0, N)]) {}
template <int N>
struct A { };
template <int N>
void g(A<((P)0,N)>) {}
int main()
{
f<1>(0);
g<1>({});
}
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