diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 43ca3b47189..61bd1f269b1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,16 @@ 2001-01-02 Jason Merrill + * 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 10afa3203f6..b0802e1977e 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 b428a96953d..7936983c28a 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 a1089ce4018..4f55c703240 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 443fb2d4b8f..947a1dbcedd 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 00000000000..e33ee2c8e5c --- /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 00000000000..21deeb52842 --- /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; +}