diff options
author | Mark Mitchell <mmitchell@usa.net> | 1998-03-17 14:59:43 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1998-03-17 14:59:43 +0000 |
commit | 297dcfb3a91b4284b9fc4c4db3eb9630a0fcd465 (patch) | |
tree | 669a4605294f2e4a57c022f3a74df9735d5c02ad /gcc | |
parent | c7dfe584801a38a984c279332c63e8fb41af4294 (diff) | |
download | gcc-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/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/cp/call.c | 11 | ||||
-rw-r--r-- | gcc/cp/decl.c | 15 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/badarrow.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/friend2.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/nested1.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/ptrmem3.C | 7 |
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 +}; |