+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,
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);
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);
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);
}
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);
}
--- /dev/null
+// Build don't link:
+
+struct S {
+ int i;
+} s;
+
+void f()
+{
+ s->i = 3; // ERROR - base operand
+}
--- /dev/null
+// 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;
+ }
+ };
+}
--- /dev/null
+// Build don't link:
+
+struct C
+{
+ struct D
+ {
+ };
+};
+
+struct E
+{
+ C& c;
+ void g();
+};
+
+void E::g()
+{
+ c.D().f(); // ERROR - no matching function
+}
--- /dev/null
+// Build don't link:
+
+class c {
+ void (c::*x)();
+public:
+ void f() { this->x(); } // ERROR - pointer-to-member
+};