PR c++/28588
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 26 Aug 2006 16:23:33 +0000 (16:23 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 26 Aug 2006 16:23:33 +0000 (16:23 +0000)
* class.c (resolve_address_of_overloaded_function): Add
access_path parameter.  Perform access checks.
(instantiate_type): Adjust call to
resolve_address_of_overloaded_function.  Remove unnecessary code.
* tree.c (is_overloaded_fn): Document.  Return 2 when there are
acutally multiple functions.
(really_overloaded_fn): Use is_overloaded_fn.
* mangle.c (write_expression): Handle BASELINKs.
* cp-tree.h (really_overloaded_fn): Return bool.
(baselink_for_fns): Declare.
* search.c (lookup_member): Check access for single static
functions here.
* pt.c (convert_nontype_argument_function): Handle BASELINKs.
(tsubst_copy_and_build): Generate BASELINKs for template-ids.
* semantics.c (finish_call_expr): Use baselink_for_fns.
(baselink_for_fns): New function.
(finish_id_expression): Use it.
* parser.c (cp_parser_template_argument): Don't strip BASELINKs.
PR c++/28595
* pt.c (tsubst): Issue errors about attempts to create VLAs at
template-instantiation time.
PR c++/28588
* g++.dg/inherit/access6.C: New test.
* g++.dg/inherit/access7.C: Likewise.
PR c++/28595
* g++.dg/template/array15.C: New test.
* g++.dg/template/crash2.C: Tweak error markers.

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

14 files changed:
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/mangle.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/access6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/inherit/access7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/array15.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/crash2.C

index 171103b..d7c952d 100644 (file)
@@ -1,3 +1,29 @@
+2006-08-26  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/28588
+       * class.c (resolve_address_of_overloaded_function): Add
+       access_path parameter.  Perform access checks.
+       (instantiate_type): Adjust call to
+       resolve_address_of_overloaded_function.  Remove unnecessary code.
+       * tree.c (is_overloaded_fn): Document.  Return 2 when there are
+       acutally multiple functions.
+       (really_overloaded_fn): Use is_overloaded_fn.
+       * mangle.c (write_expression): Handle BASELINKs.
+       * cp-tree.h (really_overloaded_fn): Return bool.
+       (baselink_for_fns): Declare.
+       * search.c (lookup_member): Check access for single static
+       functions here.
+       * pt.c (convert_nontype_argument_function): Handle BASELINKs.
+       (tsubst_copy_and_build): Generate BASELINKs for template-ids.
+       * semantics.c (finish_call_expr): Use baselink_for_fns.
+       (baselink_for_fns): New function.
+       (finish_id_expression): Use it.
+       * parser.c (cp_parser_template_argument): Don't strip BASELINKs.
+
+       PR c++/28595
+       * pt.c (tsubst): Issue errors about attempts to create VLAs at
+       template-instantiation time.
+
 2006-08-25  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR c++/28853
index 06f8cbc..673b07f 100644 (file)
@@ -134,8 +134,6 @@ static int method_name_cmp (const void *, const void *);
 static int resort_method_name_cmp (const void *, const void *);
 static void add_implicitly_declared_members (tree, int, int);
 static tree fixed_type_or_null (tree, int *, int *);
-static tree resolve_address_of_overloaded_function (tree, tree, tsubst_flags_t,
-                                                   bool, tree);
 static tree build_simple_base_path (tree expr, tree binfo);
 static tree build_vtbl_ref_1 (tree, tree);
 static tree build_vtbl_initializer (tree, tree, tree, tree, int *);
@@ -5673,18 +5671,21 @@ pop_lang_context (void)
 
 /* Given an OVERLOAD and a TARGET_TYPE, return the function that
    matches the TARGET_TYPE.  If there is no satisfactory match, return
-   error_mark_node, and issue an error & warning messages under control
-   of FLAGS.  Permit pointers to member function if FLAGS permits.  If
-   TEMPLATE_ONLY, the name of the overloaded function was a
-   template-id, and EXPLICIT_TARGS are the explicitly provided
-   template arguments.  */
+   error_mark_node, and issue an error & warning messages under
+   control of FLAGS.  Permit pointers to member function if FLAGS
+   permits.  If TEMPLATE_ONLY, the name of the overloaded function was
+   a template-id, and EXPLICIT_TARGS are the explicitly provided
+   template arguments.  If OVERLOAD is for one or more member
+   functions, then ACCESS_PATH is the base path used to reference
+   those member functions.  */
 
 static tree
 resolve_address_of_overloaded_function (tree target_type,
                                        tree overload,
                                        tsubst_flags_t flags,
                                        bool template_only,
-                                       tree explicit_targs)
+                                       tree explicit_targs,
+                                       tree access_path)
 {
   /* Here's what the standard says:
 
@@ -5935,7 +5936,17 @@ resolve_address_of_overloaded_function (tree target_type,
      function used.  If this conversion sequence is selected, the
      function will be marked as used at this point.  */
   if (!(flags & tf_conv))
-    mark_used (fn);
+    {
+      mark_used (fn);
+      /* We could not check access when this expression was originally
+        created since we did not know at that time to which function
+        the expression referred.  */
+      if (DECL_FUNCTION_MEMBER_P (fn))
+       {
+         gcc_assert (access_path);
+         perform_or_defer_access_check (access_path, fn);
+       }
+    }
 
   if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
     return build_unary_op (ADDR_EXPR, fn, 0);
@@ -5964,6 +5975,7 @@ tree
 instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
 {
   tsubst_flags_t flags_in = flags;
+  tree access_path = NULL_TREE;
 
   flags &= ~tf_ptrmem_ok;
 
@@ -5994,7 +6006,10 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
     }
 
   if (TREE_CODE (rhs) == BASELINK)
-    rhs = BASELINK_FUNCTIONS (rhs);
+    {
+      access_path = BASELINK_ACCESS_BINFO (rhs);
+      rhs = BASELINK_FUNCTIONS (rhs);
+    }
 
   /* If we are in a template, and have a NON_DEPENDENT_EXPR, we cannot
      deduce any type information.  */
@@ -6005,6 +6020,13 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
       return error_mark_node;
     }
 
