From e547455bd62b59821c4ab9e900d7d0ff14fd69c8 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 21 Jun 2016 14:17:01 -0400 Subject: [PATCH] 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. From-SVN: r237654 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/pt.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) 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 + + * 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 * 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); -- 2.30.2