aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-12-08 03:31:37 +0000
committerJason Merrill <jason@redhat.com>2012-12-08 03:31:37 +0000
commit6caff32a3fd0cdf8392c2170be89a2612aaf8f8e (patch)
tree3caa0e662e11296db05750ca5ead364263a066e6
parent26b803646856f96d9ee46f20cbf219c10115dfd7 (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/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.c31
-rw-r--r--gcc/cp/search.c13
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/testsuite/g++.dg/template/defarg16.C28
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>();
+}