+  /* There only a few kinds of expressions that may have a type
+     dependent on overload resolution.  */
+  gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
+             || TREE_CODE (rhs) == COMPONENT_REF
+             || TREE_CODE (rhs) == COMPOUND_EXPR
+             || really_overloaded_fn (rhs));
+
   /* We don't overwrite rhs if it is an overloaded function.
      Copying it would destroy the tree link.  */
   if (TREE_CODE (rhs) != OVERLOAD)
@@ -6017,32 +6039,6 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
 
   switch (TREE_CODE (rhs))
     {
-    case TYPE_EXPR:
-    case CONVERT_EXPR:
-    case SAVE_EXPR:
-    case CONSTRUCTOR:
-      gcc_unreachable ();
-
-    case INDIRECT_REF:
-    case ARRAY_REF:
-      {
-       tree new_rhs;
-
-       new_rhs = instantiate_type (build_pointer_type (lhstype),
-                                   TREE_OPERAND (rhs, 0), flags);
-       if (new_rhs == error_mark_node)
-         return error_mark_node;
-
-       TREE_TYPE (rhs) = lhstype;
-       TREE_OPERAND (rhs, 0) = new_rhs;
-       return rhs;
-      }
-
-    case NOP_EXPR:
-      rhs = copy_node (TREE_OPERAND (rhs, 0));
-      TREE_TYPE (rhs) = unknown_type_node;
-      return instantiate_type (lhstype, rhs, flags);
-
     case COMPONENT_REF:
       {
        tree member = TREE_OPERAND (rhs, 1);
@@ -6059,7 +6055,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
     case OFFSET_REF:
       rhs = TREE_OPERAND (rhs, 1);
       if (BASELINK_P (rhs))
-       return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags_in);
+       return instantiate_type (lhstype, rhs, flags_in);
 
       /* This can happen if we are forming a pointer-to-member for a
         member template.  */
@@ -6075,7 +6071,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
        return
          resolve_address_of_overloaded_function (lhstype, fns, flags_in,
                                                  /*template_only=*/true,
-                                                 args);
+                                                 args, access_path);
       }
 
     case OVERLOAD:
