Commit e9525111 by Mark Mitchell Committed by Mark Mitchell

re PR c++/13113 (Nice warning about &(X::m) lost)

	PR c++/13113
	* init.c (build_offset_ref): Improve error recovery for invalid
	uses of non-static member functions.

	PR c++/13854
	* cp-tree.h (cp_build_type_attribute_variant): New function.
	* class.c (build_clone): Use cp_build_type_attribute_variant.
	* decl.c (duplicate_decls): Likewise.
	* pt.c (copy_default_args_to_explicit_spec): Likewise.
	(tsubst_function_type): Likewise.
	* tree.c (build_exception_variant): Check attributes before
	concluding that two types are the same.
	(cp_build_type-attribute_variant): New method.
	* typeck.c (merge_types): Use cp_build_type_attribute_variant.

	PR c++/13907
	* call.c (convert_class_to_reference): Keep better track of
	pedantically invalid user-defined conversions.

	PR c++/13113
	* g++.old-deja/g++.mike/net36.C: Adjust error messages.

	PR c++/13854
	* g++.dg/ext/attrib13.C: New test.

	PR c++/13907
	* g++.dg/conversion/op2.C: New test.

From-SVN: r77127
parent 7c920151
2004-02-02 Mark Mitchell <mark@codesourcery.com>
PR c++/13113
* init.c (build_offset_ref): Improve error recovery for invalid
uses of non-static member functions.
PR c++/13854
* cp-tree.h (cp_build_type_attribute_variant): New function.
* class.c (build_clone): Use cp_build_type_attribute_variant.
* decl.c (duplicate_decls): Likewise.
* pt.c (copy_default_args_to_explicit_spec): Likewise.
(tsubst_function_type): Likewise.
* tree.c (build_exception_variant): Check attributes before
concluding that two types are the same.
(cp_build_type-attribute_variant): New method.
* typeck.c (merge_types): Use cp_build_type_attribute_variant.
PR c++/13907
* call.c (convert_class_to_reference): Keep better track of
pedantically invalid user-defined conversions.
2004-02-01 Giovanni Bajo <giovannibajo@gcc.gnu.org> 2004-02-01 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/13957 PR c++/13957
......
...@@ -828,15 +828,19 @@ convert_class_to_reference (tree t, tree s, tree expr) ...@@ -828,15 +828,19 @@ convert_class_to_reference (tree t, tree s, tree expr)
LOOKUP_NORMAL); LOOKUP_NORMAL);
if (cand) if (cand)
/* Build a standard conversion sequence indicating the {
binding from the reference type returned by the /* Build a standard conversion sequence indicating the
function to the desired REFERENCE_TYPE. */ binding from the reference type returned by the
cand->second_conv function to the desired REFERENCE_TYPE. */
= (direct_reference_binding cand->second_conv
(reference_type, = (direct_reference_binding
build1 (IDENTITY_CONV, (reference_type,
TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))), build1 (IDENTITY_CONV,
NULL_TREE))); TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
NULL_TREE)));
ICS_BAD_FLAG (cand->second_conv)
|= ICS_BAD_FLAG (TREE_VEC_ELT (cand->convs, 0));
}
} }
conversions = TREE_CHAIN (conversions); conversions = TREE_CHAIN (conversions);
} }
......
...@@ -3873,8 +3873,8 @@ build_clone (tree fn, tree name) ...@@ -3873,8 +3873,8 @@ build_clone (tree fn, tree name)
TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone),
exceptions); exceptions);
TREE_TYPE (clone) TREE_TYPE (clone)
= build_type_attribute_variant (TREE_TYPE (clone), = cp_build_type_attribute_variant (TREE_TYPE (clone),
TYPE_ATTRIBUTES (TREE_TYPE (fn))); TYPE_ATTRIBUTES (TREE_TYPE (fn)));
} }
/* Copy the function parameters. But, DECL_ARGUMENTS on a TEMPLATE_DECL /* Copy the function parameters. But, DECL_ARGUMENTS on a TEMPLATE_DECL
......
...@@ -4154,6 +4154,7 @@ extern tree maybe_dummy_object (tree, tree *); ...@@ -4154,6 +4154,7 @@ extern tree maybe_dummy_object (tree, tree *);
extern int is_dummy_object (tree); extern int is_dummy_object (tree);
extern const struct attribute_spec cxx_attribute_table[]; extern const struct attribute_spec cxx_attribute_table[];
extern tree make_ptrmem_cst (tree, tree); extern tree make_ptrmem_cst (tree, tree);
extern tree cp_build_type_attribute_variant (tree, tree);
extern tree cp_build_qualified_type_real (tree, int, tsubst_flags_t); extern tree cp_build_qualified_type_real (tree, int, tsubst_flags_t);
#define cp_build_qualified_type(TYPE, QUALS) \ #define cp_build_qualified_type(TYPE, QUALS) \
cp_build_qualified_type_real ((TYPE), (QUALS), tf_error | tf_warning) cp_build_qualified_type_real ((TYPE), (QUALS), tf_error | tf_warning)
......
...@@ -1266,7 +1266,7 @@ duplicate_decls (tree newdecl, tree olddecl) ...@@ -1266,7 +1266,7 @@ duplicate_decls (tree newdecl, tree olddecl)
tree attribs = (*targetm.merge_type_attributes) tree attribs = (*targetm.merge_type_attributes)
(TREE_TYPE (olddecl), type); (TREE_TYPE (olddecl), type);
type = build_type_attribute_variant (type, attribs); type = cp_build_type_attribute_variant (type, attribs);
TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = type; TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = type;
} }
......
...@@ -1559,16 +1559,20 @@ build_offset_ref (tree type, tree name, bool address_p) ...@@ -1559,16 +1559,20 @@ build_offset_ref (tree type, tree name, bool address_p)
a class derived from that class (_class.base.init_). */ a class derived from that class (_class.base.init_). */
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member)) if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member))
{ {
/* Build a representation of a the qualified name suitable
for use as the operand to "&" -- even though the "&" is
not actually present. */
member = build (OFFSET_REF, TREE_TYPE (member), decl, member);
/* In Microsoft mode, treat a non-static member function as if /* In Microsoft mode, treat a non-static member function as if
it were a pointer-to-member. */ it were a pointer-to-member. */
if (flag_ms_extensions) if (flag_ms_extensions)
{ {
member = build (OFFSET_REF, TREE_TYPE (member), decl, member);
PTRMEM_OK_P (member) = 1; PTRMEM_OK_P (member) = 1;
return build_unary_op (ADDR_EXPR, member, 0); return build_unary_op (ADDR_EXPR, member, 0);
} }
error ("invalid use of non-static member function `%D'", member); error ("invalid use of non-static member function `%D'",
return error_mark_node; TREE_OPERAND (member, 1));
return member;
} }
else if (TREE_CODE (member) == FIELD_DECL) else if (TREE_CODE (member) == FIELD_DECL)
{ {
......
...@@ -1526,8 +1526,8 @@ copy_default_args_to_explicit_spec (tree decl) ...@@ -1526,8 +1526,8 @@ copy_default_args_to_explicit_spec (tree decl)
else else
new_type = build_function_type (TREE_TYPE (old_type), new_type = build_function_type (TREE_TYPE (old_type),
new_spec_types); new_spec_types);
new_type = build_type_attribute_variant (new_type, new_type = cp_build_type_attribute_variant (new_type,
TYPE_ATTRIBUTES (old_type)); TYPE_ATTRIBUTES (old_type));
new_type = build_exception_variant (new_type, new_type = build_exception_variant (new_type,
TYPE_RAISES_EXCEPTIONS (old_type)); TYPE_RAISES_EXCEPTIONS (old_type));
TREE_TYPE (decl) = new_type; TREE_TYPE (decl) = new_type;
...@@ -6476,7 +6476,7 @@ tsubst_function_type (tree t, ...@@ -6476,7 +6476,7 @@ tsubst_function_type (tree t,
TREE_CHAIN (arg_types)); TREE_CHAIN (arg_types));
} }
fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain); fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain);
fntype = build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t)); fntype = cp_build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
return fntype; return fntype;
} }
......
...@@ -991,7 +991,8 @@ build_exception_variant (tree type, tree raises) ...@@ -991,7 +991,8 @@ build_exception_variant (tree type, tree raises)
for (; v; v = TYPE_NEXT_VARIANT (v)) for (; v; v = TYPE_NEXT_VARIANT (v))
if (TYPE_QUALS (v) == type_quals if (TYPE_QUALS (v) == type_quals
&& comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1)) && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1)
&& (*targetm.comp_type_attributes) (type, v))
return v; return v;
/* Need to build a new variant. */ /* Need to build a new variant. */
...@@ -1962,6 +1963,23 @@ make_ptrmem_cst (tree type, tree member) ...@@ -1962,6 +1963,23 @@ make_ptrmem_cst (tree type, tree member)
return ptrmem_cst; return ptrmem_cst;
} }
/* Build a variant of TYPE that has the indicated ATTRIBUTES. May
return an existing type of an appropriate type already exists. */
tree
cp_build_type_attribute_variant (tree type, tree attributes)
{
tree new_type;
new_type = build_type_attribute_variant (type, attributes);
if (TREE_CODE (new_type) == FUNCTION_TYPE
&& (TYPE_RAISES_EXCEPTIONS (new_type)
!= TYPE_RAISES_EXCEPTIONS (type)))
new_type = build_exception_variant (new_type,
TYPE_RAISES_EXCEPTIONS (type));
return new_type;
}
/* Apply FUNC to all language-specific sub-trees of TP in a pre-order /* Apply FUNC to all language-specific sub-trees of TP in a pre-order
traversal. Called from walk_tree(). */ traversal. Called from walk_tree(). */
......
...@@ -666,9 +666,9 @@ merge_types (tree t1, tree t2) ...@@ -666,9 +666,9 @@ merge_types (tree t1, tree t2)
/* Save space: see if the result is identical to one of the args. */ /* Save space: see if the result is identical to one of the args. */
if (valtype == TREE_TYPE (t1) && ! p2) if (valtype == TREE_TYPE (t1) && ! p2)
return build_type_attribute_variant (t1, attributes); return cp_build_type_attribute_variant (t1, attributes);
if (valtype == TREE_TYPE (t2) && ! p1) if (valtype == TREE_TYPE (t2) && ! p1)
return build_type_attribute_variant (t2, attributes); return cp_build_type_attribute_variant (t2, attributes);
/* Simple way if one arg fails to specify argument types. */ /* Simple way if one arg fails to specify argument types. */
if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node) if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
...@@ -676,7 +676,7 @@ merge_types (tree t1, tree t2) ...@@ -676,7 +676,7 @@ merge_types (tree t1, tree t2)
rval = build_function_type (valtype, p2); rval = build_function_type (valtype, p2);
if ((raises = TYPE_RAISES_EXCEPTIONS (t2))) if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))
rval = build_exception_variant (rval, raises); rval = build_exception_variant (rval, raises);
return build_type_attribute_variant (rval, attributes); return cp_build_type_attribute_variant (rval, attributes);
} }
raises = TYPE_RAISES_EXCEPTIONS (t1); raises = TYPE_RAISES_EXCEPTIONS (t1);
if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node) if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
...@@ -684,7 +684,7 @@ merge_types (tree t1, tree t2) ...@@ -684,7 +684,7 @@ merge_types (tree t1, tree t2)
rval = build_function_type (valtype, p1); rval = build_function_type (valtype, p1);
if (raises) if (raises)
rval = build_exception_variant (rval, raises); rval = build_exception_variant (rval, raises);
return build_type_attribute_variant (rval, attributes); return cp_build_type_attribute_variant (rval, attributes);
} }
rval = build_function_type (valtype, commonparms (p1, p2)); rval = build_function_type (valtype, commonparms (p1, p2));
...@@ -722,7 +722,7 @@ merge_types (tree t1, tree t2) ...@@ -722,7 +722,7 @@ merge_types (tree t1, tree t2)
default:; default:;
} }
return build_type_attribute_variant (t1, attributes); return cp_build_type_attribute_variant (t1, attributes);
} }
/* Return the common type of two types. /* Return the common type of two types.
......
2004-02-02 Mark Mitchell <mark@codesourcery.com>
PR c++/13113
* g++.old-deja/g++.mike/net36.C: Adjust error messages.
PR c++/13854
* g++.dg/ext/attrib13.C: New test.
PR c++/13907
* g++.dg/conversion/op2.C: New test.
2004-02-02 Eric Botcazou <ebotcazou@libertysurf.fr> 2004-02-02 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/titype-1.c: Fix pasto. * gcc.dg/titype-1.c: Fix pasto.
......
// PR c++/13907
struct A {
operator int & ();
operator const int & () const;
};
void f(int &);
void f(const int &);
int main() {
const A x = A();
f(x);
}
// PR c++/13854
extern char *rindex (__const char *__s, int __c) throw () __attribute__ ((__pure__));
extern char *rindex (__const char *__s, int __c) throw () __attribute__ ((__pure__));
...@@ -11,7 +11,7 @@ typedef void (A::*handler) (X*); ...@@ -11,7 +11,7 @@ typedef void (A::*handler) (X*);
class B { class B {
public: public:
void setHandler(handler); void setHandler(handler); // { dg-error "candidate" }
}; };
void f(B* b) { void f(B* b) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment