aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-11-12 23:46:20 -0500
committerJason Merrill <jason@gcc.gnu.org>2018-11-12 23:46:20 -0500
commit7c23c87c93f3eafa5c22d1f4f52711d97f3a4329 (patch)
tree5a2ab00adb89fb212cae894ad79731ed185c08de
parenta6bb6b07f76c4431cb5a2a520ac33f7c970b80c1 (diff)
downloadgcc-7c23c87c93f3eafa5c22d1f4f52711d97f3a4329.zip
gcc-7c23c87c93f3eafa5c22d1f4f52711d97f3a4329.tar.gz
gcc-7c23c87c93f3eafa5c22d1f4f52711d97f3a4329.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/decl2.c77
-rw-r--r--gcc/testsuite/g++.dg/abi/no-linkage-expr1.C19
3 files changed, 85 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5497a08..79c162c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
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
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 13c156b..74b9f4e 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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);
}
diff --git a/gcc/testsuite/g++.dg/abi/no-linkage-expr1.C b/gcc/testsuite/g++.dg/abi/no-linkage-expr1.C
new file mode 100644
index 0000000..c3b1286
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/no-linkage-expr1.C
@@ -0,0 +1,19 @@
+// { 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>({});
+}