@@ -6083,14 +6079,9 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
       return
        resolve_address_of_overloaded_function (lhstype, rhs, flags_in,
                                                /*template_only=*/false,
-                                               /*explicit_targs=*/NULL_TREE);
+                                               /*explicit_targs=*/NULL_TREE,
+                                               access_path);
 
-    case CALL_EXPR:
-      /* This is too hard for now.  */
-      gcc_unreachable ();
-
-    case PLUS_EXPR:
-    case MINUS_EXPR:
     case COMPOUND_EXPR:
       TREE_OPERAND (rhs, 0)
        = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
@@ -6104,86 +6095,6 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
       TREE_TYPE (rhs) = lhstype;
       return rhs;
 
-    case MULT_EXPR:
-    case TRUNC_DIV_EXPR:
-    case FLOOR_DIV_EXPR:
-    case CEIL_DIV_EXPR:
-    case ROUND_DIV_EXPR:
-    case RDIV_EXPR:
-    case TRUNC_MOD_EXPR:
-    case FLOOR_MOD_EXPR:
-    case CEIL_MOD_EXPR:
-    case ROUND_MOD_EXPR:
-    case FIX_ROUND_EXPR:
-    case FIX_FLOOR_EXPR:
-    case FIX_CEIL_EXPR:
-    case FIX_TRUNC_EXPR:
-    case FLOAT_EXPR:
-    case NEGATE_EXPR:
-    case ABS_EXPR:
-    case MAX_EXPR:
-    case MIN_EXPR:
-
-    case BIT_AND_EXPR:
-    case BIT_IOR_EXPR:
-    case BIT_XOR_EXPR:
-    case LSHIFT_EXPR:
-    case RSHIFT_EXPR:
-    case LROTATE_EXPR:
-    case RROTATE_EXPR:
-
-    case PREINCREMENT_EXPR:
-    case PREDECREMENT_EXPR:
-    case POSTINCREMENT_EXPR:
-    case POSTDECREMENT_EXPR:
-      if (flags & tf_error)
-       error ("invalid operation on uninstantiated type");
-      return error_mark_node;
-
-    case TRUTH_AND_EXPR:
-    case TRUTH_OR_EXPR:
-    case TRUTH_XOR_EXPR:
-    case LT_EXPR:
-    case LE_EXPR:
-    case GT_EXPR:
-    case GE_EXPR:
-    case EQ_EXPR:
-    case NE_EXPR:
-    case TRUTH_ANDIF_EXPR:
-    case TRUTH_ORIF_EXPR:
-    case TRUTH_NOT_EXPR:
-      if (flags & tf_error)
-       error ("not enough type information");
-      return error_mark_node;
-
-    case COND_EXPR:
-      if (type_unknown_p (TREE_OPERAND (rhs, 0)))
-       {
-         if (flags & tf_error)
-           error ("not enough type information");
-         return error_mark_node;
-       }
-      TREE_OPERAND (rhs, 1)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
-      if (TREE_OPERAND (rhs, 1) == error_mark_node)
-       return error_mark_node;
-      TREE_OPERAND (rhs, 2)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), flags);
-      if (TREE_OPERAND (rhs, 2) == error_mark_node)
-       return error_mark_node;
-
-      TREE_TYPE (rhs) = lhstype;
-      return rhs;
-
-    case MODIFY_EXPR:
-      TREE_OPERAND (rhs, 1)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
-      if (TREE_OPERAND (rhs, 1) == error_mark_node)
-       return error_mark_node;
-
-      TREE_TYPE (rhs) = lhstype;
-      return rhs;
-
     case ADDR_EXPR:
     {
       if (PTRMEM_OK_P (rhs))
index 713d371..c50836b 100644 (file)
@@ -4321,6 +4321,7 @@ extern tree cxx_omp_clause_copy_ctor              (tree, tree, tree);
 extern tree cxx_omp_clause_assign_op           (tree, tree, tree);
 extern tree cxx_omp_clause_dtor                        (tree, tree);
 extern bool cxx_omp_privatize_by_reference     (tree);
+extern tree baselink_for_fns                    (tree);
 
 /* in tree.c */
 extern void lang_check_failed                  (const char *, int,
@@ -4364,7 +4365,7 @@ extern bool decl_anon_ns_mem_p                    (tree);
 extern tree lvalue_type                                (tree);
 extern tree error_type                         (tree);
 extern int varargs_function_p                  (tree);
-extern int really_overloaded_fn                        (tree);
+extern bool really_overloaded_fn               (tree);
 extern bool cp_tree_equal                      (tree, tree);
 extern tree no_linkage_check                   (tree, bool);
 extern void debug_binfo                                (tree);
index 8c8eff9..74ff854 100644 (file)
@@ -2023,6 +2023,12 @@ write_expression (tree expr)
       code = TREE_CODE (expr);
     }
 
+  if (code == BASELINK)
+    {
+      expr = BASELINK_FUNCTIONS (expr);
+      code = TREE_CODE (expr);
+    }
+
   /* Handle pointers-to-members by making them look like expression
      nodes.  */
   if (code == PTRMEM_CST)
index 729d0ca..4e62340 100644 (file)
@@ -9237,11 +9237,6 @@ cp_parser_template_argument (cp_parser* parser)
              argument = TREE_OPERAND (argument, 0);
            }
 
