]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
decl.c (bad_specifiers): It's OK to have an EH spec on a function pointer.
authorJason Merrill <jason@yorick.cygnus.com>
Sat, 7 Aug 1999 01:31:58 +0000 (01:31 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 7 Aug 1999 01:31:58 +0000 (21:31 -0400)
* decl.c (bad_specifiers): It's OK to have an EH spec on a function
pointer.

* pt.c (maybe_get_template_decl_from_type_decl): Make sure that
we're looking at a class.

* decl.c (lookup_name_real): Set the complain flag if we're
looking for a namespace member.

* decl.c (pushdecl): Only give an error for shadowing a parm
from *this* function.

* decl2.c (build_expr_from_tree, case METHOD_CALL_EXPR): Only
build_expr_from_tree on the args of a TEMPLATE_ID_EXPR.

* class.c (mark_overriders): Fix order of args to overrides.
(warn_hidden): Likewise.  Fix for having virtual and non-virtual
functions with the same name.

* cp-tree.h (DECL_VIRTUAL_CONTEXT): New macro.
* typeck.c (expand_ptrmemfunc_cst): Calculate delta correctly for
virtual functions and MI.  Simplify.

* typeck.c (c_expand_return): Downgrade pedwarn about returning NULL
from op new to warning.

* decl2.c (reparse_absdcl_as_casts): Don't warn about old-style
casts in system headers or extern "C" blocks.

* pt.c (do_decl_instantiation): Downgrade duplicate instantiation
errors to pedwarn.

* error.c (dump_type_real): Handle TREE_LIST again.

* typeck.c (comp_target_parms): Don't complain about
converting from () to (...) if !flag_strict_prototype.

* class.c (instantiate_type): Downgrade errors for object-dependent
memfn refs to pedwarn.

From-SVN: r28563

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/pt.c
gcc/cp/typeck.c

index 153c4260bb5c6fb86c07192c1ee358e07bb31ef2..bfebb6e241b9c0e1f0d5c201fea2630fe3b7b0a6 100644 (file)
@@ -1,3 +1,45 @@
+1999-08-06  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (bad_specifiers): It's OK to have an EH spec on a function
+       pointer.
+
+       * pt.c (maybe_get_template_decl_from_type_decl): Make sure that
+       we're looking at a class.
+
+       * decl.c (lookup_name_real): Set the complain flag if we're
+       looking for a namespace member.
+
+       * decl.c (pushdecl): Only give an error for shadowing a parm 
+       from *this* function.
+
+       * decl2.c (build_expr_from_tree, case METHOD_CALL_EXPR): Only
+       build_expr_from_tree on the args of a TEMPLATE_ID_EXPR.
+
+       * class.c (mark_overriders): Fix order of args to overrides.
+       (warn_hidden): Likewise.  Fix for having virtual and non-virtual
+       functions with the same name.
+
+       * cp-tree.h (DECL_VIRTUAL_CONTEXT): New macro.
+       * typeck.c (expand_ptrmemfunc_cst): Calculate delta correctly for
+       virtual functions and MI.  Simplify.
+
+       * typeck.c (c_expand_return): Downgrade pedwarn about returning NULL
+       from op new to warning.
+
+       * decl2.c (reparse_absdcl_as_casts): Don't warn about old-style
+       casts in system headers or extern "C" blocks.
+
+       * pt.c (do_decl_instantiation): Downgrade duplicate instantiation
+       errors to pedwarn.
+
+       * error.c (dump_type_real): Handle TREE_LIST again.
+
+       * typeck.c (comp_target_parms): Don't complain about 
+       converting from () to (...) if !flag_strict_prototype.
+
+       * class.c (instantiate_type): Downgrade errors for object-dependent
+       memfn refs to pedwarn.
+
 1999-08-06  Alexandre Oliva  <oliva@dcc.unicamp.br>
 
        * pt.c (tsubst): Use build_index_type to build in-template array
index 31dcb67126f58d508e51632e714556613f53cda0..400c67de41ad7e536bb48bded107438d26b61758 100644 (file)
@@ -2785,18 +2785,18 @@ get_basefndecls (fndecl, t)
 
 /* Mark the functions that have been hidden with their overriders.
    Since we start out with all functions already marked with a hider,
-   no need to mark functions that are just hidden.  */
+   no need to mark functions that are just hidden.
+
+   Subroutine of warn_hidden.  */
 
 static void
 mark_overriders (fndecl, base_fndecls)
      tree fndecl, base_fndecls;
 {
-  while (base_fndecls)
+  for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls))
     {
-      if (overrides (TREE_VALUE (base_fndecls), fndecl))
+      if (overrides (fndecl, TREE_VALUE (base_fndecls)))
        TREE_PURPOSE (base_fndecls) = fndecl;
-
-      base_fndecls = TREE_CHAIN (base_fndecls);
     }
 }
 
