aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog21
-rw-r--r--gcc/cp/call.c22
-rw-r--r--gcc/cp/class.c4
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/cp/init.c10
-rw-r--r--gcc/cp/pt.c6
-rw-r--r--gcc/cp/tree.c20
-rw-r--r--gcc/cp/typeck.c10
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/conversion/op2.C16
-rw-r--r--gcc/testsuite/g++.dg/ext/attrib13.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net36.C2
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) {