OSDN Git Service

* class.c (current_class_ptr, current_class_ref): Clarify
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 3 Oct 1998 23:11:19 +0000 (23:11 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 3 Oct 1998 23:11:19 +0000 (23:11 +0000)
documentation.
* cvt.c (ocp_convert): Don't expect fold to remove all trivial
NOP type conversions.
* decl.c (decls_match): Use comptypes directly; ignore
qualifiers on the DECL.
(duplicate_decls): Remove qualifier checks on DECL.
(grokdeclarator): Make the type built up include top-level
qualifiers.
* decl2.c (do_dtors): Fix spelling error.
* error.c (dump_simple_decl): Don't look at qualifiers on the decl
when printing type information.
* init.c (build_new_1): Add documentation.  Deal with the fact
that type of allocated memory now contains qualifiers.
* lex.c (is_global): Improve error-recovery.
* sig.c (build_member_function_pointer): Don't cast away const
on fields of sigtable_entry_type.
* tree.c (lvalue_type): Don't look at top-level qualifiers on
expressions.
* typeck.c (decay_conversion): Likewise.
(build_component_ref): Make sure the type of the COMPONENT_REF
contains top-level qualifiers, as appropriate.  Improve
error-handling.
(build_indirect_ref): Simplify.  Don't strip top-level qualifiers.
(build_array_ref): Likewise.
(build_unary_op): Improve error-recovery.
(unary_complex_lvalue): Make taking the address a bound member
function an error, not a sorry.
(build_conditional_expr): Look at the type qualifiers, not the
qualifiers on the expression itself.

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

12 files changed:
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/sig.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/g++.old-deja/g++.pt/overload3.C [new file with mode: 0644]

index 8604334..7634176 100644 (file)
@@ -1,3 +1,36 @@
+1998-10-03  Mark Mitchell  <mark@markmitchell.com>
+
+       * class.c (current_class_ptr, current_class_ref): Clarify
+       documentation.
+       * cvt.c (ocp_convert): Don't expect fold to remove all trivial
+       NOP type conversions.
+       * decl.c (decls_match): Use comptypes directly; ignore
+       qualifiers on the DECL.
+       (duplicate_decls): Remove qualifier checks on DECL.
+       (grokdeclarator): Make the type built up include top-level
+       qualifiers.
+       * decl2.c (do_dtors): Fix spelling error.
+       * error.c (dump_simple_decl): Don't look at qualifiers on the decl
+       when printing type information.
+       * init.c (build_new_1): Add documentation.  Deal with the fact
+       that type of allocated memory now contains qualifiers.
+       * lex.c (is_global): Improve error-recovery.
+       * sig.c (build_member_function_pointer): Don't cast away const
+       on fields of sigtable_entry_type.
+       * tree.c (lvalue_type): Don't look at top-level qualifiers on
+       expressions.
+       * typeck.c (decay_conversion): Likewise.
+       (build_component_ref): Make sure the type of the COMPONENT_REF
+       contains top-level qualifiers, as appropriate.  Improve
+       error-handling. 
+       (build_indirect_ref): Simplify.  Don't strip top-level qualifiers.
+       (build_array_ref): Likewise.
+       (build_unary_op): Improve error-recovery.
+       (unary_complex_lvalue): Make taking the address a bound member
+       function an error, not a sorry.
+       (build_conditional_expr): Look at the type qualifiers, not the
+       qualifiers on the expression itself.
+       
 1998-10-03  Jason Merrill  <jason@yorick.cygnus.com>
 
        * decl2.c (merge_functions): Remove duplicates.
index 8e7d715..b64a91a 100644 (file)
@@ -48,8 +48,9 @@ static tree *current_class_base, *current_class_stack;
 static int current_class_stacksize;
 int current_class_depth;
 
-/* The current_class_ptr is the pointer to the current class.
-   current_class_ref is the actual current class.  */
+/* When we're processing a member function, current_class_ptr is the
+   PARM_DECL for the `this' pointer.  The current_class_ref is an
+   expression for `*this'.  */
 tree current_class_ptr, current_class_ref;
 
 /* The following two can be derived from the previous one */
index c76b743..06c5290 100644 (file)
@@ -664,9 +664,19 @@ ocp_convert (type, expr, convtype, flags)
       && TYPE_HAS_CONSTRUCTOR (type))
     /* We need a new temporary; don't take this shortcut.  */;
   else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
