OSDN Git Service

* search.c (shared_member_p): New function.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Feb 2001 15:54:39 +0000 (15:54 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Feb 2001 15:54:39 +0000 (15:54 +0000)
        (lookup_field_r): Use it.
        * cp-tree.h (SHARED_MEMBER_P): Remove.

        * method.c (process_overload_item): Handle template-dependent array
        bounds.
        * pt.c (type_unification_real): If we end up with undeduced nontype
        parms, try again.

        * decl.c (lookup_name_real): Tweak warning to refer to decls, not
        types.

        * typeck2.c (friendly_abort): Don't say anything if we have
        earlier errors or sorries.

        * decl.c (check_tag_decl): Notice attempts to redefine bool and
        wchar_t.  Ignore if in_system_header.

        * decl.c (maybe_push_cleanup_level): New fn...
        (start_decl_1): ...split out from here.
        * cvt.c (build_up_reference): Use it.
        * cp-tree.h: Declare it.

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

13 files changed:
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/method.c
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/typeck2.c
gcc/testsuite/g++.old-deja/g++.ext/syshdr1.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/dtor12.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/goto4.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/lookup21.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/deduct4.C [new file with mode: 0644]

index 6f756a4..feb0177 100644 (file)
@@ -1,3 +1,28 @@
+2001-02-08  Jason Merrill  <jason@redhat.com>
+
+       * search.c (shared_member_p): New function.
+       (lookup_field_r): Use it.
+       * cp-tree.h (SHARED_MEMBER_P): Remove.
+
+       * method.c (process_overload_item): Handle template-dependent array
+       bounds.
+       * pt.c (type_unification_real): If we end up with undeduced nontype
+       parms, try again.
+
+       * decl.c (lookup_name_real): Tweak warning to refer to decls, not
+       types.
+
+       * typeck2.c (friendly_abort): Don't say anything if we have
+       earlier errors or sorries.
+
+       * decl.c (check_tag_decl): Notice attempts to redefine bool and 
+       wchar_t.  Ignore if in_system_header.
+
+       * decl.c (maybe_push_cleanup_level): New fn...
+       (start_decl_1): ...split out from here.
+       * cvt.c (build_up_reference): Use it.
+       * cp-tree.h: Declare it.
+
 2001-02-07  Mark Mitchell  <mark@codesourcery.com>
 
        * lang-specs.h: Use CPLUSPLUS_CPP_SPEC for the preprocessor 
index d473006..43a9714 100644 (file)
@@ -2070,12 +2070,6 @@ struct lang_decl
    member function.  */
 #define DECL_STATIC_FUNCTION_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.static_function)
 
-/* Nonzero for a class member means that it is shared between all objects
-   of that class.  */
-#define SHARED_MEMBER_P(NODE) \
-  (TREE_CODE (NODE) == VAR_DECL || TREE_CODE (NODE) == TYPE_DECL \
-   || TREE_CODE (NODE) == CONST_DECL)
-
 /* Nonzero for FUNCTION_DECL means that this decl is a non-static
    member function.  */
 #define DECL_NONSTATIC_MEMBER_FUNCTION_P(NODE) \
@@ -3785,6 +3779,7 @@ extern void keep_next_level                       PARAMS ((int));
 extern int kept_level_p                                PARAMS ((void));
 extern int template_parm_scope_p               PARAMS ((void));
 extern void set_class_shadows                  PARAMS ((tree));
+extern void maybe_push_cleanup_level           PARAMS ((tree));
 extern void begin_scope                         PARAMS ((scope_kind));
 extern void finish_scope                        PARAMS ((void));
 extern void note_level_for_for                 PARAMS ((void));
index ff7d4bc..9fa2a66 100644 (file)
@@ -380,6 +380,7 @@ build_up_reference (type, arg, flags)
        arg = get_temp_name (argtype);
       else
        {
+         maybe_push_cleanup_level (argtype);
          arg = pushdecl (build_decl (VAR_DECL, NULL_TREE, argtype));
          DECL_ARTIFICIAL (arg) = 1;
        }
index 13e3094..dcf84e6 100644 (file)
@@ -863,6 +863,24 @@ pushlevel (tag_transparent)
   keep_next_level_flag = 0;
 }
 
+/* We're defining an object of type TYPE.  If it needs a cleanup, but
+   we're not allowed to add any more objects with cleanups to the current
+   scope, create a new binding level.  */
+
+void
+maybe_push_cleanup_level (type)
+     tree type;
+{
+  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+      && current_binding_level->more_cleanups_ok == 0)
+    {
+      keep_next_level (2);
+      pushlevel (1);
+      clear_last_expr ();
+      add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
+    }
+}
+  
 /* Enter a new scope.  The KIND indicates what kind of scope is being
    created.  */
 
