PR c++/55127
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 8 Dec 2012 03:31:37 +0000 (03:31 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 8 Dec 2012 03:31:37 +0000 (03:31 +0000)
* 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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194318 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/semantics.c
gcc/testsuite/g++.dg/template/defarg16.C [new file with mode: 0644]

index 78e7d40..a5d0b76 100644 (file)
@@ -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.
 
index 2741abc..465fa0f 100644 (file)
@@ -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);
index 33044e0..1bc9e1b 100644 (file)
@@ -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;
index 92234a5..1cd4fc5 100644 (file)
@@ -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,
index 92b4a2b..179c508 100644 (file)
@@ -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 (file)
index 0000000..ba78bfb
--- /dev/null
@@ -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>();
+}