]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
typeck2.c (build_x_arrow): Don't crash when an aggregate type has no overloaded opera...
authorMark Mitchell <mmitchell@usa.net>
Tue, 17 Mar 1998 14:59:43 +0000 (14:59 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 17 Mar 1998 14:59:43 +0000 (14:59 +0000)
* typeck2.c (build_x_arrow): Don't crash when an aggregate type
has no overloaded operator ->.
* call.c (build_field_call): Don't crash when presented with a
field that is actually a nested type.
* decl.c (pushtag): Deal with friend class injection in local
classes.
* call.c (build_object_call): Don't crash if OBJ is a
pointer-to-member-function.

From-SVN: r18647

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl.c
gcc/cp/typeck2.c
gcc/testsuite/g++.old-deja/g++.other/badarrow.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/friend2.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/nested1.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/ptrmem3.C [new file with mode: 0644]

index 46505862ccddb36a3e4631836dc85e751f8a2272..2882a29877427ac626ad450c00f0a4d9cf97f8a4 100644 (file)
@@ -1,3 +1,17 @@
+Tue Mar 17 14:44:54 1998  Mark Mitchell  <mmitchell@usa.net>
+
+       * typeck2.c (build_x_arrow): Don't crash when an aggregate type
+       has no overloaded operator ->.
+
+       * call.c (build_field_call): Don't crash when presented with a
+       field that is actually a nested type.
+
+       * decl.c (pushtag): Deal with friend class injection in local
+       classes.
+
+       * call.c (build_object_call): Don't crash if OBJ is a
+       pointer-to-member-function.
+
 Tue Mar 17 11:40:26 1998  Jason Merrill  <jason@yorick.cygnus.com>
 
        * pt.c (push_template_decl): Complain about template with C linkage,
index 8cef2f9f6a61aa99e86b9df41e140989bd86eafa..16a6f9f0471aab73d864ef0e0bd2cbe571914b9b 100644 (file)
@@ -169,7 +169,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
   if (field == error_mark_node)
     return error_mark_node;
 
-  if (field)
+  if (field && TREE_CODE (field) == FIELD_DECL)
     {
       tree basetype;
       tree ftype = TREE_TYPE (field);
@@ -2277,6 +2277,15 @@ build_object_call (obj, args)
   tree type = TREE_TYPE (obj);
   tree templates = NULL_TREE;
 
+  if (TYPE_PTRMEMFUNC_P (type))
+    {
+      /* It's no good looking for an overloaded operator() on a
+        pointer-to-member-function.  */
+      cp_error ("pointer-to-member function %E cannot be called", obj);
+      cp_error ("without an object; consider using .* or ->*");
+      return error_mark_node;
+    }
+
   fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 0);
 
   args = resolve_args (args);
index 43a1660a9888c09ae808ab0bdb84cfdf8593dffe..4c33191a705fcc0e6db29670c6291fba40c77307 100644 (file)
@@ -2170,8 +2170,19 @@ pushtag (name, type, globalize)
   if (name)
     {
       context = type ? TYPE_CONTEXT (type) : NULL_TREE;
-      if (! context && ! globalize)
-        context = current_scope ();
+      if (! context)
+       {
+         tree cs = current_scope ();
+
+         if (! globalize)
+           context = cs;
+         else if (cs != NULL_TREE 
+                  && TREE_CODE_CLASS (TREE_CODE (cs)) == 't')
+           /* When declaring a friend class of a local class, we want
+              to inject the newly named class into the scope
+              containing the local class, not the namespace scope.  */
+           context = hack_decl_function_context (get_type_decl (cs));
+       }
       if (context)
        c_decl = TREE_CODE (context) == FUNCTION_DECL
          ? context : TYPE_MAIN_DECL (context);
index 2a208afd149edc55bd1ae409247619fde815ad19..5b17ae2d76fc9e86697017ead953399ee897dffb 100644 (file)
@@ -1371,6 +1371,13 @@ build_x_arrow (datum)
            }
          last_rval = rval;
        }     
+
+      if (last_rval == NULL_TREE)
+       {
+         cp_error ("base operand of `->' has non-pointer type `%T'", type);
+         return error_mark_node;
+       }
+
       if (TREE_CODE (TREE_TYPE (last_rval)) == REFERENCE_TYPE)
        last_rval = convert_from_reference (last_rval);
     }
diff --git a/gcc/testsuite/g++.old-deja/g++.other/badarrow.C b/gcc/testsuite/g++.old-deja/g++.other/badarrow.C
new file mode 100644 (file)
index 0000000..e5946fd
--- /dev/null
@@ -0,0 +1,10 @@
+// Build don't link:
+
+struct S { 
+  int i;
+} s;
+
+void f()
+{
+  s->i = 3; // ERROR - base operand
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/friend2.C b/gcc/testsuite/g++.old-deja/g++.other/friend2.C
new file mode 100644 (file)
index 0000000..32a0a28
--- /dev/null
@@ -0,0 +1,19 @@
+// Build don't link:
+
+void
+f()
+{
+  class Local_2 {
+    friend class Friend;
+
+    int i;
+  };
+  
+  class Friend {
+  public:
+    void g() {
+      Local_2 l2;
+      l2.i = 3;
+    }
+  };
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/nested1.C b/gcc/testsuite/g++.old-deja/g++.other/nested1.C
new file mode 100644 (file)
index 0000000..0c03856
--- /dev/null
@@ -0,0 +1,19 @@
+// Build don't link:
+
+struct C
+{
+  struct D
+  {
+  };
+};
+
+struct E
+{
+  C& c;
+  void g();
+};
+
+void E::g()
+{
+  c.D().f(); // ERROR - no matching function
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/ptrmem3.C b/gcc/testsuite/g++.old-deja/g++.other/ptrmem3.C
new file mode 100644 (file)
index 0000000..3f6a2af
--- /dev/null
@@ -0,0 +1,7 @@
+// Build don't link:
+
+class c {
+  void (c::*x)();
+public:
+  void f() { this->x(); } // ERROR - pointer-to-member
+};