@@ -5993,10 +6011,9 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
              && TREE_CODE (val) == TYPE_DECL
              && ! same_type_p (TREE_TYPE (from_obj), TREE_TYPE (val)))
            cp_pedwarn ("\
-lookup of `%D' in the scope of `%#T' (`%#T') \
-does not match lookup in the current scope (`%#T')",
-                       name, got_object, TREE_TYPE (from_obj),
-                       TREE_TYPE (val));
+lookup of `%D' in the scope of `%#T' (`%#D') \
+does not match lookup in the current scope (`%#D')",
+                       name, got_object, from_obj, val);
 
          /* We don't change val to from_obj if got_object depends on
             template parms because that breaks implicit typename for
@@ -6864,14 +6881,23 @@ check_tag_decl (declspecs)
       register tree value = TREE_VALUE (link);
 
       if (TYPE_P (value)
+         || TREE_CODE (value) == TYPE_DECL
          || (TREE_CODE (value) == IDENTIFIER_NODE
              && IDENTIFIER_GLOBAL_VALUE (value)
-             && TYPE_P (IDENTIFIER_GLOBAL_VALUE (value))))
+             && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (value)) == TYPE_DECL))
        {
          ++found_type;
 
-         if ((TREE_CODE (value) != TYPENAME_TYPE && IS_AGGR_TYPE (value))
-             || TREE_CODE (value) == ENUMERAL_TYPE)
+         if (found_type == 2 && TREE_CODE (value) == IDENTIFIER_NODE)
+           {
+             if (! in_system_header)
+               cp_pedwarn ("redeclaration of C++ built-in type `%T'", value);
+             return NULL_TREE;
+           }
+
+         if (TYPE_P (value)
+             && ((TREE_CODE (value) != TYPENAME_TYPE && IS_AGGR_TYPE (value))
+                 || TREE_CODE (value) == ENUMERAL_TYPE))
            {
              my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261);
              t = value;
@@ -7194,17 +7220,7 @@ start_decl_1 (decl)
   if (type == error_mark_node)
     return;
 
-  /* If this type of object needs a cleanup, but we're not allowed to
-     add any more objects with cleanups to the current scope, create a
-     new binding level.  */
-  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
-      && current_binding_level->more_cleanups_ok == 0)
-    {
-      keep_next_level (2);
-      pushlevel (1);
-      clear_last_expr ();
-      add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
-    }
+  maybe_push_cleanup_level (type);
 
   if (initialized)
     /* Is it valid for this decl to have an initializer at all?
index 30ede1b..72702b4 100644 (file)
@@ -1359,8 +1359,12 @@ process_overload_item (parmtype, extra_Gcode)
            tree length = array_type_nelts (parmtype);
            if (TREE_CODE (length) != INTEGER_CST || flag_do_squangling)
              {
-               length = fold (build (PLUS_EXPR, TREE_TYPE (length),
-                                     length, integer_one_node));
+               if (TREE_CODE (length) == MINUS_EXPR
+                   && TREE_OPERAND (length, 1) == integer_one_node)
+                 length = TREE_OPERAND (length, 0);
+               else
+                 length = fold (build (PLUS_EXPR, TREE_TYPE (length),
+                                       length, integer_one_node));
                STRIP_NOPS (length);
              }
            build_overload_value (sizetype, length, 1);
@@ -1964,7 +1968,8 @@ hack_identifier (value, name)
     {
       if (current_class_name)
        {
-         tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 1);
+         tree fields = lookup_fnfields (TYPE_BINFO (current_class_type),
+                                        name, 1);
          if (fields == error_mark_node)
            return error_mark_node;
          if (fields)
@@ -2091,8 +2096,9 @@ hack_identifier (value, name)
   else if (TREE_CODE (value) == TREE_LIST 
           && TREE_TYPE (value) == error_mark_node)
     {
-      error ("request for member `%s' is ambiguous in multiple inheritance lattice",
-            IDENTIFIER_POINTER (name));
+      cp_error ("\
+request for member `%D' is ambiguous in multiple inheritance lattice",
+               name);
       print_candidates (value);
       return error_mark_node;
     }
index e85ec79..181a00e 100644 (file)
@@ -7930,25 +7930,28 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
    template).  */
 
 static int
