diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-02-02 16:53:17 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-02-02 16:53:17 +0000 |
commit | e9525111c9a3fabe2244b57e7a6257b708b8f9f5 (patch) | |
tree | 18f97563be8180b80b8d845bab5a84a1cb6453c4 | |
parent | 7c9201514989cce06b05850f55f3bcd0e3d5e18b (diff) | |
download | gcc-e9525111c9a3fabe2244b57e7a6257b708b8f9f5.zip gcc-e9525111c9a3fabe2244b57e7a6257b708b8f9f5.tar.gz gcc-e9525111c9a3fabe2244b57e7a6257b708b8f9f5.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/cp/call.c | 22 | ||||
-rw-r--r-- | gcc/cp/class.c | 4 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 2 | ||||
-rw-r--r-- | gcc/cp/init.c | 10 | ||||
-rw-r--r-- | gcc/cp/pt.c | 6 | ||||
-rw-r--r-- | gcc/cp/tree.c | 20 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/op2.C | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/attrib13.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.mike/net36.C | 2 |
13 files changed, 104 insertions, 25 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ed2a83f..9c3d573 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,24 @@ +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> PR c++/13957 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d391b29..0aa19f1 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -828,15 +828,19 @@ convert_class_to_reference (tree t, tree s, tree expr) LOOKUP_NORMAL); if (cand) - /* Build a standard conversion sequence indicating the - binding from the reference type returned by the - function to the desired REFERENCE_TYPE. */ - cand->second_conv - = (direct_reference_binding - (reference_type, - build1 (IDENTITY_CONV, - TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))), - NULL_TREE))); + { + /* Build a standard conversion sequence indicating the + binding from the reference type returned by the + function to the desired REFERENCE_TYPE. */ + cand->second_conv + = (direct_reference_binding + (reference_type, + build1 (IDENTITY_CONV, + 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); } diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 23ca83d..96e48e4 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3873,8 +3873,8 @@ build_clone (tree fn, tree name) TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), exceptions); TREE_TYPE (clone) - = build_type_attribute_variant (TREE_TYPE (clone), - TYPE_ATTRIBUTES (TREE_TYPE (fn))); + = cp_build_type_attribute_variant (TREE_TYPE (clone), + TYPE_ATTRIBUTES (TREE_TYPE (fn))); } /* Copy the function parameters. But, DECL_ARGUMENTS on a TEMPLATE_DECL diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 0614d72..5e64578 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4154,6 +4154,7 @@ extern tree maybe_dummy_object (tree, tree *); extern int is_dummy_object (tree); extern const struct attribute_spec cxx_attribute_table[]; 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); #define cp_build_qualified_type(TYPE, QUALS) \ cp_build_qualified_type_real ((TYPE), (QUALS), tf_error | tf_warning) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a9e0316..c949c74 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1266,7 +1266,7 @@ duplicate_decls (tree newdecl, tree olddecl) tree attribs = (*targetm.merge_type_attributes) (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; } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 6f361b0..2c89996 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1559,16 +1559,20 @@ build_offset_ref (tree type, tree name, bool address_p) a class derived from that class (_class.base.init_). */ 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 it were a pointer-to-member. */ if (flag_ms_extensions) { - member = build (OFFSET_REF, TREE_TYPE (member), decl, member); PTRMEM_OK_P (member) = 1; return build_unary_op (ADDR_EXPR, member, 0); } - error ("invalid use of non-static member function `%D'", member); - return error_mark_node; + error ("invalid use of non-static member function `%D'", + TREE_OPERAND (member, 1)); + return member; } else if (TREE_CODE (member) == FIELD_DECL) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 90455bc..f035042 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1526,8 +1526,8 @@ copy_default_args_to_explicit_spec (tree decl) else new_type = build_function_type (TREE_TYPE (old_type), new_spec_types); - new_type = build_type_attribute_variant (new_type, - TYPE_ATTRIBUTES (old_type)); + new_type = cp_build_type_attribute_variant (new_type, + TYPE_ATTRIBUTES (old_type)); new_type = build_exception_variant (new_type, TYPE_RAISES_EXCEPTIONS (old_type)); TREE_TYPE (decl) = new_type; @@ -6476,7 +6476,7 @@ tsubst_function_type (tree t, TREE_CHAIN (arg_types)); } 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; } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 7d98128..3413ede 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -991,7 +991,8 @@ build_exception_variant (tree type, tree raises) for (; v; v = TYPE_NEXT_VARIANT (v)) 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; /* Need to build a new variant. */ @@ -1962,6 +1963,23 @@ make_ptrmem_cst (tree type, tree member) 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 traversal. Called from walk_tree(). */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 1338085..4f635cc 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -666,9 +666,9 @@ merge_types (tree t1, tree t2) /* Save space: see if the result is identical to one of the args. */ 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) - 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. */ if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node) @@ -676,7 +676,7 @@ merge_types (tree t1, tree t2) rval = build_function_type (valtype, p2); if ((raises = TYPE_RAISES_EXCEPTIONS (t2))) 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); if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node) @@ -684,7 +684,7 @@ merge_types (tree t1, tree t2) rval = build_function_type (valtype, p1); if (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)); @@ -722,7 +722,7 @@ merge_types (tree t1, tree t2) default:; } - return build_type_attribute_variant (t1, attributes); + return cp_build_type_attribute_variant (t1, attributes); } /* Return the common type of two types. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c33adfb..e95b301 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +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> * gcc.dg/titype-1.c: Fix pasto. diff --git a/gcc/testsuite/g++.dg/conversion/op2.C b/gcc/testsuite/g++.dg/conversion/op2.C new file mode 100644 index 0000000..b400988 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/op2.C @@ -0,0 +1,16 @@ +// 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); +} diff --git a/gcc/testsuite/g++.dg/ext/attrib13.C b/gcc/testsuite/g++.dg/ext/attrib13.C new file mode 100644 index 0000000..22ea97a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib13.C @@ -0,0 +1,4 @@ +// 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__)); diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net36.C b/gcc/testsuite/g++.old-deja/g++.mike/net36.C index 3ffa60e..98b38ee 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/net36.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/net36.C @@ -11,7 +11,7 @@ typedef void (A::*handler) (X*); class B { public: - void setHandler(handler); + void setHandler(handler); // { dg-error "candidate" } }; void f(B* b) { |