-    /* Trivial conversion: cv-qualifiers do not matter on rvalues.  */
-    return fold (build1 (NOP_EXPR, type, e));
-  
+    {
+      if (comptypes (type, TREE_TYPE (e), 1))
+       /* The call to fold will not always remove the NOP_EXPR as
+          might be expected, since if one of the types is a typedef;
+          the comparsion in fold is just equality of pointers, not a
+          call to comptypes.  */
+       ;
+      else
+       e = build1 (NOP_EXPR, type, e);
+
+      return fold (e);
+    }
+
   if (code == VOID_TYPE && (convtype & CONV_STATIC))
     return build1 (CONVERT_EXPR, type, e);
 
index a4ed7b9..71fe530 100644 (file)
@@ -2571,20 +2571,9 @@ decls_match (newdecl, olddecl)
        types_match = TREE_TYPE (newdecl) == NULL_TREE;
       else if (TREE_TYPE (newdecl) == NULL_TREE)
        types_match = 0;
-      /* Qualifiers must match, and they may be present on either, the type
-        or the decl.  */
-      else if ((TREE_READONLY (newdecl)
-               || TYPE_READONLY (TREE_TYPE (newdecl)))
-              == (TREE_READONLY (olddecl)
-                  || TYPE_READONLY (TREE_TYPE (olddecl)))
-              && (TREE_THIS_VOLATILE (newdecl)
-                   || TYPE_VOLATILE (TREE_TYPE (newdecl)))
-                  == (TREE_THIS_VOLATILE (olddecl)
-                      || TYPE_VOLATILE (TREE_TYPE (olddecl))))
-       types_match = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (newdecl)),
-                                TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)), 1);
       else
-       types_match = 0;
+       types_match = comptypes (TREE_TYPE (newdecl),
+                                TREE_TYPE (olddecl), 1);
     }
 
   return types_match;
@@ -2908,13 +2897,6 @@ duplicate_decls (newdecl, olddecl)
                             olddecl);
            }
        }
-      /* These bits are logically part of the type for non-functions.  */
-      else if (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
-              || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl))
-       {
-         cp_pedwarn ("type qualifiers for `%#D'", newdecl);
-         cp_pedwarn_at ("conflict with previous decl `%#D'", olddecl);
-       }
     }
 
   /* If new decl is `static' and an `extern' was seen previously,
@@ -9084,7 +9066,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
   constp = !! RIDBIT_SETP (RID_CONST, specbits) + TYPE_READONLY (type);
   volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + TYPE_VOLATILE (type);
-  type = build_type_variant (type, 0, 0);
+  type = cp_build_type_variant (type, constp, volatilep);
   staticp = 0;
   inlinep = !! RIDBIT_SETP (RID_INLINE, specbits);
   virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
@@ -9817,6 +9799,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                    pedwarn ("discarding `volatile' applied to a reference");
                  constp = volatilep = 0;
                }
+             type = cp_build_type_variant (type, constp, volatilep);
            }
          declarator = TREE_OPERAND (declarator, 0);
          ctype = NULL_TREE;
@@ -10903,7 +10886,11 @@ grokparms (first_parm, funcdef_flag)
                                         NULL_TREE);
                  if (! decl)
                    continue;
-                 type = TREE_TYPE (decl);
+
+                 /* Top-level qualifiers on the parameters are
+                    ignored for function types.  */
+                 type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
+
                  if (TREE_CODE (type) == VOID_TYPE)
                    decl = void_type_node;
                  else if (TREE_CODE (type) == METHOD_TYPE)
index 50eea9f..492688b 100644 (file)
@@ -3192,7 +3192,7 @@ do_dtors (start)
 
               Access control for implicit calls to the constructors,
               the conversion functions, or the destructor called to
-              create and destroy a static data member is performed as
+              create and destroy a static data member is performed as
               if these calls appeared in the scope of the member's
               class.  
 