-         if (TREE_CODE (argument) == BASELINK)
-           /* We don't need the information about what class was used
-              to name the overloaded functions.  */
-           argument = BASELINK_FUNCTIONS (argument);
-
          if (TREE_CODE (argument) == VAR_DECL)
            {
              /* A variable without external linkage might still be a
index 749291c..e078149 100644 (file)
@@ -3454,7 +3454,9 @@ convert_nontype_argument_function (tree type, tree expr)
   fn_no_ptr = fn;
   if (TREE_CODE (fn_no_ptr) == ADDR_EXPR)
     fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0);
-
+  if (TREE_CODE (fn_no_ptr) == BASELINK)
+    fn_no_ptr = BASELINK_FUNCTIONS (fn_no_ptr);
   /* [temp.arg.nontype]/1
 
      A template-argument for a non-type, non-template template-parameter
@@ -7192,6 +7194,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        max = tsubst_template_arg (omax, args, complain, in_decl);
        max = fold_decl_constant_value (max);
 
+       if (TREE_CODE (max) != INTEGER_CST 
+           && TREE_CODE (max) != TEMPLATE_PARM_INDEX
+           && !at_function_scope_p ())
+         {
+           if (complain & tf_error)
+             error ("array bound is not an integer constant");
+           return error_mark_node;
+         }
+
        /* [temp.deduct]
 
           Type deduction may fail for any of the following
@@ -7204,7 +7215,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
             indicated by the state of complain), so that
             another substitution can be found.  */
          return error_mark_node;
-
        else if (TREE_CODE (max) == INTEGER_CST
                 && INT_CST_LT (max, integer_zero_node))
          {
@@ -8824,7 +8834,7 @@ tsubst_copy_and_build (tree t,
          return build3 (COMPONENT_REF, TREE_TYPE (template),
                         object, template, NULL_TREE);
        else
-         return template;
+         return baselink_for_fns (template);
       }
 
     case INDIRECT_REF:
index d54e607..45a5ea3 100644 (file)
@@ -1253,8 +1253,26 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
   /* [class.access]
 
      In the case of overloaded function names, access control is
-     applied to the function selected by overloaded resolution.  */
-  if (rval && protect && !is_overloaded_fn (rval))
+     applied to the function selected by overloaded resolution.  
+
+     We cannot check here, even if RVAL is only a single non-static
+     member function, since we do not know what the "this" pointer
+     will be.  For:
+
+        class A { protected: void f(); };
+        class B : public A { 
+          void g(A *p) {
+            f(); // OK
+            p->f(); // Not OK.
+          }
+        };
+
+    only the first call to "f" is valid.  However, if the function is
+    static, we can check.  */
+  if (rval && protect 
+      && !really_overloaded_fn (rval)
+      && !(TREE_CODE (rval) == FUNCTION_DECL
+          && DECL_NONSTATIC_MEMBER_FUNCTION_P (rval)))
     perform_or_defer_access_check (basetype_path, rval);
 
   if (errstr && protect)
index 56dbe6f..94e6dfd 100644 (file)
@@ -1774,26 +1774,8 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
       args = build_non_dependent_args (orig_args);
     }
 
-  /* A reference to a member function will appear as an overloaded
-     function (rather than a BASELINK) if an unqualified name was used
-     to refer to it.  */
-  if (!BASELINK_P (fn) && is_overloaded_fn (fn))
-    {
-      tree f = fn;
-
-      if (TREE_CODE (f) == TEMPLATE_ID_EXPR)
-       f = TREE_OPERAND (f, 0);
-      f = get_first_fn (f);
-      if (DECL_FUNCTION_MEMBER_P (f))
-       {
-         tree type = currently_open_derived_class (DECL_CONTEXT (f));
-         if (!type)
-           type = DECL_CONTEXT (f);
-         fn = build_baselink (TYPE_BINFO (type),
-                              TYPE_BINFO (type),
-                              fn, /*optype=*/NULL_TREE);
-       }
-    }
+  if (is_overloaded_fn (fn))
+    fn = baselink_for_fns (fn);
 
   result = NULL_TREE;
   if (BASELINK_P (fn))
@@ -2405,6 +2387,36 @@ qualified_name_lookup_error (tree scope, tree name, tree decl)
     error ("%<::%D%> has not been declared", name);
 }
 
