OSDN Git Service

* method.c (hack_identifier): Don't let a class template out.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Jun 1998 02:51:01 +0000 (02:51 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Jun 1998 02:51:01 +0000 (02:51 +0000)
* call.c (check_dtor_name): Split out.
(build_scoped_method_call): Use it.
(build_method_call): Use it.
* init.c (build_offset_ref): Use it.
* typeck.c (build_static_cast): Fix handling of pointers to members.
* decl.c (finish_function): Just return nothing from a constructor.
* typeck.c (c_expand_return): Complain about returning a void
expression from a destructor.

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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/typeck.c

index 897a1a1..ea7f271 100644 (file)
@@ -1,3 +1,18 @@
+1998-06-16  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * method.c (hack_identifier): Don't let a class template out.
+
+       * call.c (check_dtor_name): Split out.
+       (build_scoped_method_call): Use it.
+       (build_method_call): Use it.
+       * init.c (build_offset_ref): Use it.
+
+       * typeck.c (build_static_cast): Fix handling of pointers to members.
+
+       * decl.c (finish_function): Just return nothing from a constructor.
+       * typeck.c (c_expand_return): Complain about returning a void
+       expression from a destructor.
+
 1998-06-13  Mark Mitchell  <mark@markmitchell.com>
 
        * class.c (alter_access): Accept a BINFO explaining how to get
index 429b4cf..8999897 100644 (file)
@@ -340,6 +340,35 @@ resolve_scope_to_name (outer_type, inner_stuff)
   return tmp;
 }
 
+/* Returns nonzero iff the destructor name specified in NAME
+   (a BIT_NOT_EXPR) matches BASETYPE.  The operand of NAME can take many
+   forms...  */
+
+int
+check_dtor_name (basetype, name)
+     tree basetype, name;
+{
+  name = TREE_OPERAND (name, 0);
+
+  if (TREE_CODE (name) == TYPE_DECL)
+    name = TREE_TYPE (name);
+  else if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
+    /* OK */;
+  else if (TREE_CODE (name) == IDENTIFIER_NODE)
+    {
+      if (IS_AGGR_TYPE (basetype) && name == constructor_name (basetype))
+       name = basetype;
+      else
+       name = get_type_value (name);
+    }
+  else
+    my_friendly_abort (980605);
+
+  if (name && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (name))
+    return 1;
+  return 0;
+}
+
 /* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'.
    This is how virtual function calls are avoided.  */
 
@@ -386,31 +415,9 @@ build_scoped_method_call (exp, basetype, name, parms)
     binfo = NULL_TREE;
 
   /* Check the destructor call syntax.  */
-  if (TREE_CODE (name) == BIT_NOT_EXPR)
-    {
-      tmp = TREE_OPERAND (name, 0);
-
-      if (TREE_CODE (tmp) == TYPE_DECL)
-       tmp = TREE_TYPE (tmp);
-      else if (TREE_CODE_CLASS (TREE_CODE (tmp)) == 't')
-       /* OK */;
-      else if (TREE_CODE (tmp) == IDENTIFIER_NODE)
-       {
-         if (IS_AGGR_TYPE (basetype) && tmp == constructor_name (basetype))
-           tmp = basetype;
-         else
-           tmp = get_type_value (tmp);
-       }
-      else
-       my_friendly_abort (980605);
-      
-      if (! (tmp && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (tmp)))
-       {
-         cp_error ("qualified type `%T' does not match destructor name `~%T'",
-                   basetype, TREE_OPERAND (name, 0));
-         return error_mark_node;
-       }
-    }
+  if (TREE_CODE (name) == BIT_NOT_EXPR && ! check_dtor_name (basetype, name))
+    cp_error ("qualified type `%T' does not match destructor name `~%T'",
+             basetype, TREE_OPERAND (name, 0));
 
   /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note
      that explicit ~int is caught in the parser; this deals with typedefs
@@ -645,36 +652,16 @@ build_method_call (instance, name, parms, basetype_path, flags)
 
   if (TREE_CODE (name) == BIT_NOT_EXPR)
     {
-      tree tmp;
-
-      tmp = name = TREE_OPERAND (name, 0);
-
       if (parms)
        error ("destructors take no parameters");
       basetype = TREE_TYPE (instance);
       if (TREE_CODE (basetype) == REFERENCE_TYPE)
        basetype = TREE_TYPE (basetype);
 
-      if (TREE_CODE (tmp) == TYPE_DECL)
-       tmp = TREE_TYPE (tmp);
-      else if (TREE_CODE_CLASS (TREE_CODE (tmp)) == 't')
-       /* OK */;
-      else if (TREE_CODE (tmp) == IDENTIFIER_NODE)
-       {
-         if (IS_AGGR_TYPE (basetype) && tmp == constructor_name (basetype))
-           tmp = basetype;
-         else
-           tmp = get_type_value (tmp);
-       }
-      else
-       my_friendly_abort (980605);
-
-      if (! (tmp && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (tmp)))
-       {
-         cp_error ("destructor name `~%T' does not match type `%T' of expression",
-                   name, basetype);
-         return cp_convert (void_type_node, instance);
-       }
+      if (! check_dtor_name (basetype, name))
+       cp_error
+         ("destructor name `~%T' does not match type `%T' of expression",
+          TREE_OPERAND (name, 0), basetype);
 
       if (! TYPE_HAS_DESTRUCTOR (complete_type (basetype)))
        return cp_convert (void_type_node, instance);
index e6c5fff..20dfdf7 100644 (file)
@@ -12599,7 +12599,8 @@ finish_function (lineno, call_poplevel, nested)
                  expand_end_bindings (decls, decls != NULL_TREE, 0);
                  poplevel (decls != NULL_TREE, 0, 0);
                }
