PR c++/29475
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 20 Nov 2006 21:15:44 +0000 (21:15 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 20 Nov 2006 21:15:44 +0000 (21:15 +0000)
* cp-tree.h (enforce_access, perform_or_defer_access_check): Added an
extra argument that represents the declaration to use to print
potential error messages.
* init.c (build_offset_ref): Adjusted the call to
perform_or_defer_access_check.
* class.c (alter_access, resolve_address_of_overloaded_function):
Likewise.
* decl.c (make_typename_type, make_unbound_class_template): Likewise.
* search.c (lookup_member): Likewise.
* friend.c (add_friend): Likewise.
* parser.c (cp_parser_template_id,
cp_parser_pre_parsed_nested_name_specifier): Likewise.
* semantics.c (finish_non_static_data_member,
check_accessibility_of_qualified_id, finish_id_expression): Likewise.
(pop_to_parent_deferring_access_checks, perform_access_checks,
perform_or_defer_access_check): Adjusted the call to enforce_access.
* call.c (enforce_access): Use the new extra argument to build the
error message.
(build_op_delete_call): Adjusted the call to
perform_or_defer_access_check.
(build_over_call): Likewise.

PR c++/29475
* g++.dg/template/access19.C: New test.
* g++.old-deja/g++.other/access11.C: Adjusted the line where the
error is reported.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119027 138bc75d-0d04-0410-961f-82ee72b054a4

13 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/friend.c
gcc/cp/init.c
gcc/cp/parser.c
gcc/cp/search.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/access19.C [new file with mode: 0755]
gcc/testsuite/g++.old-deja/g++.other/access11.C

index 9784458..5d0dd5c 100644 (file)
@@ -1,3 +1,28 @@
+2006-11-20  Simon Martin  <simartin@users.sourceforge.net>
+
+       PR c++/29475
+       * cp-tree.h (enforce_access, perform_or_defer_access_check): Added an
+       extra argument that represents the declaration to use to print
+       potential error messages.
+       * init.c (build_offset_ref): Adjusted the call to
+       perform_or_defer_access_check.
+       * class.c (alter_access, resolve_address_of_overloaded_function):
+       Likewise.
+       * decl.c (make_typename_type, make_unbound_class_template): Likewise. 
+       * search.c (lookup_member): Likewise.
+       * friend.c (add_friend): Likewise.
+       * parser.c (cp_parser_template_id,
+       cp_parser_pre_parsed_nested_name_specifier): Likewise.
+       * semantics.c (finish_non_static_data_member,
+       check_accessibility_of_qualified_id, finish_id_expression): Likewise.
+       (pop_to_parent_deferring_access_checks, perform_access_checks,
+       perform_or_defer_access_check): Adjusted the call to enforce_access.
+       * call.c (enforce_access): Use the new extra argument to build the
+       error message.
+       (build_op_delete_call): Adjusted the call to
+       perform_or_defer_access_check.
+       (build_over_call): Likewise.
+       
 2006-11-16  Dirk Mueller  <dmueller@suse.de>
 
        * name-lookup.c (begin_scope): Use GGC_CNEW instead of
index 27ef203..cfb566b 100644 (file)
@@ -4097,7 +4097,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
       /* If the FN is a member function, make sure that it is
         accessible.  */
       if (DECL_CLASS_SCOPE_P (fn))
-       perform_or_defer_access_check (TYPE_BINFO (type), fn);
+       perform_or_defer_access_check (TYPE_BINFO (type), fn, fn);
 
       if (pass == 0)
        args = tree_cons (NULL_TREE, addr, args);
@@ -4128,21 +4128,22 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
 
 /* If the current scope isn't allowed to access DECL along
    BASETYPE_PATH, give an error.  The most derived class in
-   BASETYPE_PATH is the one used to qualify DECL.  */
+   BASETYPE_PATH is the one used to qualify DECL. DIAG_DECL is
+   the declaration to use in the error diagnostic.  */
 
 bool
-enforce_access (tree basetype_path, tree decl)
+enforce_access (tree basetype_path, tree decl, tree diag_decl)
 {
   gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
 
   if (!accessible_p (basetype_path, decl, true))
     {
       if (TREE_PRIVATE (decl))
-       error ("%q+#D is private", decl);
+       error ("%q+#D is private", diag_decl);
       else if (TREE_PROTECTED (decl))
-       error ("%q+#D is protected", decl);
+       error ("%q+#D is protected", diag_decl);
       else
-       error ("%q+#D is inaccessible", decl);
+       error ("%q+#D is inaccessible", diag_decl);
       error ("within this context");
       return false;
     }
@@ -4771,9 +4772,9 @@ build_over_call (struct z_candidate *cand, int flags)
       if (DECL_TEMPLATE_INFO (fn)
          && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (fn)))
        perform_or_defer_access_check (cand->access_path,
-                                      DECL_TI_TEMPLATE (fn));
+                                      DECL_TI_TEMPLATE (fn), fn);
       else
-       perform_or_defer_access_check (cand->access_path, fn);
+       perform_or_defer_access_check (cand->access_path, fn, fn);
     }
 
   if (args && TREE_CODE (args) != TREE_LIST)