-type_unification_real (tparms, targs, parms, args, subr,
-                      strict, allow_incomplete, len)
-     tree tparms, targs, parms, args;
+type_unification_real (tparms, targs, xparms, xargs, subr,
+                      strict, allow_incomplete, xlen)
+     tree tparms, targs, xparms, xargs;
      int subr;
      unification_kind_t strict;
-     int allow_incomplete, len;
+     int allow_incomplete, xlen;
 {
   tree parm, arg;
   int i;
   int ntparms = TREE_VEC_LENGTH (tparms);
   int sub_strict;
+  int saw_undeduced = 0;
+  tree parms, args;
+  int len;
 
   my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
-  my_friendly_assert (parms == NULL_TREE 
-                     || TREE_CODE (parms) == TREE_LIST, 290);
+  my_friendly_assert (xparms == NULL_TREE 
+                     || TREE_CODE (xparms) == TREE_LIST, 290);
   /* ARGS could be NULL (via a call from parse.y to
      build_x_function_call).  */
-  if (args)
-    my_friendly_assert (TREE_CODE (args) == TREE_LIST, 291);
+  if (xargs)
+    my_friendly_assert (TREE_CODE (xargs) == TREE_LIST, 291);
   my_friendly_assert (ntparms > 0, 292);
 
   switch (strict)
@@ -7974,9 +7977,14 @@ type_unification_real (tparms, targs, parms, args, subr,
       my_friendly_abort (0);
     }
 
-  if (len == 0)
+  if (xlen == 0)
     return 0;
 
+ again:
+  parms = xparms;
+  args = xargs;
+  len = xlen;
+
   while (parms
         && parms != void_list_node
         && args
@@ -8056,7 +8064,7 @@ type_unification_real (tparms, targs, parms, args, subr,
 
       /* Are we done with the interesting parms?  */
       if (--len == 0)
-       return 0;
+       goto done;
     }
   /* Fail if we've reached the end of the parm list, and more args
      are present, and the parm list isn't variadic.  */
@@ -8067,10 +8075,23 @@ type_unification_real (tparms, targs, parms, args, subr,
       && parms != void_list_node
       && TREE_PURPOSE (parms) == NULL_TREE)
     return 1;
+
+ done:
   if (!subr)
     for (i = 0; i < ntparms; i++)
       if (TREE_VEC_ELT (targs, i) == NULL_TREE)
        {
+         tree tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+
+         /* If this is an undeduced nontype parameter that depends on
+            a type parameter, try another pass; its type may have been
+            deduced from a later argument than the one from which
+            this parameter can be deduced.  */
+         if (TREE_CODE (tparm) == PARM_DECL
+             && uses_template_parms (TREE_TYPE (tparm))
+             && !saw_undeduced++)
+           goto again;
+
          if (!allow_incomplete)
            error ("incomplete type unification");
          return 2;
@@ -8742,13 +8763,17 @@ unify (tparms, targs, parm, arg, strict)
         template-parameter exactly, except that a template-argument
         deduced from an array bound may be of any integral type. 
         The non-type parameter might use already deduced type parameters.  */
-      if (same_type_p (TREE_TYPE (arg),
-                       tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE)))
-       /* OK */;
+      tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE);
+      if (same_type_p (TREE_TYPE (arg), tparm))
+         /* OK */;
       else if ((strict & UNIFY_ALLOW_INTEGER)
-              && (TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE
-                  || TREE_CODE (TREE_TYPE (parm)) == BOOLEAN_TYPE))
+              && (TREE_CODE (tparm) == INTEGER_TYPE
+                  || TREE_CODE (tparm) == BOOLEAN_TYPE))
        /* OK */;
+      else if (uses_template_parms (tparm))
+       /* We haven't deduced the type of this parameter yet.  Try again
+          later.  */
+       return 0;
       else
        return 1;
 
index 1699c32..620d759 100644 (file)
@@ -119,6 +119,7 @@ static tree bfs_walk
        PARAMS ((tree, tree (*) (tree, void *), tree (*) (tree, void *),
               void *));
 static tree lookup_field_queue_p PARAMS ((tree, void *));
+static int shared_member_p PARAMS ((tree));
 static tree lookup_field_r PARAMS ((tree, void *));
 static tree canonical_binfo PARAMS ((tree));
 static tree shared_marked_p PARAMS ((tree, void *));
@@ -1312,6 +1313,37 @@ template_self_reference_p (type, decl)
           && DECL_NAME (decl) == constructor_name (type));
 }
 