@@ -2884,8 +2884,15 @@ warn_hidden (t)
       tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
       int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
 
-      fndecl = OVL_CURRENT (fns);
-      if (DECL_VINDEX (fndecl) == NULL_TREE)
+      /* First see if we have any virtual functions in this batch.  */
+      for (; fns; fns = OVL_NEXT (fns))
+       {
+         fndecl = OVL_CURRENT (fns);
+         if (DECL_VINDEX (fndecl))
+           break;
+       }
+
+      if (fns == NULL_TREE)
        continue;
 
       /* First we get a list of all possible functions that might be
@@ -2900,38 +2907,28 @@ warn_hidden (t)
        }
 
       fns = OVL_NEXT (fns);
-      if (fns)
-       fndecl = OVL_CURRENT (fns);
-      else
-       fndecl = NULL_TREE;
 
       /* ...then mark up all the base functions with overriders, preferring
         overriders to hiders.  */
       if (base_fndecls)
-       while (fndecl)
+       for (; fns; fns = OVL_NEXT (fns))
          {
-           mark_overriders (fndecl, base_fndecls);
-           
-           fns = OVL_NEXT (fns);
-           if (fns)
-             fndecl = OVL_CURRENT (fns);
-           else
-             fndecl = NULL_TREE;
+           fndecl = OVL_CURRENT (fns);
+           if (DECL_VINDEX (fndecl))
+             mark_overriders (fndecl, base_fndecls);
          }
 
       /* Now give a warning for all base functions without overriders,
         as they are hidden.  */
-      while (base_fndecls)
+      for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls))
        {
-         if (! overrides (TREE_VALUE (base_fndecls),
-                          TREE_PURPOSE (base_fndecls)))
+         if (! overrides (TREE_PURPOSE (base_fndecls),
+                          TREE_VALUE (base_fndecls)))
            {
              /* Here we know it is a hider, and no overrider exists.  */
              cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls));
              cp_warning_at ("  by `%D'", TREE_PURPOSE (base_fndecls));
            }
-
-         base_fndecls = TREE_CHAIN (base_fndecls);
        }
     }
 }
@@ -5019,15 +5016,15 @@ instantiate_type (lhstype, rhs, flags)
                  field = OVL_FUNCTION (field);
                if (TREE_CODE (field) == FUNCTION_DECL)
                  {
-                   cp_error ("object-dependent reference `%E' can only be used in a call",
+                   cp_pedwarn ("object-dependent reference `%E' can only be used in a call",
                              DECL_NAME (field));
-                   cp_error ("  to form a pointer to member function, say `&%T::%E'",
+                   cp_pedwarn ("  to form a pointer to member function, say `&%T::%E'",
                              t, DECL_NAME (field));
                  }
                else
-                 cp_error ("object-dependent reference can only be used in a call");
+                 cp_pedwarn ("object-dependent reference can only be used in a call");
              }
-           return error_mark_node;
+           return r;
          }
        
        return r;
index ad1c370e05184329b0dee452bf1d51e7f496d154..7d643078deebc5655b709adf0ccc58318fd48bb4 100644 (file)
@@ -1327,6 +1327,10 @@ struct lang_decl
   (DECL_CONTEXT (NODE) ? DECL_CONTEXT (NODE) : global_namespace)
 #define FROB_CONTEXT(NODE)   ((NODE) == global_namespace ? NULL_TREE : (NODE))
 