index f06705e..fb6995f 100644 (file)
@@ -667,7 +667,6 @@ dump_simple_decl (t, type, v)
     {
       dump_type_prefix (type, v, 0);
       OB_PUTC (' ');
-      dump_readonly_or_volatile (t, after);
     }
   if (DECL_CLASS_SCOPE_P (t))
     {
index c5ba2c4..b6a20ba 100644 (file)
@@ -2391,12 +2391,26 @@ build_new_1 (exp)
       if (! TYPE_NEEDS_CONSTRUCTING (type)
          && ! IS_AGGR_TYPE (type) && ! has_array)
        {
-         /* New 2.0 interpretation: `new int (10)' means
-            allocate an int, and initialize it with 10.  */
+         /* We are processing something like `new int (10)', which
+            means allocate an int, and initialize it with 10.  */
          tree deref;
+         tree deref_type;
 
+         /* At present RVAL is a temporary variable, created to hold
+            the value from the call to `operator new'.  We transform
+            it to (*RVAL = INIT, RVAL).  */
          rval = save_expr (rval);
          deref = build_indirect_ref (rval, NULL_PTR);
+
+         /* Even for something like `new const int (10)' we must
+            allow the expression to be non-const while we do the
+            initialization.  */
+         deref_type = TREE_TYPE (deref);
+         if (TYPE_READONLY (deref_type))
+           TREE_TYPE (deref) 
+             = cp_build_type_variant (deref_type,
+                                      /*constp=*/0,
+                                      TYPE_VOLATILE (deref_type));
          TREE_READONLY (deref) = 0;
 
          if (TREE_CHAIN (init) != NULL_TREE)
index ac4d8b4..d69dc6e 100644 (file)
@@ -2853,6 +2853,9 @@ is_global (d)
   while (1)
     switch (TREE_CODE (d))
       {
+      case ERROR_MARK:
+       return 1;
+
       case OVERLOAD: d = OVL_FUNCTION (d); continue;
       case TREE_LIST: d = TREE_VALUE (d); continue;
       default:
index 65350db..e70ec3f 100644 (file)
@@ -321,7 +321,7 @@ build_member_function_pointer (member)
   GNU_xref_ref (current_function_decl, name);
 
   entry = build_lang_field_decl (FIELD_DECL, get_identifier (name),
-                                TYPE_MAIN_VARIANT (sigtable_entry_type));
+                                sigtable_entry_type);
   TREE_CONSTANT (entry) = 1;
   TREE_READONLY (entry) = 1;
 
index e66cbff..00202b3 100644 (file)
@@ -2571,9 +2571,6 @@ lvalue_type (arg)
   tree type = TREE_TYPE (arg);
   if (TREE_CODE (arg) == OVERLOAD)
     type = unknown_type_node;
-  else if (TREE_CODE (type) != ARRAY_TYPE)
-    type = cp_build_type_variant
-      (type, TREE_READONLY (arg), TREE_THIS_VOLATILE (arg));
   return type;
 }
 
index 40b5b7e..d0be08a 100644 (file)
@@ -1684,9 +1684,7 @@ decay_conversion (exp)
   if (code == ARRAY_TYPE)
     {
       register tree adr;
-      tree restype;
       tree ptrtype;
-      int constp, volatilep;
 
       if (TREE_CODE (exp) == INDIRECT_REF)
        {
@@ -1718,21 +1716,7 @@ decay_conversion (exp)
          return error_mark_node;
        }
 
-      constp = volatilep = 0;
-      if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r'
-         || TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')
-       {
-         constp = TREE_READONLY (exp);
-         volatilep = TREE_THIS_VOLATILE (exp);
-       }
-
-      restype = TREE_TYPE (type);
-      if (TYPE_READONLY (type) || TYPE_VOLATILE (type)
-         || constp || volatilep)
-       restype = cp_build_type_variant (restype,
-                                        TYPE_READONLY (type) || constp,
-                                        TYPE_VOLATILE (type) || volatilep);
-      ptrtype = build_pointer_type (restype);
+      ptrtype = build_pointer_type (TREE_TYPE (type));
 
       if (TREE_CODE (exp) == VAR_DECL)
        {
@@ -1954,14 +1938,24 @@ build_component_ref (datum, component, basetype_path, protect)
      tree datum, component, basetype_path;
      int protect;
 {
-  register tree basetype = TREE_TYPE (datum);
+  register tree basetype;
   register enum tree_code code;
   register tree field = NULL;
   register tree ref;
+  tree field_type;
+  int constp;
+  int volatilep;
 
   if (processing_template_decl)
     return build_min_nt (COMPONENT_REF, datum, component);
+  
+  if (datum == error_mark_node 
+      || TREE_TYPE (datum) == error_mark_node)
+    return error_mark_node;
 
+  /* BASETYPE holds the type of the class containing the COMPONENT.  */
+  basetype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
+    
   /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference
      inside it.  */
   switch (TREE_CODE (datum))
@@ -1995,13 +1989,13 @@ build_component_ref (datum, component, basetype_path, protect)
   if (code == REFERENCE_TYPE)
     {
       datum = convert_from_reference (datum);
-      basetype = TREE_TYPE (datum);
+      basetype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
       code = TREE_CODE (basetype);
     }
   if (TREE_CODE (datum) == OFFSET_REF)
     {
       datum = resolve_offset_ref (datum);
-      basetype = TREE_TYPE (datum);
+      basetype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
       code = TREE_CODE (basetype);
     }
 
@@ -2086,7 +2080,7 @@ build_component_ref (datum, component, basetype_path, protect)
                  tree access, fndecl;
 
                  /* Unique, so use this one now.  */
-                 basetype = TREE_PURPOSE (fndecls);
+                 basetype = TYPE_MAIN_VARIANT (TREE_PURPOSE (fndecls));
                  fndecl = TREE_VALUE (fndecls);
                  access = compute_access (TREE_PURPOSE (fndecls), fndecl);
                  if (access == access_public_node)
@@ -2198,15 +2192,40 @@ build_component_ref (datum, component, basetype_path, protect)
        }
     }
 
-  ref = fold (build (COMPONENT_REF, TREE_TYPE (field),
+  /* Compute the type of the field, as described in [expr.ref].  */
+  constp = 0;
+  volatilep = 0;
+  field_type = TREE_TYPE (field);
+  if (TREE_CODE (field_type) == REFERENCE_TYPE)
+    /* The standard says that the type of the result should be the
+       type referred to by the reference.  But for now, at least, we
+       do the conversion from reference type later.  */
+    ;
+  else
+    {
+      /* A field is const (volatile) if the enclosing object, or the
+        field itself, is const (volatile).  But, a mutable field is
+        not const, even within a const object.  */
+      constp = (!(DECL_LANG_SPECIFIC (field) 
+                 && DECL_MUTABLE_P (field))
+               && (TYPE_READONLY (field_type)
+                   || TYPE_READONLY (TREE_TYPE (datum))));
+      volatilep = (TYPE_VOLATILE (field_type)
+                  || TYPE_VOLATILE (TREE_TYPE (datum)));
+      if (!IS_SIGNATURE (field_type))
+       field_type = cp_build_type_variant (field_type, constp, volatilep);
+    }
+
+  ref = fold (build (COMPONENT_REF, field_type,
                     break_out_cleanups (datum), field));
 
-  if (TREE_READONLY (datum) || TREE_READONLY (field))
+  /* Mark the expression const or volatile, as appropriate.  Even
+     though we've dealt with the type above, we still have to mark the
+     expression itself.  */
+  if (constp)
     TREE_READONLY (ref) = 1;
-  if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field))
+  else if (volatilep)
     TREE_THIS_VOLATILE (ref) = 1;
-  if (DECL_LANG_SPECIFIC (field) && DECL_MUTABLE_P (field))
-    TREE_READONLY (ref) = 0;
 
   return ref;
 }
@@ -2270,29 +2289,34 @@ build_indirect_ref (ptr, errorstring)
 
   if (TREE_CODE (type) == POINTER_TYPE || TREE_CODE (type) == REFERENCE_TYPE)
     {
+      /* [expr.unary.op]
+        
+        If the type of the expression is "pointer to T," the type
+        of  the  result  is  "T."   
+
+         We must use the canonical variant because certain parts of
+        the back end, like fold, do pointer comparisons between
+        types.  */
+      tree t = canonical_type_variant (TREE_TYPE (type));
+
       if (TREE_CODE (pointer) == ADDR_EXPR
          && !flag_volatile
-         && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (pointer, 0)))
-             == TYPE_MAIN_VARIANT (TREE_TYPE (type)))
-         && (TREE_READONLY (TREE_OPERAND (pointer, 0))
-             == TYPE_READONLY (TREE_TYPE (type)))
-         && (TREE_THIS_VOLATILE (TREE_OPERAND (pointer, 0))
-             == TYPE_VOLATILE (TREE_TYPE (type))))
+         && comptypes (t, TREE_TYPE (TREE_OPERAND (pointer, 0)), 1))
+       /* The POINTER was something like `&x'.  We simplify `*&x' to
+          `x'.  */
        return TREE_OPERAND (pointer, 0);
       else
        {
-         tree t = TREE_TYPE (type);
-         register tree ref = build1 (INDIRECT_REF,
-                                     TYPE_MAIN_VARIANT (t), pointer);
+         tree ref = build1 (INDIRECT_REF, t, pointer);
 
          /* We *must* set TREE_READONLY when dereferencing a pointer to const,
             so that we get the proper error message if the result is used
             to assign to.  Also, &* is supposed to be a no-op.  */
          TREE_READONLY (ref) = TYPE_READONLY (t);
+         TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
          TREE_SIDE_EFFECTS (ref)
-           = (TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer)
+           = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer)
               || flag_volatile);
