diff options
author | Jason Merrill <jason@redhat.com> | 2012-12-08 03:31:37 +0000 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2012-12-08 03:31:37 +0000 |
commit | 6caff32a3fd0cdf8392c2170be89a2612aaf8f8e (patch) | |
tree | 3caa0e662e11296db05750ca5ead364263a066e6 | |
parent | 26b803646856f96d9ee46f20cbf219c10115dfd7 (diff) |
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.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@194318 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/pt.c | 31 | ||||
-rw-r--r-- | gcc/cp/search.c | 13 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/defarg16.C | 28 |
6 files changed, 75 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 78e7d40d4a5..a5d0b76c615 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 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 * tree.c (build_target_expr): Don't set TREE_CONSTANT. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 2741abc1d77..465fa0f78ef 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5489,6 +5489,7 @@ extern tree lookup_base (tree, tree, base_access, base_kind *, tsubst_flags_t); extern tree dcast_base_hint (tree, tree); 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 (tree, tree, int, bool); extern int lookup_fnfields_1 (tree, tree); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 33044e0f61c..1bc9e1bef14 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -19293,6 +19293,22 @@ dependent_scope_p (tree 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 [temp.dep.constexpr]. EXPRESSION is already known to be a constant expression. */ @@ -19400,10 +19416,9 @@ value_dependent_expression_p (tree expression) return instantiation_dependent_expression_p (expression); case SCOPE_REF: - /* instantiation_dependent_r treats this as dependent so that we - check access at instantiation time, and all instantiation-dependent - expressions should also be considered value-dependent. */ - return true; + /* All instantiation-dependent expressions should also be considered + value-dependent. */ + return instantiation_dependent_scope_ref_p (expression); case COMPONENT_REF: return (value_dependent_expression_p (TREE_OPERAND (expression, 0)) @@ -19744,10 +19759,10 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees, break; case SCOPE_REF: - /* Similarly, finish_qualified_id_expr builds up a SCOPE_REF in a - template so that we can check access at instantiation time even - though we know which member it resolves to. */ - return *tp; + if (instantiation_dependent_scope_ref_p (*tp)) + return *tp; + else + break; default: break; diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 92234a52be5..1cd4fc584db 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -832,6 +832,19 @@ dfs_accessible_post (tree binfo, void * /*data*/) 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 class used to name DECL. Return nonzero if, in the current context, DECL is accessible. If TYPE is actually a BINFO node, diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 92b4a2b2f6c..179c5089cc9 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5268,7 +5268,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, expr = TREE_OPERAND (expr, 0); 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 BASELINK, we will need to see through it in the next step. */ diff --git a/gcc/testsuite/g++.dg/template/defarg16.C b/gcc/testsuite/g++.dg/template/defarg16.C new file mode 100644 index 00000000000..ba78bfbd5a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg16.C @@ -0,0 +1,28 @@ +// 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>(); +} |