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>
* 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.
* call.c (std_destroying_delete_t_p, destroying_delete_p): New.
(aligned_deallocation_fn_p, usual_deallocation_fn_p): Use
......
......@@ -2238,6 +2238,9 @@ maybe_emit_vtables (tree ctype)
enum { VISIBILITY_ANON = VISIBILITY_INTERNAL+1 };
static int expr_visibility (tree);
static int type_visibility (tree);
/* walk_tree helper function for type_visibility. */
static tree
......@@ -2257,9 +2260,55 @@ min_vis_r (tree *tp, int *walk_subtrees, void *data)
else if (CLASS_TYPE_P (*tp)
&& CLASSTYPE_VISIBILITY (*tp) > *vis_p)
*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;
}
/* 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
component types. */
......@@ -2271,6 +2320,18 @@ type_visibility (tree type)
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
specified (or if VISIBILITY is static). If TMPL is true, this
constraint is for a template argument, and takes precedence
......@@ -2329,21 +2390,7 @@ constrain_visibility_for_template (tree decl, tree targs)
if (TYPE_P (arg))
vis = type_visibility (arg);
else
{
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);
}
}
vis = expr_visibility (arg);
if (vis)
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