+/* For a virtual function, the base where we find its vtable entry.
+   For a non-virtual function, the base where it is defined.  */
+#define DECL_VIRTUAL_CONTEXT(NODE) DECL_CONTEXT (NODE)
+
 /* 1 iff NODE has namespace scope, including the global namespace.  */
 #define DECL_NAMESPACE_SCOPE_P(NODE) \
   (DECL_CONTEXT (NODE) == NULL_TREE \
index a3e18798056ae3938bf39379c8efc8a8a6712be1..ea472082e19ff2f3065be0a1e745d09c5c76cd1c 100644 (file)
@@ -4154,8 +4154,10 @@ pushdecl (x)
 
          /* Warn if shadowing an argument at the top level of the body.  */
          else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
-             && TREE_CODE (oldlocal) == PARM_DECL
-             && TREE_CODE (x) != PARM_DECL)
+                  && TREE_CODE (oldlocal) == PARM_DECL
+                  /* Don't complain if it's from an enclosing function.  */
+                  && DECL_CONTEXT (oldlocal) == current_function_decl
+                  && TREE_CODE (x) != PARM_DECL)
            {
              /* Go to where the parms should be and see if we
                 find them there.  */
@@ -5815,6 +5817,7 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
            {
              struct tree_binding b;
              val = binding_init (&b);
+             flags |= LOOKUP_COMPLAIN;
              if (!qualified_lookup_using_namespace (name, type, val, flags))
                return NULL_TREE;
              val = select_decl (val, flags);
@@ -8706,9 +8709,9 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
     cp_error ("`const' and `volatile' function specifiers on `%D' invalid in %s declaration",
              object, type);
   if (friendp)
-    cp_error_at ("invalid friend declaration", object);
-  if (raises)
-    cp_error_at ("invalid exception specifications", object);
+    cp_error_at ("`%D' declared as a friend", object);
+  if (raises && ! TYPE_PTRFN_P (TREE_TYPE (object)))
+    cp_error_at ("`%D' declared with an exception specification", object);
 }
 
 /* CTYPE is class type, or null if non-class.
index 5003f60982f01fba21427646c28b248c654e6435..debcf3717e9128f8f1232dfeb77111e60ee40a12 100644 (file)
@@ -3814,7 +3814,8 @@ reparse_absdcl_as_casts (decl, expr)
       expr = build_c_cast (type, expr);
     }
 
-  if (warn_old_style_cast)
+  if (warn_old_style_cast && ! in_system_header
+      && current_lang_name != lang_name_c)
     warning ("use of old-style cast");
 
   return expr;
@@ -3988,7 +3989,7 @@ build_expr_from_tree (t)
       else 
        {
          tree fn = TREE_OPERAND (t, 0);
-         
+
          /* We can get a TEMPLATE_ID_EXPR here on code like:
 
               x->f<2>();
@@ -3999,7 +4000,9 @@ build_expr_from_tree (t)
             build_expr_from_tree.  So, just use build_expr_from_tree
             when we really need it.  */
          if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
-           fn = build_expr_from_tree (fn);
+           fn = lookup_template_function
+             (TREE_OPERAND (fn, 0),
+              build_expr_from_tree (TREE_OPERAND (fn, 1)));
 
          return build_method_call
            (build_expr_from_tree (TREE_OPERAND (t, 1)),
index ed316e1dafcdbc24b18bb1bc64b76ccdc33c8c2f..4da1d2f3b87dd971b45f073ab54b1538a8ffb947 100644 (file)
@@ -211,6 +211,11 @@ dump_type_real (t, v, canonical_name)
       OB_PUTS ("{unknown type}");
       break;
 
+    case TREE_LIST:
+      /* A list of function parms.  */
+      dump_parameters (t, 0, canonical_name);
+      break;
+
     case IDENTIFIER_NODE:
       OB_PUTID (t);
       break;
index 5789c3f74a6a00f9ac6b283d176734fcec61fa8a..e6209f906820164363644eb84d867c878471607f 100644 (file)
@@ -3574,6 +3574,7 @@ maybe_get_template_decl_from_type_decl (decl)
   return (decl != NULL_TREE
          && TREE_CODE (decl) == TYPE_DECL 
          && DECL_ARTIFICIAL (decl)
+         && CLASS_TYPE_P (decl)
          && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl))) 
     ? CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl)) : decl;
 }
@@ -8909,8 +8910,8 @@ do_decl_instantiation (declspecs, declarator, storage)
 
         No program shall both explicitly instantiate and explicitly
         specialize a template.  */
-      cp_error ("explicit instantiation of `%#D' after", result);
-      cp_error_at ("explicit specialization here", result);
+      cp_pedwarn ("explicit instantiation of `%#D' after", result);
+      cp_pedwarn_at ("explicit specialization here", result);
       return;
     }
   else if (DECL_EXPLICIT_INSTANTIATION (result))
@@ -8924,7 +8925,7 @@ do_decl_instantiation (declspecs, declarator, storage)
         first instantiation was `extern' and the second is not, and
         EXTERN_P for the opposite case.  */
       if (DECL_INTERFACE_KNOWN (result) && !extern_p)
-       cp_error ("duplicate explicit instantiation of `%#D'", result);
+       cp_pedwarn ("duplicate explicit instantiation of `%#D'", result);
 
       /* If we've already instantiated the template, just return now.  */
       if (DECL_INTERFACE_KNOWN (result))
index 23ae9edee377c038e1bab10082fc94e38d692ded..d0743e950f40b2c56a8f69920a5e90a6feb389f2 100644 (file)
@@ -1355,8 +1355,13 @@ comp_target_parms (parms1, parms2, strict)
 
   if (t1 == 0 && t2 != 0)
     {
-      cp_pedwarn ("ANSI C++ prohibits conversion from `(%#T)' to `(...)'",
-                 parms2);
+      if (! flag_strict_prototype && t2 == void_list_node)
+       /* t1 might be the arglist of a function pointer in extern "C"
+          declared to take (), which we fudged to (...).  Don't make the
+          user pay for our mistake.  */;
+      else
+       cp_pedwarn ("ANSI C++ prohibits conversion from `%#T' to `(...)'",
+                   parms2);
       return self_promoting_args_p (t2);
     }
   if (t2 == 0)
@@ -6360,7 +6365,12 @@ build_x_modify_expr (lhs, modifycode, rhs)
 \f
 /* Get difference in deltas for different pointer to member function
    types.  Return integer_zero_node, if FROM cannot be converted to a
-   TO type.  If FORCE is true, then allow reverse conversions as well.  */
+   TO type.  If FORCE is true, then allow reverse conversions as well.
+
+   Note that the naming of FROM and TO is kind of backwards; the return
+   value is what we add to a TO in order to get a FROM.  They are named
+   this way because we call this function to find out how to convert from
+   a pointer to member of FROM to a pointer to member of TO.  */
 
 static tree
 get_delta_difference (from, to, force)
@@ -6618,38 +6628,41 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2)
 {
   tree type = TREE_TYPE (cst);
   tree fn = PTRMEM_CST_MEMBER (cst);
+  tree ptr_class, fn_class;
 
   my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
-  
-  *delta 
-    = get_delta_difference (TYPE_METHOD_BASETYPE 
-                           (TREE_TYPE (fn)),
-                           TYPE_PTRMEMFUNC_OBJECT_TYPE (type),
-                           /*force=*/0);
+
+  /* The class that the function belongs to.  */
+  fn_class = DECL_CLASS_CONTEXT (fn);
+
+  /* The class that we're creating a pointer to member of.  */
+  ptr_class = TYPE_PTRMEMFUNC_OBJECT_TYPE (type);
+
+  /* First, calculate the adjustment to the function's class.  */
+  *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0);
+
   if (!DECL_VIRTUAL_P (fn))
     {
-      *idx = size_binop (MINUS_EXPR, integer_zero_node,
-                        integer_one_node);
-      *pfn = build_addr_func (fn);
-      if (!same_type_p (TYPE_METHOD_BASETYPE (TREE_TYPE (fn)),
-                       TYPE_PTRMEMFUNC_OBJECT_TYPE (type)))
-       *pfn = build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type), 
-                      *pfn);
+      *idx = size_binop (MINUS_EXPR, integer_zero_node, integer_one_node);
+      *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn));
       *delta2 = NULL_TREE;
     }
   else
     {
-      *idx = size_binop (PLUS_EXPR, DECL_VINDEX (fn), 
-                        integer_one_node);
+      /* If we're dealing with a virtual function, we have to adjust 'this'
+         again, to point to the base which provides the vtable entry for
+         fn; the call will do the opposite adjustment.  */
+      tree orig_class = DECL_VIRTUAL_CONTEXT (fn);
+      tree binfo = binfo_or_else (orig_class, fn_class);
+      *delta = size_binop (PLUS_EXPR, *delta, BINFO_OFFSET (binfo));
+
+      /* Map everything down one to make room for the null PMF.  */
+      *idx = size_binop (PLUS_EXPR, DECL_VINDEX (fn), integer_one_node);
       *pfn = NULL_TREE;
-      *delta2 = get_binfo (DECL_CONTEXT (fn),
-                         DECL_CLASS_CONTEXT (fn),
-                         0);
-      *delta2 = get_vfield_offset (*delta2);
-      *delta2 = size_binop (PLUS_EXPR, *delta2,
-                          build_binary_op (PLUS_EXPR,
-                                           *delta, 
-                                           integer_zero_node));
+
+      /* Offset from an object of PTR_CLASS to the vptr for ORIG_CLASS.  */
+      *delta2 = size_binop (PLUS_EXPR, *delta,
+                           get_vfield_offset (TYPE_BINFO (orig_class)));
     }
 }
 
@@ -7353,7 +7366,7 @@ c_expand_return (retval)
        || DECL_NAME (current_function_decl) == ansi_opname[(int) VEC_NEW_EXPR])
       && !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
       && null_ptr_cst_p (retval))
-    cp_pedwarn ("operator new should throw an exception, not return NULL");
+    cp_warning ("operator new should throw an exception, not return NULL");
   
   if (retval == NULL_TREE)
     {