+/* If FNS is a member function, a set of member functions, or a
+   template-id referring to one or more member functions, return a
+   BASELINK for FNS, incorporating the current access context.
+   Otherwise, return FNS unchanged.  */
+
+tree
+baselink_for_fns (tree fns)
+{
+  tree fn;
+  tree cl;
+
+  if (BASELINK_P (fns) 
+      || processing_template_decl
+      || error_operand_p (fns))
+    return fns;
+  
+  fn = fns;
+  if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+    fn = TREE_OPERAND (fn, 0);
+  fn = get_first_fn (fn);
+  if (!DECL_FUNCTION_MEMBER_P (fn))
+    return fns;
+
+  cl = currently_open_derived_class (DECL_CONTEXT (fn));
+  if (!cl)
+    cl = DECL_CONTEXT (fn);
+  cl = TYPE_BINFO (cl);
+  return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE);
+}
+
 /* ID_EXPRESSION is a representation of parsed, but unprocessed,
    id-expression.  (See cp_parser_id_expression for details.)  SCOPE,
    if non-NULL, is the type or namespace used to explicitly qualify
@@ -2793,8 +2805,12 @@ finish_id_expression (tree id_expression,
        }
       else if (is_overloaded_fn (decl))
        {
-         tree first_fn = OVL_CURRENT (decl);
+         tree first_fn;
 
+         first_fn = decl;
+         if (TREE_CODE (first_fn) == TEMPLATE_ID_EXPR)
+           first_fn = TREE_OPERAND (first_fn, 0);
+         first_fn = get_first_fn (first_fn);
          if (TREE_CODE (first_fn) == TEMPLATE_DECL)
            first_fn = DECL_TEMPLATE_RESULT (first_fn);
 
@@ -2811,6 +2827,8 @@ finish_id_expression (tree id_expression,
              return finish_class_member_access_expr (decl, id_expression,
                                                      /*template_p=*/false);
            }
+
+         decl = baselink_for_fns (decl);
        }
       else
        {
index 1cedec5..db7e40a 100644 (file)
@@ -842,6 +842,13 @@ build_qualified_name (tree type, tree scope, tree name, bool template_p)
   return t;
 }
 