+
+/* Nonzero for a class member means that it is shared between all objects
+   of that class.
+
+   [class.member.lookup]:If the resulting set of declarations are not all
+   from sub-objects of the same type, or the set has a  nonstatic  member
+   and  includes members from distinct sub-objects, there is an ambiguity
+   and the program is ill-formed.
+
+   This function checks that T contains no nonstatic members.  */
+
+static int
+shared_member_p (t)
+     tree t;
+{
+  if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == TYPE_DECL \
+      || TREE_CODE (t) == CONST_DECL)
+    return 1;
+  if (is_overloaded_fn (t))
+    {
+      for (; t; t = OVL_NEXT (t))
+       {
+         tree fn = OVL_CURRENT (t);
+         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+           return 0;
+       }
+      return 1;
+    }
+  return 0;
+}
+
 /* DATA is really a struct lookup_field_info.  Look for a field with
    the name indicated there in BINFO.  If this function returns a
    non-NULL value it is the result of the lookup.  Called from
@@ -1392,7 +1424,7 @@ lookup_field_r (binfo, data)
      hide the old one, we might have an ambiguity.  */
   if (lfi->rval_binfo && !is_subobject_of_p (lfi->rval_binfo, binfo, lfi->type))
     {
-      if (nval == lfi->rval && SHARED_MEMBER_P (nval))
+      if (nval == lfi->rval && shared_member_p (nval))
        /* The two things are really the same.  */
        ;
       else if (is_subobject_of_p (binfo, lfi->rval_binfo, lfi->type))
index a7e71e5..c62949e 100644 (file)
@@ -261,11 +261,15 @@ friendly_abort (where, file, line, func)
      int line;
      const char *func;
 {
-  if (where > 0)
-    error ("Internal error #%d.", where);
+  if (errorcount > 0 || sorrycount > 0)
+    /* Say nothing.  */;
+  else if (where > 0)
+    {
+      error ("Internal error #%d.", where);
 
-  /* Uncount this error, so finish_abort will do the right thing.  */
-  --errorcount;
+      /* Uncount this error, so internal_error will do the right thing.  */
+      --errorcount;
+    }
 
   fancy_abort (file, line, func);
 }
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/syshdr1.C b/gcc/testsuite/g++.old-deja/g++.ext/syshdr1.C
new file mode 100644 (file)
index 0000000..69d0c7a
--- /dev/null
@@ -0,0 +1,11 @@
+// Test that we don't complain about trying to define bool or wchar_t in a
+// system header.
+
+// Special g++ Options:
+// Build don't link:
+
+# 1 "syshdr1.C"
+# 1 "syshdr1.h" 1 3
+typedef int bool;
+typedef int wchar_t;
+# 2 "syshdr1.C" 2
diff --git a/gcc/testsuite/g++.old-deja/g++.other/dtor12.C b/gcc/testsuite/g++.old-deja/g++.other/dtor12.C
new file mode 100644 (file)
index 0000000..1a9d58a
--- /dev/null
@@ -0,0 +1,15 @@
+// Test that we don't complain about calling a destructor on a const object.
+
+#include <new>
+
+struct A
+{
+  ~A() {}
+};
+
+const A a = {};
+int main()
+{
+  a.~A();
+  a.A::~A();                   // gets bogus error - const violation
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/goto4.C b/gcc/testsuite/g++.old-deja/g++.other/goto4.C
new file mode 100644 (file)
index 0000000..75461d4
--- /dev/null
@@ -0,0 +1,26 @@
+// Test that we clean up temporaries bound to references properly when
+// jumping out of their scope.
+
+int ret = 1;
+
+struct A
+{
+  ~A() { ret = 0; }
+};
+
+void f()
+{
+  if (0)
+    {
+    out:
+      return;
+    }
+  const A& a = A();
+  goto out;
+}
+
+int main()
+{
+  f();
+  return ret;
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/lookup21.C b/gcc/testsuite/g++.old-deja/g++.other/lookup21.C
new file mode 100644 (file)
index 0000000..09b3123
--- /dev/null
@@ -0,0 +1,16 @@
+// Check that we don't complain about ambiguity between the same static
+// member function in different subobjects.
+
+struct A {
+  static void f() {}
+};
+
+struct B: public A { };
+struct C: public A { };
+struct D: public B, public C { };
+
+int main()
+{
+  D d;
+  d.f();
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/deduct4.C b/gcc/testsuite/g++.old-deja/g++.pt/deduct4.C
new file mode 100644 (file)
index 0000000..b80a932
--- /dev/null
@@ -0,0 +1,11 @@
+// Test that we can deduce t even though T is deduced from a later argument.
+
+template <int I> struct A { };
+
+template <class T, T t> void f (A<t> &, T) { }
+
+int main ()
+{
+  A<42> a;
+  f (a, 24);
+}