summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-21 18:17:01 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-21 18:17:01 +0000
commit88b05face78bb623f28890a2d6caf3b5e7836650 (patch)
tree910a4bc2bef89f21068d13e924412267a208fe6a
parent66ff0c677f9e47f7479f747d956ead8140882a67 (diff)
downloadgcc-88b05face78bb623f28890a2d6caf3b5e7836650.tar.gz
Fix type_dependent_expression_p of member templates.
* pt.c (template_parm_outer_level, uses_outer_template_parms): New. (type_dependent_expression_p): Use uses_outer_template_parms. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@237654 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/pt.c47
2 files changed, 51 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6508b6ed03e..c8aa71360e2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2016-06-21 Jason Merrill <jason@redhat.com>
+
+ * pt.c (template_parm_outer_level, uses_outer_template_parms): New.
+ (type_dependent_expression_p): Use uses_outer_template_parms.
+
2016-06-20 David Malcolm <dmalcolm@redhat.com>
* parser.c (cp_parser_string_literal): Convert non-standard
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 11b5d822a35..c5f65a7f677 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5064,6 +5064,24 @@ template_parm_this_level_p (tree t, void* data)
return level == this_level;
}
+/* Worker for uses_outer_template_parms, called via for_each_template_parm.
+ DATA is really an int, indicating the innermost outer level of parameters.
+ If T is a template parameter of that level or further out, return
+ nonzero. */
+
+static int
+template_parm_outer_level (tree t, void *data)
+{
+ int this_level = *(int *)data;
+ int level;
+
+ if (TREE_CODE (t) == TEMPLATE_PARM_INDEX)
+ level = TEMPLATE_PARM_LEVEL (t);
+ else
+ level = TEMPLATE_TYPE_LEVEL (t);
+ return level <= this_level;
+}
+
/* Creates a TEMPLATE_DECL for the indicated DECL using the template
parameters given by current_template_args, or reuses a
previously existing one, if appropriate. Returns the DECL, or an
@@ -9032,6 +9050,33 @@ uses_template_parms_level (tree t, int level)
/*include_nondeduced_p=*/true);
}
+/* Returns true if the signature of DECL depends on any template parameter from
+ its enclosing class. */
+
+bool
+uses_outer_template_parms (tree decl)
+{
+ int depth = template_class_depth (CP_DECL_CONTEXT (decl));
+ if (depth == 0)
+ return false;
+ if (for_each_template_parm (TREE_TYPE (decl), template_parm_outer_level,
+ &depth, NULL, /*include_nondeduced_p=*/true))
+ return true;
+ if (PRIMARY_TEMPLATE_P (decl)
+ && for_each_template_parm (INNERMOST_TEMPLATE_PARMS
+ (DECL_TEMPLATE_PARMS (decl)),
+ template_parm_outer_level,
+ &depth, NULL, /*include_nondeduced_p=*/true))
+ return true;
+ tree ci = get_constraints (decl);
+ if (ci)
+ ci = CI_NORMALIZED_CONSTRAINTS (ci);
+ if (ci && for_each_template_parm (ci, template_parm_outer_level,
+ &depth, NULL, /*nondeduced*/true))
+ return true;
+ return false;
+}
+
/* Returns TRUE iff INST is an instantiation we don't need to do in an
ill-formed translation unit, i.e. a variable or function that isn't
usable in a constant expression. */
@@ -23008,7 +23053,7 @@ type_dependent_expression_p (tree expression)
if (TREE_CODE (expression) == TEMPLATE_DECL
&& !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
- return false;
+ return uses_outer_template_parms (expression);
if (TREE_CODE (expression) == STMT_EXPR)
expression = stmt_expr_value_expr (expression);