index 75d56be..3e569f5 100644 (file)
@@ -1129,7 +1129,7 @@ alter_access (tree t, tree fdecl, tree access)
     }
   else
     {
-      perform_or_defer_access_check (TYPE_BINFO (t), fdecl);
+      perform_or_defer_access_check (TYPE_BINFO (t), fdecl, fdecl);
       DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
       return 1;
     }
@@ -5958,7 +5958,7 @@ resolve_address_of_overloaded_function (tree target_type,
       if (DECL_FUNCTION_MEMBER_P (fn))
        {
          gcc_assert (access_path);
-         perform_or_defer_access_check (access_path, fn);
+         perform_or_defer_access_check (access_path, fn, fn);
        }
     }
 
index 0fdbf82..d7e523b 100644 (file)
@@ -3772,7 +3772,7 @@ extern tree build_op_delete_call          (enum tree_code, tree, tree, bool, tree, tree)
 extern bool can_convert                                (tree, tree);
 extern bool can_convert_arg                    (tree, tree, tree, int);
 extern bool can_convert_arg_bad                        (tree, tree, tree);
-extern bool enforce_access                     (tree, tree);
+extern bool enforce_access                     (tree, tree, tree);
 extern tree convert_default_arg                        (tree, tree, tree, int);
 extern tree convert_arg_to_ellipsis            (tree);
 extern tree build_x_va_arg                     (tree, tree);
@@ -4209,7 +4209,7 @@ extern tree get_deferred_access_checks            (void);
 extern void pop_to_parent_deferring_access_checks (void);
 extern void perform_access_checks              (tree);
 extern void perform_deferred_access_checks     (void);
-extern void perform_or_defer_access_check      (tree, tree);
+extern void perform_or_defer_access_check      (tree, tree, tree);
 extern int stmts_are_full_exprs_p              (void);
 extern void init_cp_semantics                  (void);
 extern tree do_poplevel                                (tree);
index cc74908..e8af0e4 100644 (file)
@@ -2858,7 +2858,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
     }
   
   if (complain & tf_error)
-    perform_or_defer_access_check (TYPE_BINFO (context), t);
+    perform_or_defer_access_check (TYPE_BINFO (context), t, t);
 
   if (want_template)
     return lookup_template_class (t, TREE_OPERAND (fullname, 1),
@@ -2921,7 +2921,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
        }
 
       if (complain & tf_error)
-       perform_or_defer_access_check (TYPE_BINFO (context), tmpl);
+       perform_or_defer_access_check (TYPE_BINFO (context), tmpl, tmpl);
 
       return tmpl;
     }
index d92df5f..bc946e8 100644 (file)
@@ -171,7 +171,7 @@ add_friend (tree type, tree decl, bool complain)
 
   ctx = DECL_CONTEXT (decl);
   if (ctx && CLASS_TYPE_P (ctx) && !uses_template_parms (ctx))
-    perform_or_defer_access_check (TYPE_BINFO (ctx), decl);
+    perform_or_defer_access_check (TYPE_BINFO (ctx), decl, decl);
 
   maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
 
index 0c85c0f..0ea6888 100644 (file)
@@ -1383,9 +1383,9 @@ build_offset_ref (tree type, tree member, bool address_p)
               (or any class derived from that class).  */
          if (address_p && DECL_P (t)
              && DECL_NONSTATIC_MEMBER_P (t))
-           perform_or_defer_access_check (TYPE_BINFO (type), t);
+           perform_or_defer_access_check (TYPE_BINFO (type), t, t);
          else
-           perform_or_defer_access_check (basebinfo, t);
+           perform_or_defer_access_check (basebinfo, t, t);
 
          if (DECL_STATIC_FUNCTION_P (t))
            return t;
@@ -1398,7 +1398,7 @@ build_offset_ref (tree type, tree member, bool address_p)
     /* We need additional test besides the one in
        check_accessibility_of_qualified_id in case it is
        a pointer to non-static member.  */
-    perform_or_defer_access_check (TYPE_BINFO (type), member);
+    perform_or_defer_access_check (TYPE_BINFO (type), member, member);
 
   if (!address_p)
     {
index 8d25db6..8e79eab 100644 (file)
@@ -8759,6 +8759,7 @@ cp_parser_template_id (cp_parser *parser,
       /* Perform any access checks that were deferred.  */
       for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
        perform_or_defer_access_check (TREE_PURPOSE (check),
+                                      TREE_VALUE (check),
                                       TREE_VALUE (check));
       /* Return the stored value.  */
       return TREE_VALUE (value);
@@ -16643,7 +16644,9 @@ cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
   value = cp_lexer_consume_token (parser->lexer)->value;
   /* Perform any access checks that were deferred.  */
   for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
-    perform_or_defer_access_check (TREE_PURPOSE (check), TREE_VALUE (check));
+    perform_or_defer_access_check (TREE_PURPOSE (check),
+                                  TREE_VALUE (check),
+                                  TREE_VALUE (check));
   /* Set the scope from the stored value.  */
   parser->scope = TREE_VALUE (value);
   parser->qualifying_scope = TREE_TYPE (value);
index 45a5ea3..9d47aaf 100644 (file)
@@ -1273,7 +1273,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
       && !really_overloaded_fn (rval)
       && !(TREE_CODE (rval) == FUNCTION_DECL
           && DECL_NONSTATIC_MEMBER_FUNCTION_P (rval)))
-    perform_or_defer_access_check (basetype_path, rval);
+    perform_or_defer_access_check (basetype_path, rval, rval);
 
   if (errstr && protect)
     {
index 91d200a..e3dc3ab 100644 (file)
@@ -234,7 +234,7 @@ pop_to_parent_deferring_access_checks (void)
          /* Check access.  */
          for (; checks; checks = TREE_CHAIN (checks))
            enforce_access (TREE_PURPOSE (checks),
-                           TREE_VALUE (checks));
+                           TREE_VALUE (checks), TREE_VALUE (checks));
        }
       else
        {
@@ -271,7 +271,7 @@ perform_access_checks (tree checks)
   while (checks)
     {
       enforce_access (TREE_PURPOSE (checks),
-                     TREE_VALUE (checks));
+                     TREE_VALUE (checks), TREE_VALUE (checks));
       checks = TREE_CHAIN (checks);
     }
 }
@@ -299,10 +299,10 @@ perform_deferred_access_checks (void)
 }
 
 /* Defer checking the accessibility of DECL, when looked up in
-   BINFO.  */
+   BINFO. DIAG_DECL is the declaration to use to print diagnostics.  */
 
 void
-perform_or_defer_access_check (tree binfo, tree decl)
+perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl)
 {
   tree check;
   deferred_access *ptr;
@@ -319,7 +319,7 @@ perform_or_defer_access_check (tree binfo, tree decl)
   /* If we are not supposed to defer access checks, just check now.  */
   if (ptr->deferring_access_checks_kind == dk_no_deferred)
     {
-      enforce_access (binfo, decl);
+      enforce_access (binfo, decl, diag_decl);
       return;
     }
 
@@ -1432,7 +1432,8 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
                                     DECL_NAME (decl),
                                     /*template_p=*/false);
 
-      perform_or_defer_access_check (TYPE_BINFO (access_type), decl);
+      perform_or_defer_access_check (TYPE_BINFO (access_type), decl,
+                                    decl);
 
       /* If the data member was named `C::M', convert `*this' to `C'
         first.  */
@@ -1511,7 +1512,8 @@ check_accessibility_of_qualified_id (tree decl,
         or similar in a default argument value.  */
       && CLASS_TYPE_P (qualifying_type)
       && !dependent_type_p (qualifying_type))
-    perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl);
+    perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl,
+                                  decl);
 }
 
 /* EXPR is the result of a qualified-id.  The QUALIFYING_CLASS was the
@@ -2839,7 +2841,7 @@ finish_id_expression (tree id_expression,
              tree path;
 
              path = currently_open_derived_class (DECL_CONTEXT (decl));
-             perform_or_defer_access_check (TYPE_BINFO (path), decl);
+             perform_or_defer_access_check (TYPE_BINFO (path), decl, decl);
            }
 
          decl = convert_from_reference (decl);
index 57ce15b..079e73e 100644 (file)
@@ -1,3 +1,10 @@
+2006-11-20  Simon Martin  <simartin@users.sourceforge.net>
+
+       PR c++/29475
+       * g++.dg/template/access19.C: New test.
+       * g++.old-deja/g++.other/access11.C: Adjusted the line where the
+       error is reported.
+       
 2006-11-20  Andrew Pinski  <andrew_pinski@playstation.sony.com>
 
        PR tree-opt/25500
diff --git a/gcc/testsuite/g++.dg/template/access19.C b/gcc/testsuite/g++.dg/template/access19.C
new file mode 100755 (executable)
index 0000000..e717a72
--- /dev/null
@@ -0,0 +1,24 @@
+/* PR c++/29475 The error diagnostic contained "U = U" instead of "U = char" */\r
+/* { dg-do "compile" } */\r
+\r
+template< class T >\r
+class explicit_t\r
+{\r
+public:\r
+        explicit_t( const T& c ): value( c ) { }\r
+        operator T&() { return value; }\r
+private:\r
+        template< class U >\r
+        explicit_t( U t ); /* { dg-error "with U = char, T = int|is private" } */\r
+        T value;\r
+};\r
+\r
+int foo( int x, explicit_t< int > y )\r
+{\r
+        return x + y;\r
+}\r
+\r
+int main()\r
+{\r
+        return foo( 5, 'c' ); /* { dg-error "this context" } */\r
+}\r
index fb97824..72fc333 100644 (file)
@@ -5,12 +5,12 @@
 class A
 {
 private:
-  template <class T> void g(T t)  {} // { dg-error "" } private
+  template <class T> void g(T t)  {}
   int i;
 };
 
 template <>
-void A::g<int>(int t) { i = 1; }
+void A::g<int>(int t) { i = 1; } // { dg-error "" } private
 
 int main()
 {