aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2001-01-02 14:48:02 -0500
committerJason Merrill <jason@gcc.gnu.org>2001-01-02 14:48:02 -0500
commit96d6c6107ae89e779b41cca083c7c453f690bcc1 (patch)
treeaa36d1aa0124a5c7b635fb6c694ef78e0c12e341
parent381ddaa6e1e86b6c4b6702ee0ece25d81d19f7fa (diff)
downloadgcc-96d6c6107ae89e779b41cca083c7c453f690bcc1.zip
gcc-96d6c6107ae89e779b41cca083c7c453f690bcc1.tar.gz
gcc-96d6c6107ae89e779b41cca083c7c453f690bcc1.tar.bz2
tree.c (cp_valid_lang_attribute): Don't set CLASSTYPE_COM_INTERFACE for v3 ABI.
* tree.c (cp_valid_lang_attribute): Don't set CLASSTYPE_COM_INTERFACE for v3 ABI. * typeck.c (cp_truthvalue_conversion): New fn. * cvt.c (ocp_convert): Use it. * cp-tree.h: Lose c-common.c decls. * typeck.c (build_unary_op): Restore old &a.f diagnostic code. * cvt.c (convert_to_void): Use type_unknown_p. From-SVN: r38636
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h36
-rw-r--r--gcc/cp/cvt.c22
-rw-r--r--gcc/cp/tree.c4
-rw-r--r--gcc/cp/typeck.c38
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/pmf7.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/ptrmem10.C10
7 files changed, 85 insertions, 51 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 43ca3b4..61bd1f2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,16 @@
2001-01-02 Jason Merrill <jason@redhat.com>
+ * tree.c (cp_valid_lang_attribute): Don't set CLASSTYPE_COM_INTERFACE
+ for v3 ABI.
+
+ * typeck.c (cp_truthvalue_conversion): New fn.
+ * cvt.c (ocp_convert): Use it.
+
+ * cp-tree.h: Lose c-common.c decls.
+
+ * typeck.c (build_unary_op): Restore old &a.f diagnostic code.
+ * cvt.c (convert_to_void): Use type_unknown_p.
+
* typeck.c (strip_all_pointer_quals): Also strip quals from
pointer-to-member types.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 10afa32..b0802e1 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3190,40 +3190,6 @@ extern int warn_multichar;
flag_guiding_decls in do_friend. */
extern int warn_nontemplate_friend;
-/* in c-common.c */
-extern void declare_function_name PARAMS ((void));
-extern void decl_attributes PARAMS ((tree, tree, tree));
-extern void init_function_format_info PARAMS ((void));
-extern void record_function_format PARAMS ((tree, tree, int, int, int));
-extern void check_function_format PARAMS ((int *, tree, tree, tree));
-/* Print an error message for invalid operands to arith operation CODE.
- NOP_EXPR is used as a special case (see truthvalue_conversion). */
-extern void binary_op_error PARAMS ((enum tree_code));
-extern tree canonical_type_variant PARAMS ((tree));
-/* Validate the expression after `case' and apply default promotions. */
-extern tree check_case_value PARAMS ((tree));
-/* Concatenate a list of STRING_CST nodes into one STRING_CST. */
-extern tree combine_strings PARAMS ((tree));
-extern void constant_expression_warning PARAMS ((tree));
-extern tree convert_and_check PARAMS ((tree, tree));
-extern void overflow_warning PARAMS ((tree));
-extern void unsigned_conversion_warning PARAMS ((tree, tree));
-extern void c_apply_type_quals_to_decl PARAMS ((int, tree));
-
-/* Read the rest of the current #-directive line. */
-extern char *get_directive_line PARAMS ((void));
-#define GET_DIRECTIVE_LINE() get_directive_line ()
-
-/* Subroutine of build_binary_op, used for comparison operations.
- See if the operands have both been converted from subword integer types
- and, if so, perhaps change them both back to their original type. */
-extern tree shorten_compare PARAMS ((tree *, tree *, tree *, enum tree_code *));
-/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
- or validate its data type for an `if' or `while' statement or ?..: exp. */
-extern tree truthvalue_conversion PARAMS ((tree));
-extern tree type_for_mode PARAMS ((enum machine_mode, int));
-extern tree type_for_size PARAMS ((unsigned, int));
-
/* in decl{2}.c */
/* A node that is a list (length 1) of error_mark_nodes. */
extern tree error_mark_list;
@@ -4391,6 +4357,7 @@ extern tree frob_opname PARAMS ((tree));
/* in tree.c */
extern void init_tree PARAMS ((void));
extern int pod_type_p PARAMS ((tree));
+extern tree canonical_type_variant PARAMS ((tree));
extern void unshare_base_binfos PARAMS ((tree));
extern int member_p PARAMS ((tree));
extern cp_lvalue_kind real_lvalue_p PARAMS ((tree));
@@ -4470,6 +4437,7 @@ extern linkage_kind decl_linkage PARAMS ((tree));
/* in typeck.c */
extern int string_conv_p PARAMS ((tree, tree, int));
+extern tree cp_truthvalue_conversion PARAMS ((tree));
extern tree condition_conversion PARAMS ((tree));
extern tree target_type PARAMS ((tree));
extern tree require_complete_type PARAMS ((tree));
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index b428a96..7936983 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -787,7 +787,7 @@ ocp_convert (type, expr, convtype, flags)
fn = TREE_OPERAND (expr, 0);
if (fn)
cp_warning ("the address of `%D', will always be `true'", fn);
- return truthvalue_conversion (e);
+ return cp_truthvalue_conversion (e);
}
return fold (convert_to_integer (type, e));
}
@@ -976,19 +976,17 @@ convert_to_void (expr, implicit)
if (TREE_CODE (probe) == ADDR_EXPR)
probe = TREE_OPERAND (expr, 0);
- if (!is_overloaded_fn (probe))
- ;/* OK */
- else if (really_overloaded_fn (probe))
- {
- /* [over.over] enumerates the places where we can take the address
- of an overloaded function, and this is not one of them. */
- cp_pedwarn ("%s has no context for overloaded function name `%E'",
- implicit ? implicit : "void cast", expr);
- }
- else if (implicit && probe == expr)
+ if (type_unknown_p (probe))
+ {
+ /* [over.over] enumerates the places where we can take the address
+ of an overloaded function, and this is not one of them. */
+ cp_pedwarn ("%s cannot resolve address of overloaded function",
+ implicit ? implicit : "void cast");
+ }
+ else if (implicit && probe == expr && is_overloaded_fn (probe))
/* Only warn when there is no &. */
cp_warning ("%s is a reference, not call, to function `%E'",
- implicit, expr);
+ implicit, expr);
}
if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a1089ce..4f55c70 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2259,7 +2259,9 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type)
return 0;
}
- CLASSTYPE_COM_INTERFACE (type) = 1;
+ if (!flag_new_abi)
+ /* The v3 ABI is already COM compliant; don't set this flag. */
+ CLASSTYPE_COM_INTERFACE (type) = 1;
return 1;
}
else if (is_attribute_p ("init_priority", attr_name))
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 443fb2d..947a1db 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4348,7 +4348,21 @@ build_x_unary_op (code, xarg)
return exp;
}
-/* Just like truthvalue_conversion, but we want a CLEANUP_POINT_EXPR. */
+/* Like truthvalue_conversion, but handle pointer-to-member constants, where
+ a null value is represented by an INTEGER_CST of -1. */
+
+tree
+cp_truthvalue_conversion (expr)
+ tree expr;
+{
+ tree type = TREE_TYPE (expr);
+ if (TYPE_PTRMEM_P (type))
+ return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
+ else
+ return truthvalue_conversion (expr);
+}
+
+/* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR. */
tree
condition_conversion (expr)
@@ -4682,15 +4696,31 @@ build_unary_op (code, xarg, noconvert)
return build1 (ADDR_EXPR, unknown_type_node, arg);
}
- if (TREE_CODE (arg) == COMPONENT_REF && flag_ms_extensions
- && type_unknown_p (arg)
+ if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
&& OVL_NEXT (TREE_OPERAND (arg, 1)) == NULL_TREE)
{
/* They're trying to take the address of a unique non-static
- member function. This is ill-formed, except in microsoft-land. */
+ member function. This is ill-formed (except in MS-land),
+ but let's try to DTRT.
+ Note: We only handle unique functions here because we don't
+ want to complain if there's a static overload; non-unique
+ cases will be handled by instantiate_type. But we need to
+ handle this case here to allow casts on the resulting PMF.
+ We could defer this in non-MS mode, but it's easier to give
+ a useful error here. */
tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
tree name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
+
+ if (! flag_ms_extensions)
+ {
+ if (current_class_type
+ && TREE_OPERAND (arg, 0) == current_class_ref)
+ /* An expression like &memfn. */
+ cp_pedwarn ("ISO C++ forbids taking the address of a non-static member function to form a pointer to member function. Say `&%T::%D'", base, name);
+ else
+ cp_pedwarn ("ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say `&%T::%D'", base, name);
+ }
arg = build_offset_ref (base, name);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/pmf7.C b/gcc/testsuite/g++.old-deja/g++.other/pmf7.C
new file mode 100644
index 0000000..e33ee2c
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/pmf7.C
@@ -0,0 +1,15 @@
+// Test for proper diagnostics on trying to take the address of a non-static
+// member function.
+
+struct A {
+ void f ();
+ void f (int);
+ void g ();
+};
+
+int main ()
+{
+ A a;
+ &a.f; // ERROR - overloaded
+ &a.g; // ERROR - can't write a pmf like this
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/ptrmem10.C b/gcc/testsuite/g++.old-deja/g++.other/ptrmem10.C
new file mode 100644
index 0000000..21deeb5
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/ptrmem10.C
@@ -0,0 +1,10 @@
+// Test that we properly convert a constant ptm to bool.
+
+class A { };
+
+int main()
+{
+ int A::*const p = 0;
+ if (p)
+ return 1;
+}