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
This commit is contained in:
Mark Mitchell 1998-03-17 14:59:43 +00:00 committed by Mark Mitchell
parent c7dfe58480
commit 297dcfb3a9
8 changed files with 99 additions and 3 deletions

View 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,

View 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);

View 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);

View 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);
}

View File

@ -0,0 +1,10 @@
// Build don't link:
struct S {
int i;
} s;
void f()
{
s->i = 3; // ERROR - base operand
}

View File

@ -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;
}
};
}

View File

@ -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
}

View File

@ -0,0 +1,7 @@
// Build don't link:
class c {
void (c::*x)();
public:
void f() { this->x(); } // ERROR - pointer-to-member
};