-         TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
          return ref;
        }
     }
@@ -2403,23 +2427,16 @@ build_array_ref (array, idx)
            warning ("subscripting array declared `register'");
        }
 
-      type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
+      type = TREE_TYPE (TREE_TYPE (array));
       rval = build (ARRAY_REF, type, array, idx);
       /* Array ref is const/volatile if the array elements are
         or if the array is..  */
       TREE_READONLY (rval)
-       |= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array)))
-           | TREE_READONLY (array));
+       |= (TYPE_READONLY (type) | TREE_READONLY (array));
       TREE_SIDE_EFFECTS (rval)
-       |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
-           | TREE_SIDE_EFFECTS (array));
+       |= (TYPE_VOLATILE (type) | TREE_SIDE_EFFECTS (array));
       TREE_THIS_VOLATILE (rval)
-       |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
-           /* This was added by rms on 16 Nov 91.
-              It fixes  vol struct foo *a;  a->elts[1] 
-              in an inline function.
-              Hope it doesn't break something else.  */
-           | TREE_THIS_VOLATILE (array));
+       |= (TYPE_VOLATILE (type) | TREE_THIS_VOLATILE (array));
       return require_complete_type (fold (rval));
     }
 
@@ -4720,7 +4737,8 @@ build_unary_op (code, xarg, noconvert)
               && !lvalue_or_else (arg, "unary `&'"))
        return error_mark_node;
 
