Commit cf3c30d3 by Jason Merrill Committed by Jason Merrill

re PR c++/55127 (Incorrect "dependent scope" error with partial specialization…

re PR c++/55127 (Incorrect "dependent scope" error with partial specialization of non-type parameter)

	PR c++/55127
	* search.c (accessible_in_template_p): New.
	* cp-tree.h: Declare it.
	* pt.c (instantiation_dependent_scope_ref_p): New.
	(value_dependent_expression_p): Use it.
	(instantiation_dependent_r): Likewise.
	* semantics.c (finish_decltype_type): Handle SCOPE_REF.

From-SVN: r194318
parent 4eaee921
2012-12-07 Jason Merrill <jason@redhat.com> 2012-12-07 Jason Merrill <jason@redhat.com>
PR c++/55127
* search.c (accessible_in_template_p): New.
* cp-tree.h: Declare it.
* pt.c (instantiation_dependent_scope_ref_p): New.
(value_dependent_expression_p): Use it.
(instantiation_dependent_r): Likewise.
* semantics.c (finish_decltype_type): Handle SCOPE_REF.
PR c++/55419 PR c++/55419
* tree.c (build_target_expr): Don't set TREE_CONSTANT. * tree.c (build_target_expr): Don't set TREE_CONSTANT.
......
...@@ -5489,6 +5489,7 @@ extern tree lookup_base (tree, tree, base_access, ...@@ -5489,6 +5489,7 @@ extern tree lookup_base (tree, tree, base_access,
base_kind *, tsubst_flags_t); base_kind *, tsubst_flags_t);
extern tree dcast_base_hint (tree, tree); extern tree dcast_base_hint (tree, tree);
extern int accessible_p (tree, tree, bool); extern int accessible_p (tree, tree, bool);
extern int accessible_in_template_p (tree, tree);
extern tree lookup_field_1 (tree, tree, bool); extern tree lookup_field_1 (tree, tree, bool);
extern tree lookup_field (tree, tree, int, bool); extern tree lookup_field (tree, tree, int, bool);
extern int lookup_fnfields_1 (tree, tree); extern int lookup_fnfields_1 (tree, tree);
......
...@@ -19293,6 +19293,22 @@ dependent_scope_p (tree scope) ...@@ -19293,6 +19293,22 @@ dependent_scope_p (tree scope)
&& !currently_open_class (scope)); && !currently_open_class (scope));
} }
/* T is a SCOPE_REF; return whether we need to consider it
instantiation-dependent so that we can check access at instantiation
time even though we know which member it resolves to. */
static bool
instantiation_dependent_scope_ref_p (tree t)
{
if (DECL_P (TREE_OPERAND (t, 1))
&& CLASS_TYPE_P (TREE_OPERAND (t, 0))
&& accessible_in_template_p (TREE_OPERAND (t, 0),
TREE_OPERAND (t, 1)))
return false;
else
return true;
}
/* Returns TRUE if the EXPRESSION is value-dependent, in the sense of /* Returns TRUE if the EXPRESSION is value-dependent, in the sense of
[temp.dep.constexpr]. EXPRESSION is already known to be a constant [temp.dep.constexpr]. EXPRESSION is already known to be a constant
expression. */ expression. */
...@@ -19400,10 +19416,9 @@ value_dependent_expression_p (tree expression) ...@@ -19400,10 +19416,9 @@ value_dependent_expression_p (tree expression)
return instantiation_dependent_expression_p (expression); return instantiation_dependent_expression_p (expression);
case SCOPE_REF: case SCOPE_REF:
/* instantiation_dependent_r treats this as dependent so that we /* All instantiation-dependent expressions should also be considered
check access at instantiation time, and all instantiation-dependent value-dependent. */
expressions should also be considered value-dependent. */ return instantiation_dependent_scope_ref_p (expression);
return true;
case COMPONENT_REF: case COMPONENT_REF:
return (value_dependent_expression_p (TREE_OPERAND (expression, 0)) return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
...@@ -19744,10 +19759,10 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees, ...@@ -19744,10 +19759,10 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
break; break;
case SCOPE_REF: case SCOPE_REF:
/* Similarly, finish_qualified_id_expr builds up a SCOPE_REF in a if (instantiation_dependent_scope_ref_p (*tp))
template so that we can check access at instantiation time even return *tp;
though we know which member it resolves to. */ else
return *tp; break;
default: default:
break; break;
......
...@@ -832,6 +832,19 @@ dfs_accessible_post (tree binfo, void * /*data*/) ...@@ -832,6 +832,19 @@ dfs_accessible_post (tree binfo, void * /*data*/)
return NULL_TREE; return NULL_TREE;
} }
/* Like accessible_p below, but within a template returns true iff DECL is
accessible in TYPE to all possible instantiations of the template. */
int
accessible_in_template_p (tree type, tree decl)
{
int save_ptd = processing_template_decl;
processing_template_decl = 0;
int val = accessible_p (type, decl, false);
processing_template_decl = save_ptd;
return val;
}
/* DECL is a declaration from a base class of TYPE, which was the /* DECL is a declaration from a base class of TYPE, which was the
class used to name DECL. Return nonzero if, in the current class used to name DECL. Return nonzero if, in the current
context, DECL is accessible. If TYPE is actually a BINFO node, context, DECL is accessible. If TYPE is actually a BINFO node,
......
...@@ -5268,7 +5268,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, ...@@ -5268,7 +5268,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
expr = TREE_OPERAND (expr, 0); expr = TREE_OPERAND (expr, 0);
if (TREE_CODE (expr) == OFFSET_REF if (TREE_CODE (expr) == OFFSET_REF
|| TREE_CODE (expr) == MEMBER_REF) || TREE_CODE (expr) == MEMBER_REF
|| TREE_CODE (expr) == SCOPE_REF)
/* We're only interested in the field itself. If it is a /* We're only interested in the field itself. If it is a
BASELINK, we will need to see through it in the next BASELINK, we will need to see through it in the next
step. */ step. */
......
// PR c++/55127
struct some_class
{
static const bool is_valid_type = true;
};
template< typename Type
, bool Valid = Type::is_valid_type
>
struct wrapper;
template< typename Type >
struct wrapper< Type, true >
{
typedef Type type;
};
template< typename T >
void fun()
{
wrapper<some_class>::type x;
}
int main()
{
fun<int>();
}
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