-             c_expand_return (current_class_ptr);
+             /* c_expand_return knows to return 'this' from a constructor.  */
+             c_expand_return (NULL_TREE);
            }
          else if (TREE_CODE (TREE_TYPE (DECL_RESULT (current_function_decl))) != VOID_TYPE
                   && return_label != NULL_RTX)
@@ -12666,7 +12667,8 @@ finish_function (lineno, call_poplevel, nested)
              poplevel (decls != NULL_TREE, 1, 0);
            }
 
-         c_expand_return (current_class_ptr);
+         /* c_expand_return knows to return 'this' from a constructor.  */
+         c_expand_return (NULL_TREE);
 
          current_function_assigns_this = 0;
          current_function_just_assigned_this = 0;
index aa8fb0c..84015b0 100644 (file)
@@ -1521,7 +1521,6 @@ build_offset_ref (type, name)
 {
   tree decl, fnfields, fields, t = error_mark_node;
   tree basebinfo = NULL_TREE;
-  int dtor = 0;
   tree orig_name = name;
 
   /* class templates can come in as TEMPLATE_DECLs here.  */
@@ -1553,12 +1552,17 @@ build_offset_ref (type, name)
 
   if (TREE_CODE (name) == BIT_NOT_EXPR)
     {
-      dtor = 1;
-      name = TREE_OPERAND (name, 0);
+      if (! check_dtor_name (type, name))
+       cp_error ("qualified type `%T' does not match destructor name `~%T'",
+                 type, TREE_OPERAND (name, 0));
+      name = dtor_identifier;
     }
-
-  if (name == constructor_name_full (type))
-    name = constructor_name (type);
+#if 0
+  /* I think this is wrong, but the draft is unclear.  --jason 6/15/98 */
+  else if (name == constructor_name_full (type)
+          || name == constructor_name (type))
+    name = ctor_identifier;
+#endif
 
   if (TYPE_SIZE (complete_type (type)) == 0)
     {
@@ -1598,18 +1602,6 @@ build_offset_ref (type, name)
   else
     decl = current_class_ref;
 
-  if (constructor_name (BINFO_TYPE (basebinfo)) == name)
-    {
-      if (dtor)
-       name = dtor_identifier;
-      else
-       name = ctor_identifier;
-    }
-  else
-    if (dtor)
-      my_friendly_abort (999);
-
-    
   fnfields = lookup_fnfields (basebinfo, name, 1);
   fields = lookup_field (basebinfo, name, 0, 0);
 
index cc01371..1414870 100644 (file)
@@ -1847,6 +1847,11 @@ hack_identifier (value, name)
   else if (TREE_CODE (value) == NAMESPACE_DECL)
     /* A namespace is not really expected here; this is likely illegal code. */
     return value;
+  else if (DECL_CLASS_TEMPLATE_P (value))
+    {
+      cp_error ("use of class template `%T' as expression", value);
+      value = error_mark_node;
+    }
   else
     mark_used (value);
 
index b8a46d1..b038a86 100644 (file)
@@ -4774,7 +4774,11 @@ unary_complex_lvalue (code, arg)
 
       /* Check all this code for right semantics.  */  
       if (TREE_CODE (t) == FUNCTION_DECL)
-       return build_unary_op (ADDR_EXPR, t, 0);
+       {
+         if (DECL_DESTRUCTOR_P (t))
+           cp_error ("taking address of destructor");
+         return build_unary_op (ADDR_EXPR, t, 0);
+       }
       if (TREE_CODE (t) == VAR_DECL)
        return build_unary_op (ADDR_EXPR, t, 0);
       else
@@ -5422,8 +5426,8 @@ build_static_cast (type, expr)
              >= TYPE_READONLY (TREE_TYPE (TREE_TYPE (intype))))
          && (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (type)))
              >= TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (intype))))
-         && (binfo = get_binfo (TYPE_OFFSET_BASETYPE (intype),
-                                TYPE_OFFSET_BASETYPE (type), 0))
+         && (binfo = get_binfo (TYPE_OFFSET_BASETYPE (TREE_TYPE (type)),
+                                TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)), 0))
          && ! TREE_VIA_VIRTUAL (binfo))
        ok = 1;
     }
@@ -7206,16 +7210,19 @@ c_expand_return (retval)
       return;
     }
 
-  if (retval == NULL_TREE)
+  if (dtor_label)
     {
-      /* A non-named return value does not count.  */
+      if (retval)
+       error ("returning a value from a destructor");
 
       /* Can't just return from a destructor.  */
-      if (dtor_label)
-       {
-         expand_goto (dtor_label);
-         return;
-       }
+      expand_goto (dtor_label);
+      return;
+    }
+
+  if (retval == NULL_TREE)
+    {
+      /* A non-named return value does not count.  */
 
       if (DECL_CONSTRUCTOR_P (current_function_decl))
        retval = current_class_ptr;
@@ -7242,13 +7249,12 @@ c_expand_return (retval)
          return;
        }
     }
-  else if (DECL_CONSTRUCTOR_P (current_function_decl)
-          && retval != current_class_ptr)
+  else if (DECL_CONSTRUCTOR_P (current_function_decl))
     {
       if (flag_this_is_variable)
        error ("return from a constructor: use `this = ...' instead");
       else
-       error ("return from a constructor");
+       error ("returning a value from a constructor");
       retval = current_class_ptr;
     }