-      argtype = build_pointer_type (argtype);
+      if (argtype != error_mark_node)
+       argtype = build_pointer_type (argtype);
 
       if (mark_addressable (arg) == 0)
        return error_mark_node;
@@ -4871,14 +4889,12 @@ unary_complex_lvalue (code, arg)
          if (TREE_OPERAND (arg, 0)
              && (TREE_CODE (TREE_OPERAND (arg, 0)) != NOP_EXPR
                  || (TREE_OPERAND (TREE_OPERAND (arg, 0), 0)
-                     != error_mark_node)))
-           if (TREE_CODE (t) != FIELD_DECL)
-             {
-               /* Don't know if this should return address to just
-                  _DECL, or actual address resolved in this expression.  */
-               sorry ("address of bound pointer-to-member expression");
-               return error_mark_node;
-             }
+                     != error_mark_node))
+             && TREE_CODE (t) != FIELD_DECL)
+           {
+             cp_error ("taking address of bound pointer-to-member expression");
+             return error_mark_node;
+           }
 
          /* Add in the offset to the field.  */
          offset = convert (sizetype,
@@ -5115,8 +5131,8 @@ build_conditional_expr (ifexp, op1, op2)
       if (type1 != type2)
        type1 = cp_build_type_variant
                        (type1,
-                        TREE_READONLY (op1) || TREE_READONLY (op2),
-                        TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2));
+                        TYPE_READONLY (op1) || TYPE_READONLY (op2),
+                        TYPE_VOLATILE (op1) || TYPE_VOLATILE (op2));
       /* ??? This is a kludge to deal with the fact that
         we don't sort out integers and enums properly, yet.  */
       result = fold (build (COND_EXPR, type1, ifexp, op1, op2));
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/overload3.C b/gcc/testsuite/g++.old-deja/g++.pt/overload3.C
new file mode 100644 (file)
index 0000000..a716917
--- /dev/null
@@ -0,0 +1,18 @@
+// Build don't link:
+
+template <class T>
+void g(T, T);
+
+template <class T>
+void g(int*, T);
+
+struct S
+{
+  void f() const
+    {
+      g(X, X+3);
+    }
+
+  double X[3];
+};
+