aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mmitchell@usa.net>1998-03-17 14:59:43 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-03-17 14:59:43 +0000
commit297dcfb3a91b4284b9fc4c4db3eb9630a0fcd465 (patch)
tree669a4605294f2e4a57c022f3a74df9735d5c02ad /gcc
parentc7dfe584801a38a984c279332c63e8fb41af4294 (diff)
downloadgcc-297dcfb3a91b4284b9fc4c4db3eb9630a0fcd465.zip
gcc-297dcfb3a91b4284b9fc4c4db3eb9630a0fcd465.tar.gz
gcc-297dcfb3a91b4284b9fc4c4db3eb9630a0fcd465.tar.bz2
typeck2.c (build_x_arrow): Don't crash when an aggregate type has no overloaded operator ->.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/call.c11
-rw-r--r--gcc/cp/decl.c15
-rw-r--r--gcc/cp/typeck2.c7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/badarrow.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/friend2.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/nested1.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/ptrmem3.C7
8 files changed, 99 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4650586..2882a29 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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,
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8cef2f9..16a6f9f 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 43a1660..4c33191 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 2a208af..5b17ae2 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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
index 0000000..e5946fd
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/badarrow.C
@@ -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
index 0000000..32a0a28
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/friend2.C
@@ -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
index 0000000..0c03856
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/nested1.C
@@ -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
index 0000000..3f6a2af
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/ptrmem3.C
@@ -0,0 +1,7 @@
+// Build don't link:
+
+class c {
+ void (c::*x)();
+public:
+ void f() { this->x(); } // ERROR - pointer-to-member
+};