+/* Returns non-zero if X is an expression for a (possibly overloaded)
+   function.  If "f" is a function or function template, "f", "c->f",
+   "c.f", "C::f", and "f<int>" will all be considered possibly
+   overloaded functions.  Returns 2 if the function is actually
+   overloaded, i.e., if it is impossible to know the the type of the
+   function without performing overload resolution.  */
 int
 is_overloaded_fn (tree x)
 {
@@ -850,24 +857,22 @@ is_overloaded_fn (tree x)
     x = TREE_OPERAND (x, 1);
   if (BASELINK_P (x))
     x = BASELINK_FUNCTIONS (x);
-  return (TREE_CODE (x) == FUNCTION_DECL
-         || TREE_CODE (x) == TEMPLATE_ID_EXPR
-         || DECL_FUNCTION_TEMPLATE_P (x)
-         || TREE_CODE (x) == OVERLOAD);
+  if (TREE_CODE (x) == TEMPLATE_ID_EXPR
+      || DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x))
+      || (TREE_CODE (x) == OVERLOAD && OVL_CHAIN (x)))
+    return 2;
+  return  (TREE_CODE (x) == FUNCTION_DECL
+          || TREE_CODE (x) == OVERLOAD);
 }
 
-int
+/* Returns true iff X is an expression for an overloaded function
+   whose type cannot be known without performing overload
+   resolution.  */
+
+bool
 really_overloaded_fn (tree x)
 {
-  if (TREE_CODE (x) == OFFSET_REF)
-    x = TREE_OPERAND (x, 1);
-  /* A baselink is also considered an overloaded function.  */
-  if (BASELINK_P (x))
-    x = BASELINK_FUNCTIONS (x);
-
-  return ((TREE_CODE (x) == OVERLOAD && OVL_CHAIN (x))
-         || DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x))
-         || TREE_CODE (x) == TEMPLATE_ID_EXPR);
+  return is_overloaded_fn (x) == 2;
 }
 
 tree
index b9ddcf0..017de89 100644 (file)
@@ -1,3 +1,13 @@
+2006-08-26  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/28588
+       * g++.dg/inherit/access6.C: New test.
+       * g++.dg/inherit/access7.C: Likewise.
+
+       PR c++/28595
+       * g++.dg/template/array15.C: New test.
+       * g++.dg/template/crash2.C: Tweak error markers.
+
 2006-08-26  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/28683
diff --git a/gcc/testsuite/g++.dg/inherit/access6.C b/gcc/testsuite/g++.dg/inherit/access6.C
new file mode 100644 (file)
index 0000000..7645c2d
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/28588
+
+class Foo { 
+  static void f(); // { dg-error "private" }
+  static void f(int);
+  static void g(); // { dg-error "private" }
+};
+
+void h()
+{
+  Foo foo;
+  void (*f)();
+  f = foo.f; // { dg-error "context" }
+  f = foo.g; // { dg-error "context" }
+}
diff --git a/gcc/testsuite/g++.dg/inherit/access7.C b/gcc/testsuite/g++.dg/inherit/access7.C
new file mode 100644 (file)
index 0000000..4e2db14
--- /dev/null
@@ -0,0 +1,15 @@
+struct B {
+  static void f();
+};
+
+template <typename T>
+struct D : private B {
+  void g() {
+    f();
+  }
+};
+  
+void h() {
+  D<int> d;
+  d.g();
+}
diff --git a/gcc/testsuite/g++.dg/template/array15.C b/gcc/testsuite/g++.dg/template/array15.C
new file mode 100644 (file)
index 0000000..b1e047d
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/28595
+
+template<int> struct A
+{
+  static const int i;
+};
+
+template<int N> struct B
+{
+  char c[A<N>::i], d; // { dg-error "constant" }
+};
+
+B<0> b;
index a02787a..47c95ab 100644 (file)
@@ -5,7 +5,7 @@ class A
 {
 public:
   static const EnumType size = max; // { dg-error "" }
-  int table[size];
+  int table[size]; // { dg-error "constant" }
 };
 template <class EnumType>
 const EnumType A<EnumType>::size;