typeck.c (composite_pointer_type_r): Add SFINAE support.
2008-03-25 Douglas Gregor <doug.gregor@gmail.com> * typeck.c (composite_pointer_type_r): Add SFINAE support. (composite_pointer_type): Ditto. (common_type): Fix call to composite_pointer_type. (cxx_sizeof_nowarn): New; used to be a macro. (cxx_sizeof_expr): Add SFINAE support. (cxx_alignof_expr): Ditto. (decay_conversion): Fix calls for SFINAE support. (rationalize_conditional_expr): Add SFINAE support. (build_class_member_access_expr): Ditto. (finish_class_member_access_expr): Ditto. (build_x_indirect_ref): Ditto. (build_indirect_ref): Original version renamed to cp_build_indirect_ref; new version provides a bridge from c-common. (cp_build_indirect_ref): Was build_indirect_ref; added SFINAE support. (get_member_function_from_ptrfunc): Fix calls for SFINAE support. (build_function_call): Original version renamed to cp_build_function_call; new version provides a bridge from c-common. (cp_build_function_call): Was build_function_call; added SFINAE support. (convert_arguments): Add SFINAE support. (build_x_binary_op): Ditto. (build_binary_op): Original version renamed to cp_build_binary_op; new version provides a bridge from c-common. (cp_build_binary_op): Was build_binary_op; added SFINAE support. (pointer_diff): Fix calls for SFINAE. (build_x_unary_op): Add SFINAE support. (condition_conversion): Fix calls for SFINAE. (build_unary_op): Original version renamed to cp_build_unary_op; new version provides a bridge from c-common. (cp_build_unary_op): Was build_unary_op; added SFINAE support. (unary_complex_lvalue): Fix calls for SFINAE. (build_x_conditional_expr): Add SFINAE support. (build_x_compound_expr_from_list): Fix calls for SFINAE. (build_x_compound_expr): Add SFINAE support. (convert_ptrmem): Fix calls for SFINAE. (build_static_cast_1): Add SFINAE support. (build_static_cast): Ditto. (build_reinterpret_cast_1): Ditto. (build_reinterpret_cast): Ditto. (build_const_cast_1): Ditto. (build_const_cast): Ditto. (build_c_cast): Ditto. (build_modify_expr): Original version renamed to cp_build_modify_expr; new version provides a bridge from c-common. (cp_build_modify_expr): Was build_modify_expr; added SFINAE support. (build_x_modify_expr): Add SFINAE support. (build_ptrmemfunc): Fix calls for SFINAE. (convert_for_assignment): Add SFINAE support. (convert_for_initialization): Ditto. (check_return_expr): Fix calls for SFINAE. (lvalue_or_else): Add SFINAE support. * init.c (perform_member_init): Fix calls for SFINAE. (emit_mem_initializers): Ditto. (expand_virtual_init): Ditto. (expand_cleanup_for_base): Ditto. (build_aggr_init): Add SFINAE support. (expand_default_init): Ditto. (expand_aggr_init_1): Fix calls for SFINAE. (build_offset_ref): Ditto. (build_new_1): Add SFINAE support. (build_new): Ditto. (build_vec_delete_1): Fix calls for SFINAE. (get_temp_regvar): Ditto. (build_vec_init): Add SFINAE support. (build_dtor_call): Fix calls for SFINAE. (build_delete): Ditto. (push_base_cleanups): Ditto. (build_vec_delete_1): Ditto. * class.c (build_base_path): Fix calls for SFINAE. (build_simple_base_path): Ditto. (convert_to_base_statically): Ditto. (build_vfn_ref): Ditto. (resolve_address_of_overloaded_function): Ditto. * decl.c (check_initializer): Fix calls for SFINAE. (register_dtor_fn): Ditto. (compute_array_index_type): Ditto. (finish_enum): Ditto. (start_preparsed_function): Ditto. (cxx_maybe_build_cleanup): Ditto. * call.c (convert_like): Add COMPLAIN argument. (convert_like_with_context): Ditto. (build_this): Fix calls for SFINAE. (build_user_type_conversion): Ditto. (resolve_args): Ditto. (build_new_function_call): Add SFINAE support. (build_operator_new_call): Fix calls for SFINAE. (build_object_call): Add SFINAE support. (build_conditional_expr): Ditto. (build_new_op): Ditto. (build_op_delete_call): Fix calls for SFINAE. (build_temp): Ditto. (convert_like_real): Add SFINAE support. (build_x_va_arg): Fix calls for SFINAE. (convert_default_arg): Ditto. (build_over_call): Add SFINAE support. (build_java_interface_fn_ref): Fix calls for SFINAE. (build_special_member_call): Add SFINAE support. (build_new_method_call): Ditto. (perform_implicit_conversion): Ditto. (perform_direct_initialization_if_possible): Ditto. (initialize_reference): Fix calls for SFINAE. * method.c (do_build_assign_ref): Fix calls for SFINAE. * rtti.c (build_headof): Fix calls for SFINAE. (get_tinfo_decl_dynamic): Ditto. (get_typeid): Ditto. (build_dynamic_cast_1): Add SFINAE support. (build_dynamic_cast): Ditto. (tinfo_base_init): Fix calls for SFINAE. * except.c (do_get_exception_ptr): Fix calls for SFINAE. (do_end_catch): Ditto. (initialize_handler_parm): Ditto. (expand_start_catch_block): Ditto. (do_allocate_exception): Ditto. (do_free_exception): Ditto. (build_throw): Ditto. * cvt.c (build_up_reference): Fix calls for SFINAE. (convert_to_reference): Ditto. (ocp_convert): Ditto. (convert_to_void): Add SFINAE support. * tree.c (build_dummy_object): Fix calls for SFINAE. (stabilize_expr): Ditto. * cp-tree.h (build_conditional_expr): Add tsubst_flags_t parameter. (build_new_method_call): Ditto. (build_special_member_call): Ditto. (build_new_op): Ditto. (perform_implicit_conversion): Ditto. (perform_direct_initialization_if_possible): Ditto. (convert_to_void): Ditto. (build_aggr_init): Ditto. (build_new): Ditto. (build_vec_init): Ditto. (build_dynamic_cast): Ditto. (finish_call_expr): Ditto (cxx_sizeof_or_alignof_expr): Add COMPLAIN parameter. (cxx_sizeof_nowarn): Remove macro; add function declaration. (build_class_member_access_expr): Add tsubst_flags_t parameter. (finish_class_member_access_expr): Ditto. (build_x_indirect_ref): Ditto. (cp_build_indirect_ref): New. (cp_build_function_call): Add tsubst_flags_t parameter. (build_x_unary_op): Ditto. (cp_build_unary_op): New. (build_x_conditional_expr): Add tsubst_flags_t parameter. (build_x_compound_expr): Ditto. (build_compound_expr): Ditto. (build_static_cast): Ditto. (build_reinterpret_cast): Ditto. (build_const_cast): Ditto. (build_c_cast): Ditto. (build_x_modify_expr): Ditto. (cp_build_modify_expr): New. (convert_for_initialization): Add tsubst_flags_t parameter. (cp_build_binary_op): Remove macro; add function declaration. (invalid_nonstatic_memfn_p): Add tsubst_flags_t parameter. (lvalue_or_else): Ditto. (build_functional_cast): Ditto. * typeck2.c (digest_init): Fix calls for SFINAE. (process_init_constructor_array): Ditto. (process_init_constructor_record): Ditto. (build_x_arrow): Ditto. (build_m_component_ref): Ditto. (build_functional_cast): Add SFINAE support. * pt.c (tsubst_copy_and_build): Add (more) SFINAE support. * semantics.c (simplify_loop_decl_cond): Fix calls for SFINAE. (finish_expr_stmt): Ditto. (finish_for_expr): Ditto. (finish_asm_stmt): Ditto. (finish_non_static_data_member): Ditto. (finish_qualified_id_expr): Ditto. (finish_call_expr): Add SFINAE support. (finish_increment_expr): Fix calls for SFINAE. (finish_unary_op_expr): Ditto. (simplify_aggr_init_expr): Ditto. (finish_omp_clauses): Ditto. (finish_omp_for): Ditto. (finish_omp_barrier): Ditto. (finish_omo_flush): Ditto. * decl2.c (grok_array_decl): Fix calls or SFINAE. (build_anon_union_vars): Ditto. (get_guard_cond): Ditto. (set_guard): Ditto. (one_static_initialization_or_destruction): Ditto. (do_static_initialization_or_destruction): Ditto. (generate_ctor_or_dtor_function): Ditto. (build_offset_ref_call_from_tree): Ditto. * parser.c (cp_parser_postfix_expression): Fix calls for SFINAE. (cp_parser_postfix_dot_deref_expression): Ditto. (cp_parser_unary_expression): Ditto. (cp_parser_new_expression): Ditto. (cp_parser_cast_expression): Ditto. (cp_parser_binary_expression): Ditto. (cp_parser_question_colon_clause): Ditto. (cp_parser_assignment_expression): Ditto. (cp_parser_expression): Ditto. (cp_parser_builtin_offsetof): Ditto. (cp_parser_template_argument): Ditto. (cp_parser_functional_cast): Ditto. 2008-03-25 Douglas Gregor <doug.gregor@gmail.com> * c-common.c (c_sizeof_or_alignof_type): If we're not allowed to complain when we hit an error, return ERROR_MARK_NODE. 2008-03-25 Douglas Gregor <doug.gregor@gmail.com> * g++.dg/template/sfinae4.C: New. * g++.dg/template/sfinae5.C: New. * g++.dg/template/sfinae6.C: New. * g++.dg/template/sfinae6_neg.C: New. * g++.dg/template/sfinae7.C: New. * g++.dg/template/sfinae8.C: New. * g++.dg/template/sfinae9.C: New. * g++.dg/template/sfinae10.C: New. * g++.dg/template/sfinae11.C: New. * g++.dg/template/sfinae12.C: New. * g++.dg/template/sfinae13.C: New. * g++.dg/template/sfinae14C: New. From-SVN: r133519
This commit is contained in:
parent
de6adfa2f4
commit
5ade1ed2c0
|
@ -1,3 +1,8 @@
|
|||
2008-03-25 Douglas Gregor <doug.gregor@gmail.com>
|
||||
|
||||
* c-common.c (c_sizeof_or_alignof_type): If we're not allowed to
|
||||
complain when we hit an error, return ERROR_MARK_NODE.
|
||||
|
||||
2008-03-25 Naveen.H.S <naveen.hs@kpitcummins.com>
|
||||
|
||||
* config/sh/constraints.md (Pso, Psz): New constraints.
|
||||
|
|
|
@ -3347,6 +3347,8 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
|
|||
{
|
||||
if (complain && (pedantic || warn_pointer_arith))
|
||||
pedwarn ("invalid application of %<sizeof%> to a function type");
|
||||
else if (!complain)
|
||||
return error_mark_node;
|
||||
value = size_one_node;
|
||||
}
|
||||
else
|
||||
|
@ -3357,6 +3359,8 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
|
|||
if (type_code == VOID_TYPE
|
||||
&& complain && (pedantic || warn_pointer_arith))
|
||||
pedwarn ("invalid application of %qs to a void type", op_name);
|
||||
else if (!complain)
|
||||
return error_mark_node;
|
||||
value = size_one_node;
|
||||
}
|
||||
else if (!COMPLETE_TYPE_P (type))
|
||||
|
|
205
gcc/cp/ChangeLog
205
gcc/cp/ChangeLog
|
@ -1,3 +1,208 @@
|
|||
2008-03-25 Douglas Gregor <doug.gregor@gmail.com>
|
||||
|
||||
* typeck.c (composite_pointer_type_r): Add SFINAE support.
|
||||
(composite_pointer_type): Ditto.
|
||||
(common_type): Fix call to composite_pointer_type.
|
||||
(cxx_sizeof_nowarn): New; used to be a macro.
|
||||
(cxx_sizeof_expr): Add SFINAE support.
|
||||
(cxx_alignof_expr): Ditto.
|
||||
(decay_conversion): Fix calls for SFINAE support.
|
||||
(rationalize_conditional_expr): Add SFINAE support.
|
||||
(build_class_member_access_expr): Ditto.
|
||||
(finish_class_member_access_expr): Ditto.
|
||||
(build_x_indirect_ref): Ditto.
|
||||
(build_indirect_ref): Original version renamed to
|
||||
cp_build_indirect_ref; new version provides a bridge from
|
||||
c-common.
|
||||
(cp_build_indirect_ref): Was build_indirect_ref; added SFINAE
|
||||
support.
|
||||
(get_member_function_from_ptrfunc): Fix calls for SFINAE support.
|
||||
(build_function_call): Original version renamed to
|
||||
cp_build_function_call; new version provides a bridge from
|
||||
c-common.
|
||||
(cp_build_function_call): Was build_function_call; added SFINAE
|
||||
support.
|
||||
(convert_arguments): Add SFINAE support.
|
||||
(build_x_binary_op): Ditto.
|
||||
(build_binary_op): Original version renamed to cp_build_binary_op;
|
||||
new version provides a bridge from c-common.
|
||||
(cp_build_binary_op): Was build_binary_op; added SFINAE support.
|
||||
(pointer_diff): Fix calls for SFINAE.
|
||||
(build_x_unary_op): Add SFINAE support.
|
||||
(condition_conversion): Fix calls for SFINAE.
|
||||
(build_unary_op): Original version renamed to cp_build_unary_op;
|
||||
new version provides a bridge from c-common.
|
||||
(cp_build_unary_op): Was build_unary_op; added SFINAE support.
|
||||
(unary_complex_lvalue): Fix calls for SFINAE.
|
||||
(build_x_conditional_expr): Add SFINAE support.
|
||||
(build_x_compound_expr_from_list): Fix calls for SFINAE.
|
||||
(build_x_compound_expr): Add SFINAE support.
|
||||
(convert_ptrmem): Fix calls for SFINAE.
|
||||
(build_static_cast_1): Add SFINAE support.
|
||||
(build_static_cast): Ditto.
|
||||
(build_reinterpret_cast_1): Ditto.
|
||||
(build_reinterpret_cast): Ditto.
|
||||
(build_const_cast_1): Ditto.
|
||||
(build_const_cast): Ditto.
|
||||
(build_c_cast): Ditto.
|
||||
(build_modify_expr): Original version renamed to
|
||||
cp_build_modify_expr; new version provides a bridge from c-common.
|
||||
(cp_build_modify_expr): Was build_modify_expr; added SFINAE
|
||||
support.
|
||||
(build_x_modify_expr): Add SFINAE support.
|
||||
(build_ptrmemfunc): Fix calls for SFINAE.
|
||||
(convert_for_assignment): Add SFINAE support.
|
||||
(convert_for_initialization): Ditto.
|
||||
(check_return_expr): Fix calls for SFINAE.
|
||||
(lvalue_or_else): Add SFINAE support.
|
||||
* init.c (perform_member_init): Fix calls for SFINAE.
|
||||
(emit_mem_initializers): Ditto.
|
||||
(expand_virtual_init): Ditto.
|
||||
(expand_cleanup_for_base): Ditto.
|
||||
(build_aggr_init): Add SFINAE support.
|
||||
(expand_default_init): Ditto.
|
||||
(expand_aggr_init_1): Fix calls for SFINAE.
|
||||
(build_offset_ref): Ditto.
|
||||
(build_new_1): Add SFINAE support.
|
||||
(build_new): Ditto.
|
||||
(build_vec_delete_1): Fix calls for SFINAE.
|
||||
(get_temp_regvar): Ditto.
|
||||
(build_vec_init): Add SFINAE support.
|
||||
(build_dtor_call): Fix calls for SFINAE.
|
||||
(build_delete): Ditto.
|
||||
(push_base_cleanups): Ditto.
|
||||
(build_vec_delete_1): Ditto.
|
||||
* class.c (build_base_path): Fix calls for SFINAE.
|
||||
(build_simple_base_path): Ditto.
|
||||
(convert_to_base_statically): Ditto.
|
||||
(build_vfn_ref): Ditto.
|
||||
(resolve_address_of_overloaded_function): Ditto.
|
||||
* decl.c (check_initializer): Fix calls for SFINAE.
|
||||
(register_dtor_fn): Ditto.
|
||||
(compute_array_index_type): Ditto.
|
||||
(finish_enum): Ditto.
|
||||
(start_preparsed_function): Ditto.
|
||||
(cxx_maybe_build_cleanup): Ditto.
|
||||
* call.c (convert_like): Add COMPLAIN argument.
|
||||
(convert_like_with_context): Ditto.
|
||||
(build_this): Fix calls for SFINAE.
|
||||
(build_user_type_conversion): Ditto.
|
||||
(resolve_args): Ditto.
|
||||
(build_new_function_call): Add SFINAE support.
|
||||
(build_operator_new_call): Fix calls for SFINAE.
|
||||
(build_object_call): Add SFINAE support.
|
||||
(build_conditional_expr): Ditto.
|
||||
(build_new_op): Ditto.
|
||||
(build_op_delete_call): Fix calls for SFINAE.
|
||||
(build_temp): Ditto.
|
||||
(convert_like_real): Add SFINAE support.
|
||||
(build_x_va_arg): Fix calls for SFINAE.
|
||||
(convert_default_arg): Ditto.
|
||||
(build_over_call): Add SFINAE support.
|
||||
(build_java_interface_fn_ref): Fix calls for SFINAE.
|
||||
(build_special_member_call): Add SFINAE support.
|
||||
(build_new_method_call): Ditto.
|
||||
(perform_implicit_conversion): Ditto.
|
||||
(perform_direct_initialization_if_possible): Ditto.
|
||||
(initialize_reference): Fix calls for SFINAE.
|
||||
* method.c (do_build_assign_ref): Fix calls for SFINAE.
|
||||
* rtti.c (build_headof): Fix calls for SFINAE.
|
||||
(get_tinfo_decl_dynamic): Ditto.
|
||||
(get_typeid): Ditto.
|
||||
(build_dynamic_cast_1): Add SFINAE support.
|
||||
(build_dynamic_cast): Ditto.
|
||||
(tinfo_base_init): Fix calls for SFINAE.
|
||||
* except.c (do_get_exception_ptr): Fix calls for SFINAE.
|
||||
(do_end_catch): Ditto.
|
||||
(initialize_handler_parm): Ditto.
|
||||
(expand_start_catch_block): Ditto.
|
||||
(do_allocate_exception): Ditto.
|
||||
(do_free_exception): Ditto.
|
||||
(build_throw): Ditto.
|
||||
* cvt.c (build_up_reference): Fix calls for SFINAE.
|
||||
(convert_to_reference): Ditto.
|
||||
(ocp_convert): Ditto.
|
||||
(convert_to_void): Add SFINAE support.
|
||||
* tree.c (build_dummy_object): Fix calls for SFINAE.
|
||||
(stabilize_expr): Ditto.
|
||||
* cp-tree.h (build_conditional_expr): Add tsubst_flags_t
|
||||
parameter.
|
||||
(build_new_method_call): Ditto.
|
||||
(build_special_member_call): Ditto.
|
||||
(build_new_op): Ditto.
|
||||
(perform_implicit_conversion): Ditto.
|
||||
(perform_direct_initialization_if_possible): Ditto.
|
||||
(convert_to_void): Ditto.
|
||||
(build_aggr_init): Ditto.
|
||||
(build_new): Ditto.
|
||||
(build_vec_init): Ditto.
|
||||
(build_dynamic_cast): Ditto.
|
||||
(finish_call_expr): Ditto
|
||||
(cxx_sizeof_or_alignof_expr): Add COMPLAIN parameter.
|
||||
(cxx_sizeof_nowarn): Remove macro; add function declaration.
|
||||
(build_class_member_access_expr): Add tsubst_flags_t parameter.
|
||||
(finish_class_member_access_expr): Ditto.
|
||||
(build_x_indirect_ref): Ditto.
|
||||
(cp_build_indirect_ref): New.
|
||||
(cp_build_function_call): Add tsubst_flags_t parameter.
|
||||
(build_x_unary_op): Ditto.
|
||||
(cp_build_unary_op): New.
|
||||
(build_x_conditional_expr): Add tsubst_flags_t parameter.
|
||||
(build_x_compound_expr): Ditto.
|
||||
(build_compound_expr): Ditto.
|
||||
(build_static_cast): Ditto.
|
||||
(build_reinterpret_cast): Ditto.
|
||||
(build_const_cast): Ditto.
|
||||
(build_c_cast): Ditto.
|
||||
(build_x_modify_expr): Ditto.
|
||||
(cp_build_modify_expr): New.
|
||||
(convert_for_initialization): Add tsubst_flags_t parameter.
|
||||
(cp_build_binary_op): Remove macro; add function declaration.
|
||||
(invalid_nonstatic_memfn_p): Add tsubst_flags_t parameter.
|
||||
(lvalue_or_else): Ditto.
|
||||
(build_functional_cast): Ditto.
|
||||
* typeck2.c (digest_init): Fix calls for SFINAE.
|
||||
(process_init_constructor_array): Ditto.
|
||||
(process_init_constructor_record): Ditto.
|
||||
(build_x_arrow): Ditto.
|
||||
(build_m_component_ref): Ditto.
|
||||
(build_functional_cast): Add SFINAE support.
|
||||
* pt.c (tsubst_copy_and_build): Add (more) SFINAE support.
|
||||
* semantics.c (simplify_loop_decl_cond): Fix calls for SFINAE.
|
||||
(finish_expr_stmt): Ditto.
|
||||
(finish_for_expr): Ditto.
|
||||
(finish_asm_stmt): Ditto.
|
||||
(finish_non_static_data_member): Ditto.
|
||||
(finish_qualified_id_expr): Ditto.
|
||||
(finish_call_expr): Add SFINAE support.
|
||||
(finish_increment_expr): Fix calls for SFINAE.
|
||||
(finish_unary_op_expr): Ditto.
|
||||
(simplify_aggr_init_expr): Ditto.
|
||||
(finish_omp_clauses): Ditto.
|
||||
(finish_omp_for): Ditto.
|
||||
(finish_omp_barrier): Ditto.
|
||||
(finish_omo_flush): Ditto.
|
||||
* decl2.c (grok_array_decl): Fix calls or SFINAE.
|
||||
(build_anon_union_vars): Ditto.
|
||||
(get_guard_cond): Ditto.
|
||||
(set_guard): Ditto.
|
||||
(one_static_initialization_or_destruction): Ditto.
|
||||
(do_static_initialization_or_destruction): Ditto.
|
||||
(generate_ctor_or_dtor_function): Ditto.
|
||||
(build_offset_ref_call_from_tree): Ditto.
|
||||
* parser.c (cp_parser_postfix_expression): Fix calls for SFINAE.
|
||||
(cp_parser_postfix_dot_deref_expression): Ditto.
|
||||
(cp_parser_unary_expression): Ditto.
|
||||
(cp_parser_new_expression): Ditto.
|
||||
(cp_parser_cast_expression): Ditto.
|
||||
(cp_parser_binary_expression): Ditto.
|
||||
(cp_parser_question_colon_clause): Ditto.
|
||||
(cp_parser_assignment_expression): Ditto.
|
||||
(cp_parser_expression): Ditto.
|
||||
(cp_parser_builtin_offsetof): Ditto.
|
||||
(cp_parser_template_argument): Ditto.
|
||||
(cp_parser_functional_cast): Ditto.
|
||||
|
||||
2008-03-24 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* lex.c (handle_pragma_interface): Don't copy the filename.
|
||||
|
|
429
gcc/cp/call.c
429
gcc/cp/call.c
|
@ -126,21 +126,21 @@ static struct z_candidate * tourney (struct z_candidate *);
|
|||
static int equal_functions (tree, tree);
|
||||
static int joust (struct z_candidate *, struct z_candidate *, bool);
|
||||
static int compare_ics (conversion *, conversion *);
|
||||
static tree build_over_call (struct z_candidate *, int);
|
||||
static tree build_over_call (struct z_candidate *, int, tsubst_flags_t);
|
||||
static tree build_java_interface_fn_ref (tree, tree);
|
||||
#define convert_like(CONV, EXPR) \
|
||||
#define convert_like(CONV, EXPR, COMPLAIN) \
|
||||
convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0, \
|
||||
/*issue_conversion_warnings=*/true, \
|
||||
/*c_cast_p=*/false)
|
||||
#define convert_like_with_context(CONV, EXPR, FN, ARGNO) \
|
||||
convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0, \
|
||||
/*issue_conversion_warnings=*/true, \
|
||||
/*c_cast_p=*/false)
|
||||
/*c_cast_p=*/false, (COMPLAIN))
|
||||
#define convert_like_with_context(CONV, EXPR, FN, ARGNO, COMPLAIN ) \
|
||||
convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0, \
|
||||
/*issue_conversion_warnings=*/true, \
|
||||
/*c_cast_p=*/false, (COMPLAIN))
|
||||
static tree convert_like_real (conversion *, tree, tree, int, int, bool,
|
||||
bool);
|
||||
bool, tsubst_flags_t);
|
||||
static void op_error (enum tree_code, enum tree_code, tree, tree,
|
||||
tree, const char *);
|
||||
static tree build_object_call (tree, tree);
|
||||
static tree build_object_call (tree, tree, tsubst_flags_t);
|
||||
static tree resolve_args (tree);
|
||||
static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
|
||||
static void print_z_candidate (const char *, struct z_candidate *);
|
||||
|
@ -2418,7 +2418,7 @@ build_this (tree obj)
|
|||
if (processing_template_decl)
|
||||
return build_address (obj);
|
||||
|
||||
return build_unary_op (ADDR_EXPR, obj, 0);
|
||||
return cp_build_unary_op (ADDR_EXPR, obj, 0, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Returns true iff functions are equivalent. Equivalent functions are
|
||||
|
@ -2750,7 +2750,7 @@ build_user_type_conversion (tree totype, tree expr, int flags)
|
|||
{
|
||||
if (cand->second_conv->kind == ck_ambig)
|
||||
return error_mark_node;
|
||||
expr = convert_like (cand->second_conv, expr);
|
||||
expr = convert_like (cand->second_conv, expr, tf_warning_or_error);
|
||||
return convert_from_reference (expr);
|
||||
}
|
||||
return NULL_TREE;
|
||||
|
@ -2773,7 +2773,7 @@ resolve_args (tree args)
|
|||
error ("invalid use of void expression");
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (invalid_nonstatic_memfn_p (arg))
|
||||
else if (invalid_nonstatic_memfn_p (arg, tf_warning_or_error))
|
||||
return error_mark_node;
|
||||
}
|
||||
return args;
|
||||
|
@ -2837,7 +2837,8 @@ perform_overload_resolution (tree fn,
|
|||
or a static member function) with the ARGS. */
|
||||
|
||||
tree
|
||||
build_new_function_call (tree fn, tree args, bool koenig_p)
|
||||
build_new_function_call (tree fn, tree args, bool koenig_p,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
struct z_candidate *candidates, *cand;
|
||||
bool any_viable_p;
|
||||
|
@ -2858,8 +2859,9 @@ build_new_function_call (tree fn, tree args, bool koenig_p)
|
|||
fn = remove_hidden_names (fn);
|
||||
if (!fn)
|
||||
{
|
||||
error ("no matching function for call to %<%D(%A)%>",
|
||||
DECL_NAME (OVL_CURRENT (orig_fn)), args);
|
||||
if (complain & tf_error)
|
||||
error ("no matching function for call to %<%D(%A)%>",
|
||||
DECL_NAME (OVL_CURRENT (orig_fn)), args);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
|
@ -2871,22 +2873,25 @@ build_new_function_call (tree fn, tree args, bool koenig_p)
|
|||
|
||||
if (!cand)
|
||||
{
|
||||
if (!any_viable_p && candidates && ! candidates->next)
|
||||
return build_function_call (candidates->fn, args);
|
||||
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
|
||||
fn = TREE_OPERAND (fn, 0);
|
||||
if (!any_viable_p)
|
||||
error ("no matching function for call to %<%D(%A)%>",
|
||||
DECL_NAME (OVL_CURRENT (fn)), args);
|
||||
else
|
||||
error ("call of overloaded %<%D(%A)%> is ambiguous",
|
||||
DECL_NAME (OVL_CURRENT (fn)), args);
|
||||
if (candidates)
|
||||
print_z_candidates (candidates);
|
||||
if (complain & tf_error)
|
||||
{
|
||||
if (!any_viable_p && candidates && ! candidates->next)
|
||||
return cp_build_function_call (candidates->fn, args, complain);
|
||||
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
|
||||
fn = TREE_OPERAND (fn, 0);
|
||||
if (!any_viable_p)
|
||||
error ("no matching function for call to %<%D(%A)%>",
|
||||
DECL_NAME (OVL_CURRENT (fn)), args);
|
||||
else
|
||||
error ("call of overloaded %<%D(%A)%> is ambiguous",
|
||||
DECL_NAME (OVL_CURRENT (fn)), args);
|
||||
if (candidates)
|
||||
print_z_candidates (candidates);
|
||||
}
|
||||
result = error_mark_node;
|
||||
}
|
||||
else
|
||||
result = build_over_call (cand, LOOKUP_NORMAL);
|
||||
result = build_over_call (cand, LOOKUP_NORMAL, complain);
|
||||
|
||||
/* Free all the conversions we allocated. */
|
||||
obstack_free (&conversion_obstack, p);
|
||||
|
@ -2997,11 +3002,11 @@ build_operator_new_call (tree fnname, tree args,
|
|||
*fn = cand->fn;
|
||||
|
||||
/* Build the CALL_EXPR. */
|
||||
return build_over_call (cand, LOOKUP_NORMAL);
|
||||
return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error);
|
||||
}
|
||||
|
||||
static tree
|
||||
build_object_call (tree obj, tree args)
|
||||
build_object_call (tree obj, tree args, tsubst_flags_t complain)
|
||||
{
|
||||
struct z_candidate *candidates = 0, *cand;
|
||||
tree fns, convs, mem_args = NULL_TREE;
|
||||
|
@ -3012,9 +3017,10 @@ build_object_call (tree obj, tree args)
|
|||
|
||||
if (TYPE_PTRMEMFUNC_P (type))
|
||||
{
|
||||
/* It's no good looking for an overloaded operator() on a
|
||||
pointer-to-member-function. */
|
||||
error ("pointer-to-member function %E cannot be called without an object; consider using .* or ->*", obj);
|
||||
if (complain & tf_error)
|
||||
/* It's no good looking for an overloaded operator() on a
|
||||
pointer-to-member-function. */
|
||||
error ("pointer-to-member function %E cannot be called without an object; consider using .* or ->*", obj);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -3088,8 +3094,11 @@ build_object_call (tree obj, tree args)
|
|||
candidates = splice_viable (candidates, pedantic, &any_viable_p);
|
||||
if (!any_viable_p)
|
||||
{
|
||||
error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj), args);
|
||||
print_z_candidates (candidates);
|
||||
if (complain & tf_error)
|
||||
{
|
||||
error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj), args);
|
||||
print_z_candidates (candidates);
|
||||
}
|
||||
result = error_mark_node;
|
||||
}
|
||||
else
|
||||
|
@ -3097,8 +3106,12 @@ build_object_call (tree obj, tree args)
|
|||
cand = tourney (candidates);
|
||||
if (cand == 0)
|
||||
{
|
||||
error ("call of %<(%T) (%A)%> is ambiguous", TREE_TYPE (obj), args);
|
||||
print_z_candidates (candidates);
|
||||
if (complain & tf_error)
|
||||
{
|
||||
error ("call of %<(%T) (%A)%> is ambiguous",
|
||||
TREE_TYPE (obj), args);
|
||||
print_z_candidates (candidates);
|
||||
}
|
||||
result = error_mark_node;
|
||||
}
|
||||
/* Since cand->fn will be a type, not a function, for a conversion
|
||||
|
@ -3106,12 +3119,13 @@ build_object_call (tree obj, tree args)
|
|||
DECL_NAME here. */
|
||||
else if (TREE_CODE (cand->fn) == FUNCTION_DECL
|
||||
&& DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR)
|
||||
result = build_over_call (cand, LOOKUP_NORMAL);
|
||||
result = build_over_call (cand, LOOKUP_NORMAL, complain);
|
||||
else
|
||||
{
|
||||
obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1);
|
||||
obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1,
|
||||
complain);
|
||||
obj = convert_from_reference (obj);
|
||||
result = build_function_call (obj, args);
|
||||
result = cp_build_function_call (obj, args, complain);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3232,7 +3246,8 @@ conditional_conversion (tree e1, tree e2)
|
|||
arguments to the conditional expression. */
|
||||
|
||||
tree
|
||||
build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
||||
build_conditional_expr (tree arg1, tree arg2, tree arg3,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
tree arg2_type;
|
||||
tree arg3_type;
|
||||
|
@ -3249,7 +3264,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
|||
calculated only once. */
|
||||
if (!arg2)
|
||||
{
|
||||
if (pedantic)
|
||||
if (pedantic && (complain & tf_error))
|
||||
pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression");
|
||||
|
||||
/* Make sure that lvalues remain lvalues. See g++.oliva/ext1.C. */
|
||||
|
@ -3263,7 +3278,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
|||
|
||||
The first expr ession is implicitly converted to bool (clause
|
||||
_conv_). */
|
||||
arg1 = perform_implicit_conversion (boolean_type_node, arg1);
|
||||
arg1 = perform_implicit_conversion (boolean_type_node, arg1, complain);
|
||||
|
||||
/* If something has already gone wrong, just pass that fact up the
|
||||
tree. */
|
||||
|
@ -3327,16 +3342,19 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
|||
result_type = void_type_node;
|
||||
else
|
||||
{
|
||||
if (VOID_TYPE_P (arg2_type))
|
||||
error ("second operand to the conditional operator "
|
||||
"is of type %<void%>, "
|
||||
"but the third operand is neither a throw-expression "
|
||||
"nor of type %<void%>");
|
||||
else
|
||||
error ("third operand to the conditional operator "
|
||||
"is of type %<void%>, "
|
||||
"but the second operand is neither a throw-expression "
|
||||
"nor of type %<void%>");
|
||||
if (complain & tf_error)
|
||||
{
|
||||
if (VOID_TYPE_P (arg2_type))
|
||||
error ("second operand to the conditional operator "
|
||||
"is of type %<void%>, "
|
||||
"but the third operand is neither a throw-expression "
|
||||
"nor of type %<void%>");
|
||||
else
|
||||
error ("third operand to the conditional operator "
|
||||
"is of type %<void%>, "
|
||||
"but the second operand is neither a throw-expression "
|
||||
"nor of type %<void%>");
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -3380,7 +3398,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
|||
}
|
||||
else if (conv2 && (!conv2->bad_p || !conv3))
|
||||
{
|
||||
arg2 = convert_like (conv2, arg2);
|
||||
arg2 = convert_like (conv2, arg2, complain);
|
||||
arg2 = convert_from_reference (arg2);
|
||||
arg2_type = TREE_TYPE (arg2);
|
||||
/* Even if CONV2 is a valid conversion, the result of the
|
||||
|
@ -3393,7 +3411,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
|||
}
|
||||
else if (conv3 && (!conv3->bad_p || !conv2))
|
||||
{
|
||||
arg3 = convert_like (conv3, arg3);
|
||||
arg3 = convert_like (conv3, arg3, complain);
|
||||
arg3 = convert_from_reference (arg3);
|
||||
arg3_type = TREE_TYPE (arg3);
|
||||
if (error_operand_p (arg3))
|
||||
|
@ -3477,15 +3495,21 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
|||
candidates = splice_viable (candidates, pedantic, &any_viable_p);
|
||||
if (!any_viable_p)
|
||||
{
|
||||
op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
|
||||
print_z_candidates (candidates);
|
||||
if (complain & tf_error)
|
||||
{
|
||||
op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
|
||||
print_z_candidates (candidates);
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
cand = tourney (candidates);
|
||||
if (!cand)
|
||||
{
|
||||
op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
|
||||
print_z_candidates (candidates);
|
||||
if (complain & tf_error)
|
||||
{
|
||||
op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
|
||||
print_z_candidates (candidates);
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -3495,11 +3519,11 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
|||
the converted operands are used in place of the original
|
||||
operands for the remainder of this section. */
|
||||
conv = cand->convs[0];
|
||||
arg1 = convert_like (conv, arg1);
|
||||
arg1 = convert_like (conv, arg1, complain);
|
||||
conv = cand->convs[1];
|
||||
arg2 = convert_like (conv, arg2);
|
||||
arg2 = convert_like (conv, arg2, complain);
|
||||
conv = cand->convs[2];
|
||||
arg3 = convert_like (conv, arg3);
|
||||
arg3 = convert_like (conv, arg3, complain);
|
||||
}
|
||||
|
||||
/* [expr.cond]
|
||||
|
@ -3548,17 +3572,25 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
|||
|
||||
if (TREE_CODE (arg2_type) == ENUMERAL_TYPE
|
||||
&& TREE_CODE (arg3_type) == ENUMERAL_TYPE)
|
||||
warning (0, "enumeral mismatch in conditional expression: %qT vs %qT",
|
||||
arg2_type, arg3_type);
|
||||
{
|
||||
if (complain & tf_warning)
|
||||
warning (0,
|
||||
"enumeral mismatch in conditional expression: %qT vs %qT",
|
||||
arg2_type, arg3_type);
|
||||
}
|
||||
else if (extra_warnings
|
||||
&& ((TREE_CODE (arg2_type) == ENUMERAL_TYPE
|
||||
&& !same_type_p (arg3_type, type_promotes_to (arg2_type)))
|
||||
|| (TREE_CODE (arg3_type) == ENUMERAL_TYPE
|
||||
&& !same_type_p (arg2_type, type_promotes_to (arg3_type)))))
|
||||
warning (0, "enumeral and non-enumeral type in conditional expression");
|
||||
{
|
||||
if (complain & tf_warning)
|
||||
warning (0,
|
||||
"enumeral and non-enumeral type in conditional expression");
|
||||
}
|
||||
|
||||
arg2 = perform_implicit_conversion (result_type, arg2);
|
||||
arg3 = perform_implicit_conversion (result_type, arg3);
|
||||
arg2 = perform_implicit_conversion (result_type, arg2, complain);
|
||||
arg3 = perform_implicit_conversion (result_type, arg3, complain);
|
||||
}
|
||||
/* [expr.cond]
|
||||
|
||||
|
@ -3585,17 +3617,19 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
|||
|| (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type)))
|
||||
{
|
||||
result_type = composite_pointer_type (arg2_type, arg3_type, arg2,
|
||||
arg3, "conditional expression");
|
||||
arg3, "conditional expression",
|
||||
complain);
|
||||
if (result_type == error_mark_node)
|
||||
return error_mark_node;
|
||||
arg2 = perform_implicit_conversion (result_type, arg2);
|
||||
arg3 = perform_implicit_conversion (result_type, arg3);
|
||||
arg2 = perform_implicit_conversion (result_type, arg2, complain);
|
||||
arg3 = perform_implicit_conversion (result_type, arg3, complain);
|
||||
}
|
||||
|
||||
if (!result_type)
|
||||
{
|
||||
error ("operands to ?: have different types %qT and %qT",
|
||||
arg2_type, arg3_type);
|
||||
if (complain & tf_error)
|
||||
error ("operands to ?: have different types %qT and %qT",
|
||||
arg2_type, arg3_type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -3707,7 +3741,7 @@ add_candidates (tree fns, tree args,
|
|||
|
||||
tree
|
||||
build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
||||
bool *overloaded_p)
|
||||
bool *overloaded_p, tsubst_flags_t complain)
|
||||
{
|
||||
struct z_candidate *candidates = 0, *cand;
|
||||
tree arglist, fnname;
|
||||
|
@ -3747,7 +3781,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
gcc_unreachable ();
|
||||
|
||||
case CALL_EXPR:
|
||||
return build_object_call (arg1, arg2);
|
||||
return build_object_call (arg1, arg2, complain);
|
||||
|
||||
case TRUTH_ORIF_EXPR:
|
||||
case TRUTH_ANDIF_EXPR:
|
||||
|
@ -3856,6 +3890,11 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
{
|
||||
case POSTINCREMENT_EXPR:
|
||||
case POSTDECREMENT_EXPR:
|
||||
/* Don't try anything fancy if we're not allowed to produce
|
||||
errors. */
|
||||
if (!(complain & tf_error))
|
||||
return error_mark_node;
|
||||
|
||||
/* Look for an `operator++ (int)'. If they didn't have
|
||||
one, then we fall back to the old way of doing things. */
|
||||
if (flags & LOOKUP_COMPLAIN)
|
||||
|
@ -3868,7 +3907,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
else
|
||||
code = PREDECREMENT_EXPR;
|
||||
result = build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE,
|
||||
overloaded_p);
|
||||
overloaded_p, complain);
|
||||
break;
|
||||
|
||||
/* The caller will deal with these. */
|
||||
|
@ -3880,7 +3919,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
break;
|
||||
|
||||
default:
|
||||
if (flags & LOOKUP_COMPLAIN)
|
||||
if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
|
||||
{
|
||||
op_error (code, code2, arg1, arg2, arg3, "no match");
|
||||
print_z_candidates (candidates);
|
||||
|
@ -3894,7 +3933,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
cand = tourney (candidates);
|
||||
if (cand == 0)
|
||||
{
|
||||
if (flags & LOOKUP_COMPLAIN)
|
||||
if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
|
||||
{
|
||||
op_error (code, code2, arg1, arg2, arg3, "ambiguous overload");
|
||||
print_z_candidates (candidates);
|
||||
|
@ -3909,12 +3948,12 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
if (resolve_args (arglist) == error_mark_node)
|
||||
result = error_mark_node;
|
||||
else
|
||||
result = build_over_call (cand, LOOKUP_NORMAL);
|
||||
result = build_over_call (cand, LOOKUP_NORMAL, complain);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Give any warnings we noticed during overload resolution. */
|
||||
if (cand->warnings)
|
||||
if (cand->warnings && (complain & tf_warning))
|
||||
{
|
||||
struct candidate_warning *w;
|
||||
for (w = cand->warnings; w; w = w->next)
|
||||
|
@ -3933,7 +3972,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE
|
||||
&& (TYPE_MAIN_VARIANT (TREE_TYPE (arg1))
|
||||
!= TYPE_MAIN_VARIANT (TREE_TYPE (arg2))))
|
||||
!= TYPE_MAIN_VARIANT (TREE_TYPE (arg2)))
|
||||
&& (complain & tf_warning))
|
||||
{
|
||||
warning (0, "comparison between %q#T and %q#T",
|
||||
TREE_TYPE (arg1), TREE_TYPE (arg2));
|
||||
|
@ -3950,25 +3990,26 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
conv = cand->convs[0];
|
||||
if (conv->kind == ck_ref_bind)
|
||||
conv = conv->u.next;
|
||||
arg1 = convert_like (conv, arg1);
|
||||
arg1 = convert_like (conv, arg1, complain);
|
||||
if (arg2)
|
||||
{
|
||||
conv = cand->convs[1];
|
||||
if (conv->kind == ck_ref_bind)
|
||||
conv = conv->u.next;
|
||||
arg2 = convert_like (conv, arg2);
|
||||
arg2 = convert_like (conv, arg2, complain);
|
||||
}
|
||||
if (arg3)
|
||||
{
|
||||
conv = cand->convs[2];
|
||||
if (conv->kind == ck_ref_bind)
|
||||
conv = conv->u.next;
|
||||
arg3 = convert_like (conv, arg3);
|
||||
arg3 = convert_like (conv, arg3, complain);
|
||||
}
|
||||
|
||||
if (!expl_eq_arg1)
|
||||
{
|
||||
warn_logical_operator (code, arg1, arg2);
|
||||
if (complain & tf_warning)
|
||||
warn_logical_operator (code, arg1, arg2);
|
||||
expl_eq_arg1 = true;
|
||||
}
|
||||
}
|
||||
|
@ -3986,10 +4027,10 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
switch (code)
|
||||
{
|
||||
case MODIFY_EXPR:
|
||||
return build_modify_expr (arg1, code2, arg2);
|
||||
return cp_build_modify_expr (arg1, code2, arg2, complain);
|
||||
|
||||
case INDIRECT_REF:
|
||||
return build_indirect_ref (arg1, "unary *");
|
||||
return cp_build_indirect_ref (arg1, "unary *", complain);
|
||||
|
||||
case TRUTH_ANDIF_EXPR:
|
||||
case TRUTH_ORIF_EXPR:
|
||||
|
@ -4015,7 +4056,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
case BIT_AND_EXPR:
|
||||
case BIT_IOR_EXPR:
|
||||
case BIT_XOR_EXPR:
|
||||
return cp_build_binary_op (code, arg1, arg2);
|
||||
return cp_build_binary_op (code, arg1, arg2, complain);
|
||||
|
||||
case UNARY_PLUS_EXPR:
|
||||
case NEGATE_EXPR:
|
||||
|
@ -4027,16 +4068,18 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
|||
case POSTDECREMENT_EXPR:
|
||||
case REALPART_EXPR:
|
||||
case IMAGPART_EXPR:
|
||||
return build_unary_op (code, arg1, candidates != 0);
|
||||
return cp_build_unary_op (code, arg1, candidates != 0, complain);
|
||||
|
||||
case ARRAY_REF:
|
||||
return build_array_ref (arg1, arg2);
|
||||
|
||||
case COND_EXPR:
|
||||
return build_conditional_expr (arg1, arg2, arg3);
|
||||
return build_conditional_expr (arg1, arg2, arg3, complain);
|
||||
|
||||
case MEMBER_REF:
|
||||
return build_m_component_ref (build_indirect_ref (arg1, NULL), arg2);
|
||||
return build_m_component_ref (cp_build_indirect_ref (arg1, NULL,
|
||||
complain),
|
||||
arg2);
|
||||
|
||||
/* The caller will deal with these. */
|
||||
case ADDR_EXPR:
|
||||
|
@ -4205,7 +4248,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
|
|||
else
|
||||
args = tree_cons (NULL_TREE, addr,
|
||||
build_tree_list (NULL_TREE, size));
|
||||
return build_function_call (fn, args);
|
||||
return cp_build_function_call (fn, args, tf_warning_or_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4268,7 +4311,7 @@ build_temp (tree expr, tree type, int flags,
|
|||
expr = build_special_member_call (NULL_TREE,
|
||||
complete_ctor_identifier,
|
||||
build_tree_list (NULL_TREE, expr),
|
||||
type, flags);
|
||||
type, flags, tf_warning_or_error);
|
||||
if (warningcount > savew)
|
||||
*diagnostic_fn = warning0;
|
||||
else if (errorcount > savee)
|
||||
|
@ -4317,7 +4360,7 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
|
|||
static tree
|
||||
convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
||||
int inner, bool issue_conversion_warnings,
|
||||
bool c_cast_p)
|
||||
bool c_cast_p, tsubst_flags_t complain)
|
||||
{
|
||||
tree totype = convs->type;
|
||||
diagnostic_fn_t diagnostic_fn;
|
||||
|
@ -4335,23 +4378,31 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
{
|
||||
expr = convert_like_real (t, expr, fn, argnum, 1,
|
||||
/*issue_conversion_warnings=*/false,
|
||||
/*c_cast_p=*/false);
|
||||
/*c_cast_p=*/false,
|
||||
complain);
|
||||
break;
|
||||
}
|
||||
else if (t->kind == ck_ambig)
|
||||
return convert_like_real (t, expr, fn, argnum, 1,
|
||||
/*issue_conversion_warnings=*/false,
|
||||
/*c_cast_p=*/false);
|
||||
/*c_cast_p=*/false,
|
||||
complain);
|
||||
else if (t->kind == ck_identity)
|
||||
break;
|
||||
}
|
||||
permerror ("invalid conversion from %qT to %qT", TREE_TYPE (expr), totype);
|
||||
if (fn)
|
||||
permerror (" initializing argument %P of %qD", argnum, fn);
|
||||
if (complain & tf_error)
|
||||
{
|
||||
permerror ("invalid conversion from %qT to %qT", TREE_TYPE (expr), totype);
|
||||
if (fn)
|
||||
permerror (" initializing argument %P of %qD", argnum, fn);
|
||||
}
|
||||
else
|
||||
return error_mark_node;
|
||||
|
||||
return cp_convert (totype, expr);
|
||||
}
|
||||
|
||||
if (issue_conversion_warnings)
|
||||
if (issue_conversion_warnings && (complain & tf_warning))
|
||||
conversion_null_warnings (totype, expr, fn, argnum);
|
||||
|
||||
switch (convs->kind)
|
||||
|
@ -4367,7 +4418,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
for (i = 0; i < cand->num_convs; ++i)
|
||||
cand->convs[i]->user_conv_p = true;
|
||||
|
||||
expr = build_over_call (cand, LOOKUP_NORMAL);
|
||||
expr = build_over_call (cand, LOOKUP_NORMAL, complain);
|
||||
|
||||
/* If this is a constructor or a function returning an aggr type,
|
||||
we need to build up a TARGET_EXPR. */
|
||||
|
@ -4394,7 +4445,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION,
|
||||
&diagnostic_fn));
|
||||
|
||||
if (diagnostic_fn)
|
||||
if (diagnostic_fn && (complain & tf_error))
|
||||
{
|
||||
if (fn)
|
||||
diagnostic_fn
|
||||
|
@ -4410,7 +4461,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
}
|
||||
case ck_identity:
|
||||
if (type_unknown_p (expr))
|
||||
expr = instantiate_type (totype, expr, tf_warning_or_error);
|
||||
expr = instantiate_type (totype, expr, complain);
|
||||
/* Convert a constant to its underlying value, unless we are
|
||||
about to bind it to a reference, in which case we need to
|
||||
leave it as an lvalue. */
|
||||
|
@ -4436,7 +4487,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
expr = convert_like_real (convs->u.next, expr, fn, argnum,
|
||||
convs->kind == ck_ref_bind ? -1 : 1,
|
||||
convs->kind == ck_ref_bind ? issue_conversion_warnings : false,
|
||||
c_cast_p);
|
||||
c_cast_p,
|
||||
complain);
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
@ -4453,10 +4505,10 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
/* We are going to bind a reference directly to a base-class
|
||||
subobject of EXPR. */
|
||||
/* Build an expression for `*((base*) &expr)'. */
|
||||
expr = build_unary_op (ADDR_EXPR, expr, 0);
|
||||
expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain);
|
||||
expr = convert_to_base (expr, build_pointer_type (totype),
|
||||
!c_cast_p, /*nonnull=*/true);
|
||||
expr = build_indirect_ref (expr, "implicit conversion");
|
||||
expr = cp_build_indirect_ref (expr, "implicit conversion", complain);
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
@ -4470,7 +4522,12 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
flags |= LOOKUP_NO_CONVERSION;
|
||||
expr = build_temp (expr, totype, flags, &diagnostic_fn);
|
||||
if (diagnostic_fn && fn)
|
||||
diagnostic_fn (" initializing argument %P of %qD", argnum, fn);
|
||||
{
|
||||
if ((complain & tf_error))
|
||||
diagnostic_fn (" initializing argument %P of %qD", argnum, fn);
|
||||
else if (diagnostic_fn == error)
|
||||
return error_mark_node;
|
||||
}
|
||||
return build_cplus_new (totype, expr);
|
||||
|
||||
case ck_ref_bind:
|
||||
|
@ -4482,7 +4539,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
VA_ARG_EXPR and CONSTRUCTOR expressions are special cases
|
||||
that need temporaries, even when their types are reference
|
||||
compatible with the type of reference being bound, so the
|
||||
upcoming call to build_unary_op (ADDR_EXPR, expr, ...)
|
||||
upcoming call to cp_build_unary_op (ADDR_EXPR, expr, ...)
|
||||
doesn't fail. */
|
||||
if (convs->need_temporary_p
|
||||
|| TREE_CODE (expr) == CONSTRUCTOR
|
||||
|
@ -4494,16 +4551,19 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type))
|
||||
&& !TYPE_REF_IS_RVALUE (ref_type))
|
||||
{
|
||||
/* If the reference is volatile or non-const, we
|
||||
cannot create a temporary. */
|
||||
if (lvalue & clk_bitfield)
|
||||
error ("cannot bind bitfield %qE to %qT",
|
||||
expr, ref_type);
|
||||
else if (lvalue & clk_packed)
|
||||
error ("cannot bind packed field %qE to %qT",
|
||||
expr, ref_type);
|
||||
else
|
||||
error ("cannot bind rvalue %qE to %qT", expr, ref_type);
|
||||
if (complain & tf_error)
|
||||
{
|
||||
/* If the reference is volatile or non-const, we
|
||||
cannot create a temporary. */
|
||||
if (lvalue & clk_bitfield)
|
||||
error ("cannot bind bitfield %qE to %qT",
|
||||
expr, ref_type);
|
||||
else if (lvalue & clk_packed)
|
||||
error ("cannot bind packed field %qE to %qT",
|
||||
expr, ref_type);
|
||||
else
|
||||
error ("cannot bind rvalue %qE to %qT", expr, ref_type);
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
/* If the source is a packed field, and we must use a copy
|
||||
|
@ -4516,8 +4576,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
&& CLASS_TYPE_P (type)
|
||||
&& !TYPE_HAS_TRIVIAL_INIT_REF (type))
|
||||
{
|
||||
error ("cannot bind packed field %qE to %qT",
|
||||
expr, ref_type);
|
||||
if (complain & tf_error)
|
||||
error ("cannot bind packed field %qE to %qT",
|
||||
expr, ref_type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (lvalue & clk_bitfield)
|
||||
|
@ -4527,7 +4588,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
|
||||
/* Take the address of the thing to which we will bind the
|
||||
reference. */
|
||||
expr = build_unary_op (ADDR_EXPR, expr, 1);
|
||||
expr = cp_build_unary_op (ADDR_EXPR, expr, 1, complain);
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
@ -4652,7 +4713,7 @@ build_x_va_arg (tree expr, tree type)
|
|||
expr = convert (build_pointer_type (type1), null_node);
|
||||
expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr),
|
||||
call_builtin_trap (), expr);
|
||||
expr = build_indirect_ref (expr, NULL);
|
||||
expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
@ -4719,7 +4780,8 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
|
|||
{
|
||||
arg = digest_init (type, arg);
|
||||
arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
|
||||
"default argument", fn, parmnum);
|
||||
"default argument", fn, parmnum,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4732,7 +4794,8 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
|
|||
if (!CONSTANT_CLASS_P (arg))
|
||||
arg = unshare_expr (arg);
|
||||
arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
|
||||
"default argument", fn, parmnum);
|
||||
"default argument", fn, parmnum,
|
||||
tf_warning_or_error);
|
||||
arg = convert_for_arg_passing (type, arg);
|
||||
}
|
||||
|
||||
|
@ -4845,7 +4908,7 @@ magic_varargs_p (tree fn)
|
|||
bitmask of various LOOKUP_* flags which apply to the call itself. */
|
||||
|
||||
static tree
|
||||
build_over_call (struct z_candidate *cand, int flags)
|
||||
build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
{
|
||||
tree fn = cand->fn;
|
||||
tree args = cand->args;
|
||||
|
@ -4957,8 +5020,13 @@ build_over_call (struct z_candidate *cand, int flags)
|
|||
tree base_binfo;
|
||||
|
||||
if (convs[i]->bad_p)
|
||||
permerror ("passing %qT as %<this%> argument of %q#D discards qualifiers",
|
||||
TREE_TYPE (argtype), fn);
|
||||
{
|
||||
if (complain & tf_error)
|
||||
permerror ("passing %qT as %<this%> argument of %q#D discards qualifiers",
|
||||
TREE_TYPE (argtype), fn);
|
||||
else
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* [class.mfct.nonstatic]: If a nonstatic member function of a class
|
||||
X is called for an object that is not of type X, or of a type
|
||||
|
@ -5008,10 +5076,13 @@ build_over_call (struct z_candidate *cand, int flags)
|
|||
conv = conv->u.next;
|
||||
|
||||
val = convert_like_with_context
|
||||
(conv, TREE_VALUE (arg), fn, i - is_method);
|
||||
(conv, TREE_VALUE (arg), fn, i - is_method, complain);
|
||||
|
||||
val = convert_for_arg_passing (type, val);
|
||||
argarray[j++] = val;
|
||||
if ((complain == tf_none) && val == error_mark_node)
|
||||
return error_mark_node;
|
||||
else
|
||||
argarray[j++] = val;
|
||||
}
|
||||
|
||||
/* Default arguments */
|
||||
|
@ -5067,7 +5138,7 @@ build_over_call (struct z_candidate *cand, int flags)
|
|||
if (targ)
|
||||
arg = targ;
|
||||
else
|
||||
arg = build_indirect_ref (arg, 0);
|
||||
arg = cp_build_indirect_ref (arg, 0, complain);
|
||||
|
||||
/* [class.copy]: the copy constructor is implicitly defined even if
|
||||
the implementation elided its use. */
|
||||
|
@ -5091,7 +5162,7 @@ build_over_call (struct z_candidate *cand, int flags)
|
|||
&& !move_fn_p (fn)))
|
||||
{
|
||||
tree to = stabilize_reference
|
||||
(build_indirect_ref (TREE_VALUE (args), 0));
|
||||
(cp_build_indirect_ref (TREE_VALUE (args), 0, complain));
|
||||
|
||||
val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
|
||||
return val;
|
||||
|
@ -5102,14 +5173,14 @@ build_over_call (struct z_candidate *cand, int flags)
|
|||
&& TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
|
||||
{
|
||||
tree to = stabilize_reference
|
||||
(build_indirect_ref (argarray[0], 0));
|
||||
(cp_build_indirect_ref (argarray[0], 0, complain));
|
||||
tree type = TREE_TYPE (to);
|
||||
tree as_base = CLASSTYPE_AS_BASE (type);
|
||||
|
||||
arg = argarray[1];
|
||||
if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
|
||||
{
|
||||
arg = build_indirect_ref (arg, 0);
|
||||
arg = cp_build_indirect_ref (arg, 0, complain);
|
||||
val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
|
||||
}
|
||||
else
|
||||
|
@ -5121,12 +5192,12 @@ build_over_call (struct z_candidate *cand, int flags)
|
|||
|
||||
arg2 = TYPE_SIZE_UNIT (as_base);
|
||||
arg1 = arg;
|
||||
arg0 = build_unary_op (ADDR_EXPR, to, 0);
|
||||
arg0 = cp_build_unary_op (ADDR_EXPR, to, 0, complain);
|
||||
t = implicit_built_in_decls[BUILT_IN_MEMCPY];
|
||||
t = build_call_n (t, 3, arg0, arg1, arg2);
|
||||
|
||||
t = convert (TREE_TYPE (arg0), t);
|
||||
val = build_indirect_ref (t, 0);
|
||||
val = cp_build_indirect_ref (t, 0, complain);
|
||||
}
|
||||
|
||||
return val;
|
||||
|
@ -5227,7 +5298,8 @@ build_java_interface_fn_ref (tree fn, tree instance)
|
|||
|
||||
/* Look up the pointer to the runtime java.lang.Class object for `instance'.
|
||||
This is the first entry in the vtable. */
|
||||
klass_ref = build_vtbl_ref (build_indirect_ref (instance, 0),
|
||||
klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, 0,
|
||||
tf_warning_or_error),
|
||||
integer_zero_node);
|
||||
|
||||
/* Get the java.lang.Class pointer for the interface being called. */
|
||||
|
@ -5300,7 +5372,7 @@ in_charge_arg_for_name (tree name)
|
|||
|
||||
tree
|
||||
build_special_member_call (tree instance, tree name, tree args,
|
||||
tree binfo, int flags)
|
||||
tree binfo, int flags, tsubst_flags_t complain)
|
||||
{
|
||||
tree fns;
|
||||
/* The type of the subobject to be constructed or destroyed. */
|
||||
|
@ -5390,7 +5462,8 @@ build_special_member_call (tree instance, tree name, tree args,
|
|||
|
||||
return build_new_method_call (instance, fns, args,
|
||||
TYPE_BINFO (BINFO_TYPE (binfo)),
|
||||
flags, /*fn=*/NULL);
|
||||
flags, /*fn=*/NULL,
|
||||
complain);
|
||||
}
|
||||
|
||||
/* Return the NAME, as a C string. The NAME indicates a function that
|
||||
|
@ -5444,7 +5517,7 @@ name_as_c_string (tree name, tree type, bool *free_p)
|
|||
tree
|
||||
build_new_method_call (tree instance, tree fns, tree args,
|
||||
tree conversion_path, int flags,
|
||||
tree *fn_p)
|
||||
tree *fn_p, tsubst_flags_t complain)
|
||||
{
|
||||
struct z_candidate *candidates = 0, *cand;
|
||||
tree explicit_targs = NULL_TREE;
|
||||
|
@ -5477,7 +5550,8 @@ build_new_method_call (tree instance, tree fns, tree args,
|
|||
|
||||
if (!BASELINK_P (fns))
|
||||
{
|
||||
error ("call to non-function %qD", fns);
|
||||
if (complain & tf_error)
|
||||
error ("call to non-function %qD", fns);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -5594,21 +5668,24 @@ build_new_method_call (tree instance, tree fns, tree args,
|
|||
candidates = splice_viable (candidates, pedantic, &any_viable_p);
|
||||
if (!any_viable_p)
|
||||
{
|
||||
if (!COMPLETE_TYPE_P (basetype))
|
||||
cxx_incomplete_type_error (instance_ptr, basetype);
|
||||
else
|
||||
if (complain & tf_error)
|
||||
{
|
||||
char *pretty_name;
|
||||
bool free_p;
|
||||
if (!COMPLETE_TYPE_P (basetype))
|
||||
cxx_incomplete_type_error (instance_ptr, basetype);
|
||||
else
|
||||
{
|
||||
char *pretty_name;
|
||||
bool free_p;
|
||||
|
||||
pretty_name = name_as_c_string (name, basetype, &free_p);
|
||||
error ("no matching function for call to %<%T::%s(%A)%#V%>",
|
||||
basetype, pretty_name, user_args,
|
||||
TREE_TYPE (TREE_TYPE (instance_ptr)));
|
||||
if (free_p)
|
||||
free (pretty_name);
|
||||
pretty_name = name_as_c_string (name, basetype, &free_p);
|
||||
error ("no matching function for call to %<%T::%s(%A)%#V%>",
|
||||
basetype, pretty_name, user_args,
|
||||
TREE_TYPE (TREE_TYPE (instance_ptr)));
|
||||
if (free_p)
|
||||
free (pretty_name);
|
||||
}
|
||||
print_z_candidates (candidates);
|
||||
}
|
||||
print_z_candidates (candidates);
|
||||
call = error_mark_node;
|
||||
}
|
||||
else
|
||||
|
@ -5619,12 +5696,15 @@ build_new_method_call (tree instance, tree fns, tree args,
|
|||
char *pretty_name;
|
||||
bool free_p;
|
||||
|
||||
pretty_name = name_as_c_string (name, basetype, &free_p);
|
||||
error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name,
|
||||
user_args);
|
||||
print_z_candidates (candidates);
|
||||
if (free_p)
|
||||
free (pretty_name);
|
||||
if (complain & tf_error)
|
||||
{
|
||||
pretty_name = name_as_c_string (name, basetype, &free_p);
|
||||
error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name,
|
||||
user_args);
|
||||
print_z_candidates (candidates);
|
||||
if (free_p)
|
||||
free (pretty_name);
|
||||
}
|
||||
call = error_mark_node;
|
||||
}
|
||||
else
|
||||
|
@ -5635,7 +5715,8 @@ build_new_method_call (tree instance, tree fns, tree args,
|
|||
&& DECL_PURE_VIRTUAL_P (fn)
|
||||
&& instance == current_class_ref
|
||||
&& (DECL_CONSTRUCTOR_P (current_function_decl)
|
||||
|| DECL_DESTRUCTOR_P (current_function_decl)))
|
||||
|| DECL_DESTRUCTOR_P (current_function_decl))
|
||||
&& (complain & tf_warning))
|
||||
/* This is not an error, it is runtime undefined
|
||||
behavior. */
|
||||
warning (0, (DECL_CONSTRUCTOR_P (current_function_decl) ?
|
||||
|
@ -5646,8 +5727,9 @@ build_new_method_call (tree instance, tree fns, tree args,
|
|||
if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
|
||||
&& is_dummy_object (instance_ptr))
|
||||
{
|
||||
error ("cannot call member function %qD without object",
|
||||
fn);
|
||||
if (complain & tf_error)
|
||||
error ("cannot call member function %qD without object",
|
||||
fn);
|
||||
call = error_mark_node;
|
||||
}
|
||||
else
|
||||
|
@ -5659,7 +5741,7 @@ build_new_method_call (tree instance, tree fns, tree args,
|
|||
if (fn_p)
|
||||
*fn_p = fn;
|
||||
/* Build the actual CALL_EXPR. */
|
||||
call = build_over_call (cand, flags);
|
||||
call = build_over_call (cand, flags, complain);
|
||||
/* In an expression of the form `a->f()' where `f' turns
|
||||
out to be a static member function, `a' is
|
||||
none-the-less evaluated. */
|
||||
|
@ -6608,7 +6690,7 @@ can_convert_arg_bad (tree to, tree from, tree arg)
|
|||
doing a bad conversion, convert_like will complain. */
|
||||
|
||||
tree
|
||||
perform_implicit_conversion (tree type, tree expr)
|
||||
perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
|
||||
{
|
||||
conversion *conv;
|
||||
void *p;
|
||||
|
@ -6624,7 +6706,8 @@ perform_implicit_conversion (tree type, tree expr)
|
|||
LOOKUP_NORMAL);
|
||||
if (!conv)
|
||||
{
|
||||
error ("could not convert %qE to %qT", expr, type);
|
||||
if (complain & tf_error)
|
||||
error ("could not convert %qE to %qT", expr, type);
|
||||
expr = error_mark_node;
|
||||
}
|
||||
else if (processing_template_decl)
|
||||
|
@ -6636,7 +6719,7 @@ perform_implicit_conversion (tree type, tree expr)
|
|||
expr = build_nop (type, expr);
|
||||
}
|
||||
else
|
||||
expr = convert_like (conv, expr);
|
||||
expr = convert_like (conv, expr, complain);
|
||||
|
||||
/* Free all the conversions we allocated. */
|
||||
obstack_free (&conversion_obstack, p);
|
||||
|
@ -6655,7 +6738,8 @@ perform_implicit_conversion (tree type, tree expr)
|
|||
tree
|
||||
perform_direct_initialization_if_possible (tree type,
|
||||
tree expr,
|
||||
bool c_cast_p)
|
||||
bool c_cast_p,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
conversion *conv;
|
||||
void *p;
|
||||
|
@ -6674,7 +6758,7 @@ perform_direct_initialization_if_possible (tree type,
|
|||
{
|
||||
expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
|
||||
build_tree_list (NULL_TREE, expr),
|
||||
type, LOOKUP_NORMAL);
|
||||
type, LOOKUP_NORMAL, complain);
|
||||
return build_cplus_new (type, expr);
|
||||
}
|
||||
|
||||
|
@ -6689,7 +6773,8 @@ perform_direct_initialization_if_possible (tree type,
|
|||
else
|
||||
expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
|
||||
/*issue_conversion_warnings=*/false,
|
||||
c_cast_p);
|
||||
c_cast_p,
|
||||
tf_warning_or_error);
|
||||
|
||||
/* Free all the conversions we allocated. */
|
||||
obstack_free (&conversion_obstack, p);
|
||||
|
@ -6824,7 +6909,8 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
|
|||
/*fn=*/NULL_TREE, /*argnum=*/0,
|
||||
/*inner=*/-1,
|
||||
/*issue_conversion_warnings=*/true,
|
||||
/*c_cast_p=*/false);
|
||||
/*c_cast_p=*/false,
|
||||
tf_warning_or_error);
|
||||
if (error_operand_p (expr))
|
||||
expr = error_mark_node;
|
||||
else
|
||||
|
@ -6897,17 +6983,18 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
|
|||
}
|
||||
else
|
||||
/* Take the address of EXPR. */
|
||||
expr = build_unary_op (ADDR_EXPR, expr, 0);
|
||||
expr = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error);
|
||||
/* If a BASE_CONV was required, perform it now. */
|
||||
if (base_conv_type)
|
||||
expr = (perform_implicit_conversion
|
||||
(build_pointer_type (base_conv_type), expr));
|
||||
(build_pointer_type (base_conv_type), expr,
|
||||
tf_warning_or_error));
|
||||
expr = build_nop (type, expr);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Perform the conversion. */
|
||||
expr = convert_like (conv, expr);
|
||||
expr = convert_like (conv, expr, tf_warning_or_error);
|
||||
|
||||
/* Free all the conversions we allocated. */
|
||||
obstack_free (&conversion_obstack, p);
|
||||
|
|
|
@ -284,7 +284,7 @@ build_base_path (enum tree_code code,
|
|||
|
||||
if (!want_pointer)
|
||||
/* This must happen before the call to save_expr. */
|
||||
expr = build_unary_op (ADDR_EXPR, expr, 0);
|
||||
expr = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error);
|
||||
|
||||
offset = BINFO_OFFSET (binfo);
|
||||
fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
|
||||
|
@ -345,7 +345,7 @@ build_base_path (enum tree_code code,
|
|||
interesting to the optimizers anyway. */
|
||||
&& !has_empty)
|
||||
{
|
||||
expr = build_indirect_ref (expr, NULL);
|
||||
expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
|
||||
expr = build_simple_base_path (expr, binfo);
|
||||
if (want_pointer)
|
||||
expr = build_address (expr);
|
||||
|
@ -370,10 +370,12 @@ build_base_path (enum tree_code code,
|
|||
t = TREE_TYPE (TYPE_VFIELD (current_class_type));
|
||||
t = build_pointer_type (t);
|
||||
v_offset = convert (t, current_vtt_parm);
|
||||
v_offset = build_indirect_ref (v_offset, NULL);
|
||||
v_offset = cp_build_indirect_ref (v_offset, NULL,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
else
|
||||
v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
|
||||
v_offset = build_vfield_ref (cp_build_indirect_ref (expr, NULL,
|
||||
tf_warning_or_error),
|
||||
TREE_TYPE (TREE_TYPE (expr)));
|
||||
|
||||
v_offset = build2 (POINTER_PLUS_EXPR, TREE_TYPE (v_offset),
|
||||
|
@ -381,7 +383,7 @@ build_base_path (enum tree_code code,
|
|||
v_offset = build1 (NOP_EXPR,
|
||||
build_pointer_type (ptrdiff_type_node),
|
||||
v_offset);
|
||||
v_offset = build_indirect_ref (v_offset, NULL);
|
||||
v_offset = cp_build_indirect_ref (v_offset, NULL, tf_warning_or_error);
|
||||
TREE_CONSTANT (v_offset) = 1;
|
||||
TREE_INVARIANT (v_offset) = 1;
|
||||
|
||||
|
@ -425,7 +427,7 @@ build_base_path (enum tree_code code,
|
|||
null_test = NULL;
|
||||
|
||||
if (!want_pointer)
|
||||
expr = build_indirect_ref (expr, NULL);
|
||||
expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
|
||||
|
||||
out:
|
||||
if (null_test)
|
||||
|
@ -459,7 +461,7 @@ build_simple_base_path (tree expr, tree binfo)
|
|||
in the back end. */
|
||||
temp = unary_complex_lvalue (ADDR_EXPR, expr);
|
||||
if (temp)
|
||||
expr = build_indirect_ref (temp, NULL);
|
||||
expr = cp_build_indirect_ref (temp, NULL, tf_warning_or_error);
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -551,7 +553,8 @@ convert_to_base_statically (tree expr, tree base)
|
|||
when processing a template because they do not handle C++-specific
|
||||
trees. */
|
||||
gcc_assert (!processing_template_decl);
|
||||
expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1);
|
||||
expr = cp_build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1,
|
||||
tf_warning_or_error);
|
||||
if (!integer_zerop (BINFO_OFFSET (base)))
|
||||
expr = fold_build2 (POINTER_PLUS_EXPR, pointer_type, expr,
|
||||
fold_convert (sizetype, BINFO_OFFSET (base)));
|
||||
|
@ -648,13 +651,16 @@ build_vfn_ref (tree instance_ptr, tree idx)
|
|||
{
|
||||
tree aref;
|
||||
|
||||
aref = build_vtbl_ref_1 (build_indirect_ref (instance_ptr, 0), idx);
|
||||
aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, 0,
|
||||
tf_warning_or_error),
|
||||
idx);
|
||||
|
||||
/* When using function descriptors, the address of the
|
||||
vtable entry is treated as a function pointer. */
|
||||
if (TARGET_VTABLE_USES_DESCRIPTORS)
|
||||
aref = build1 (NOP_EXPR, TREE_TYPE (aref),
|
||||
build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1));
|
||||
cp_build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1,
|
||||
tf_warning_or_error));
|
||||
|
||||
/* Remember this as a method reference, for later devirtualization. */
|
||||
aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx);
|
||||
|
@ -6098,10 +6104,10 @@ resolve_address_of_overloaded_function (tree target_type,
|
|||
}
|
||||
|
||||
if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
|
||||
return build_unary_op (ADDR_EXPR, fn, 0);
|
||||
return cp_build_unary_op (ADDR_EXPR, fn, 0, flags);
|
||||
else
|
||||
{
|
||||
/* The target must be a REFERENCE_TYPE. Above, build_unary_op
|
||||
/* The target must be a REFERENCE_TYPE. Above, cp_build_unary_op
|
||||
will mark the function as addressed, but here we must do it
|
||||
explicitly. */
|
||||
cxx_mark_addressable (fn);
|
||||
|
|
|
@ -4061,7 +4061,8 @@ extern cp_parameter_declarator *no_parameters;
|
|||
extern bool check_dtor_name (tree, tree);
|
||||
|
||||
extern tree build_vfield_ref (tree, tree);
|
||||
extern tree build_conditional_expr (tree, tree, tree);
|
||||
extern tree build_conditional_expr (tree, tree, tree,
|
||||
tsubst_flags_t);
|
||||
extern tree build_addr_func (tree);
|
||||
extern tree build_call_a (tree, int, tree*);
|
||||
extern tree build_call_n (tree, int, ...);
|
||||
|
@ -4069,13 +4070,17 @@ extern bool null_ptr_cst_p (tree);
|
|||
extern bool sufficient_parms_p (const_tree);
|
||||
extern tree type_decays_to (tree);
|
||||
extern tree build_user_type_conversion (tree, tree, int);
|
||||
extern tree build_new_function_call (tree, tree, bool);
|
||||
extern tree build_new_function_call (tree, tree, bool,
|
||||
tsubst_flags_t);
|
||||
extern tree build_operator_new_call (tree, tree, tree *, tree *,
|
||||
tree *);
|
||||
extern tree build_new_method_call (tree, tree, tree, tree, int,
|
||||
tree *);
|
||||
extern tree build_special_member_call (tree, tree, tree, tree, int);
|
||||
extern tree build_new_op (enum tree_code, int, tree, tree, tree, bool *);
|
||||
tree *, tsubst_flags_t);
|
||||
extern tree build_special_member_call (tree, tree, tree, tree, int,
|
||||
tsubst_flags_t);
|
||||
extern tree build_new_op (enum tree_code, int, tree,
|
||||
tree, tree, bool *,
|
||||
tsubst_flags_t);
|
||||
extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree, tree);
|
||||
extern bool can_convert (tree, tree);
|
||||
extern bool can_convert_arg (tree, tree, tree, int);
|
||||
|
@ -4091,8 +4096,9 @@ extern bool is_properly_derived_from (tree, tree);
|
|||
extern tree initialize_reference (tree, tree, tree, tree *);
|
||||
extern tree make_temporary_var_for_ref_to_temp (tree, tree);
|
||||
extern tree strip_top_quals (tree);
|
||||
extern tree perform_implicit_conversion (tree, tree);
|
||||
extern tree perform_direct_initialization_if_possible (tree, tree, bool);
|
||||
extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t);
|
||||
extern tree perform_direct_initialization_if_possible (tree, tree, bool,
|
||||
tsubst_flags_t);
|
||||
extern tree in_charge_arg_for_name (tree);
|
||||
extern tree build_cxx_call (tree, int, tree *);
|
||||
#ifdef ENABLE_CHECKING
|
||||
|
@ -4159,7 +4165,8 @@ extern tree force_rvalue (tree);
|
|||
extern tree ocp_convert (tree, tree, int, int);
|
||||
extern tree cp_convert (tree, tree);
|
||||
extern tree cp_convert_and_check (tree, tree);
|
||||
extern tree convert_to_void (tree, const char */*implicit context*/);
|
||||
extern tree convert_to_void (tree, const char */*implicit context*/,
|
||||
tsubst_flags_t);
|
||||
extern tree convert_force (tree, tree, int);
|
||||
extern tree build_expr_type_conversion (int, tree, bool);
|
||||
extern tree type_promotes_to (tree);
|
||||
|
@ -4336,14 +4343,17 @@ extern tree do_friend (tree, tree, tree, tree, enum overload_flags, bool);
|
|||
/* in init.c */
|
||||
extern tree expand_member_init (tree);
|
||||
extern void emit_mem_initializers (tree);
|
||||
extern tree build_aggr_init (tree, tree, int);
|
||||
extern tree build_aggr_init (tree, tree, int,
|
||||
tsubst_flags_t);
|
||||
extern int is_class_type (tree, int);
|
||||
extern tree get_type_value (tree);
|
||||
extern tree build_zero_init (tree, tree, bool);
|
||||
extern tree build_value_init (tree);
|
||||
extern tree build_offset_ref (tree, tree, bool);
|
||||
extern tree build_new (tree, tree, tree, tree, int);
|
||||
extern tree build_vec_init (tree, tree, tree, bool, int);
|
||||
extern tree build_new (tree, tree, tree, tree, int,
|
||||
tsubst_flags_t);
|
||||
extern tree build_vec_init (tree, tree, tree, bool, int,
|
||||
tsubst_flags_t);
|
||||
extern tree build_default_init (tree, tree);
|
||||
extern tree build_delete (tree, tree,
|
||||
special_function_kind,
|
||||
|
@ -4482,7 +4492,7 @@ extern tree build_typeid (tree);
|
|||
extern tree get_tinfo_decl (tree);
|
||||
extern tree get_typeid (tree);
|
||||
extern tree build_headof (tree);
|
||||
extern tree build_dynamic_cast (tree, tree);
|
||||
extern tree build_dynamic_cast (tree, tree, tsubst_flags_t);
|
||||
extern void emit_support_tinfos (void);
|
||||
extern bool emit_tinfo_decl (tree);
|
||||
|
||||
|
@ -4613,7 +4623,8 @@ extern tree finish_stmt_expr_expr (tree, tree);
|
|||
extern tree finish_stmt_expr (tree, bool);
|
||||
extern tree stmt_expr_value_expr (tree);
|
||||
extern tree perform_koenig_lookup (tree, tree);
|
||||
extern tree finish_call_expr (tree, tree, bool, bool);
|
||||
extern tree finish_call_expr (tree, tree, bool, bool,
|
||||
tsubst_flags_t);
|
||||
extern tree finish_increment_expr (tree, enum tree_code);
|
||||
extern tree finish_this_expr (void);
|
||||
extern tree finish_pseudo_destructor_expr (tree, tree, tree);
|
||||
|
@ -4762,36 +4773,49 @@ extern bool comptypes (tree, tree, int);
|
|||
extern bool compparms (const_tree, const_tree);
|
||||
extern int comp_cv_qualification (const_tree, const_tree);
|
||||
extern int comp_cv_qual_signature (tree, tree);
|
||||
extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code);
|
||||
extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code, bool);
|
||||
extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool);
|
||||
#define cxx_sizeof_nowarn(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false)
|
||||
extern tree cxx_sizeof_nowarn (tree);
|
||||
extern tree inline_conversion (tree);
|
||||
extern tree is_bitfield_expr_with_lowered_type (const_tree);
|
||||
extern tree unlowered_expr_type (const_tree);
|
||||
extern tree decay_conversion (tree);
|
||||
extern tree build_class_member_access_expr (tree, tree, tree, bool);
|
||||
extern tree finish_class_member_access_expr (tree, tree, bool);
|
||||
extern tree build_x_indirect_ref (tree, const char *);
|
||||
extern tree build_indirect_ref (tree, const char *);
|
||||
extern tree build_class_member_access_expr (tree, tree, tree, bool,
|
||||
tsubst_flags_t);
|
||||
extern tree finish_class_member_access_expr (tree, tree, bool,
|
||||
tsubst_flags_t);
|
||||
extern tree build_x_indirect_ref (tree, const char *,
|
||||
tsubst_flags_t);
|
||||
extern tree cp_build_indirect_ref (tree, const char *,
|
||||
tsubst_flags_t);
|
||||
extern tree build_array_ref (tree, tree);
|
||||
extern tree get_member_function_from_ptrfunc (tree *, tree);
|
||||
extern tree cp_build_function_call (tree, tree, tsubst_flags_t);
|
||||
extern tree build_x_binary_op (enum tree_code, tree,
|
||||
enum tree_code, tree,
|
||||
enum tree_code, bool *);
|
||||
extern tree build_x_unary_op (enum tree_code, tree);
|
||||
enum tree_code, bool *,
|
||||
tsubst_flags_t);
|
||||
extern tree build_x_unary_op (enum tree_code, tree,
|
||||
tsubst_flags_t);
|
||||
extern tree cp_build_unary_op (enum tree_code, tree, int,
|
||||
tsubst_flags_t);
|
||||
extern tree unary_complex_lvalue (enum tree_code, tree);
|
||||
extern tree build_x_conditional_expr (tree, tree, tree);
|
||||
extern tree build_x_conditional_expr (tree, tree, tree,
|
||||
tsubst_flags_t);
|
||||
extern tree build_x_compound_expr_from_list (tree, const char *);
|
||||
extern tree build_x_compound_expr (tree, tree);
|
||||
extern tree build_compound_expr (tree, tree);
|
||||
extern tree build_static_cast (tree, tree);
|
||||
extern tree build_reinterpret_cast (tree, tree);
|
||||
extern tree build_const_cast (tree, tree);
|
||||
extern tree build_c_cast (tree, tree);
|
||||
extern tree build_x_modify_expr (tree, enum tree_code, tree);
|
||||
extern tree build_modify_expr (tree, enum tree_code, tree);
|
||||
extern tree build_x_compound_expr (tree, tree, tsubst_flags_t);
|
||||
extern tree build_compound_expr (tree, tree, tsubst_flags_t);
|
||||
extern tree build_static_cast (tree, tree, tsubst_flags_t);
|
||||
extern tree build_reinterpret_cast (tree, tree, tsubst_flags_t);
|
||||
extern tree build_const_cast (tree, tree, tsubst_flags_t);
|
||||
extern tree build_c_cast (tree, tree, tsubst_flags_t);
|
||||
extern tree build_x_modify_expr (tree, enum tree_code, tree,
|
||||
tsubst_flags_t);
|
||||
extern tree cp_build_modify_expr (tree, enum tree_code, tree,
|
||||
tsubst_flags_t);
|
||||
extern tree convert_for_initialization (tree, tree, tree, int,
|
||||
const char *, tree, int);
|
||||
const char *, tree, int,
|
||||
tsubst_flags_t);
|
||||
extern int comp_ptr_ttypes (tree, tree);
|
||||
extern bool comp_ptr_ttypes_const (tree, tree);
|
||||
extern int ptr_reasonably_similar (const_tree, const_tree);
|
||||
|
@ -4805,21 +4829,22 @@ extern tree build_ptrmemfunc1 (tree, tree, tree);
|
|||
extern void expand_ptrmemfunc_cst (tree, tree *, tree *);
|
||||
extern tree type_after_usual_arithmetic_conversions (tree, tree);
|
||||
extern tree composite_pointer_type (tree, tree, tree, tree,
|
||||
const char*);
|
||||
const char*, tsubst_flags_t);
|
||||
extern tree merge_types (tree, tree);
|
||||
extern tree check_return_expr (tree, bool *);
|
||||
#define cp_build_binary_op(code, arg1, arg2) \
|
||||
build_binary_op(code, arg1, arg2, 1)
|
||||
extern tree cp_build_binary_op (enum tree_code, tree, tree,
|
||||
tsubst_flags_t);
|
||||
#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
|
||||
extern tree build_ptrmemfunc_access_expr (tree, tree);
|
||||
extern tree build_address (tree);
|
||||
extern tree build_nop (tree, tree);
|
||||
extern tree non_reference (tree);
|
||||
extern tree lookup_anon_field (tree, tree);
|
||||
extern bool invalid_nonstatic_memfn_p (const_tree);
|
||||
extern bool invalid_nonstatic_memfn_p (const_tree, tsubst_flags_t);
|
||||
extern tree convert_member_func_to_ptr (tree, tree);
|
||||
extern tree convert_ptrmem (tree, tree, bool, bool);
|
||||
extern int lvalue_or_else (const_tree, enum lvalue_use);
|
||||
extern int lvalue_or_else (const_tree, enum lvalue_use,
|
||||
tsubst_flags_t);
|
||||
extern int lvalue_p (const_tree);
|
||||
|
||||
/* in typeck2.c */
|
||||
|
@ -4840,7 +4865,7 @@ extern tree digest_init (tree, tree);
|
|||
extern tree build_scoped_ref (tree, tree, tree *);
|
||||
extern tree build_x_arrow (tree);
|
||||
extern tree build_m_component_ref (tree, tree);
|
||||
extern tree build_functional_cast (tree, tree);
|
||||
extern tree build_functional_cast (tree, tree, tsubst_flags_t);
|
||||
extern tree add_exception_specifier (tree, tree, int);
|
||||
extern tree merge_exception_specifiers (tree, tree);
|
||||
|
||||
|
|
64
gcc/cp/cvt.c
64
gcc/cp/cvt.c
|
@ -326,7 +326,7 @@ build_up_reference (tree type, tree arg, int flags, tree decl)
|
|||
/* If we had a way to wrap this up, and say, if we ever needed its
|
||||
address, transform all occurrences of the register, into a memory
|
||||
reference we could win better. */
|
||||
rval = build_unary_op (ADDR_EXPR, arg, 1);
|
||||
rval = cp_build_unary_op (ADDR_EXPR, arg, 1, tf_warning_or_error);
|
||||
if (rval == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
@ -470,7 +470,7 @@ convert_to_reference (tree reftype, tree expr, int convtype,
|
|||
warning (0, "casting %qT to %qT does not dereference pointer",
|
||||
intype, reftype);
|
||||
|
||||
rval = build_unary_op (ADDR_EXPR, expr, 0);
|
||||
rval = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error);
|
||||
if (rval != error_mark_node)
|
||||
rval = convert_force (build_pointer_type (TREE_TYPE (reftype)),
|
||||
rval, 0);
|
||||
|
@ -480,7 +480,8 @@ convert_to_reference (tree reftype, tree expr, int convtype,
|
|||
else
|
||||
{
|
||||
rval = convert_for_initialization (NULL_TREE, type, expr, flags,
|
||||
"converting", 0, 0);
|
||||
"converting", 0, 0,
|
||||
tf_warning_or_error);
|
||||
if (rval == NULL_TREE || rval == error_mark_node)
|
||||
return rval;
|
||||
warn_ref_binding (reftype, intype, decl);
|
||||
|
@ -630,7 +631,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
|
|||
|
||||
if (code == VOID_TYPE && (convtype & CONV_STATIC))
|
||||
{
|
||||
e = convert_to_void (e, /*implicit=*/NULL);
|
||||
e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -734,7 +735,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
|
|||
ctor = build_special_member_call (NULL_TREE,
|
||||
complete_ctor_identifier,
|
||||
build_tree_list (NULL_TREE, ctor),
|
||||
type, flags);
|
||||
type, flags,
|
||||
tf_warning_or_error);
|
||||
if (ctor)
|
||||
return build_cplus_new (type, ctor);
|
||||
}
|
||||
|
@ -763,18 +765,19 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
|
|||
IMPLICIT is tells us the context of an implicit void conversion. */
|
||||
|
||||
tree
|
||||
convert_to_void (tree expr, const char *implicit)
|
||||
convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain)
|
||||
{
|
||||
if (expr == error_mark_node
|
||||
|| TREE_TYPE (expr) == error_mark_node)
|
||||
return error_mark_node;
|
||||
if (!TREE_TYPE (expr))
|
||||
return expr;
|
||||
if (invalid_nonstatic_memfn_p (expr))
|
||||
if (invalid_nonstatic_memfn_p (expr, complain))
|
||||
return error_mark_node;
|
||||
if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
|
||||
{
|
||||
error ("pseudo-destructor is not called");
|
||||
if (complain & tf_error)
|
||||
error ("pseudo-destructor is not called");
|
||||
return error_mark_node;
|
||||
}
|
||||
if (VOID_TYPE_P (TREE_TYPE (expr)))
|
||||
|
@ -788,10 +791,10 @@ convert_to_void (tree expr, const char *implicit)
|
|||
tree op2 = TREE_OPERAND (expr,2);
|
||||
tree new_op1 = convert_to_void
|
||||
(op1, (implicit && !TREE_SIDE_EFFECTS (op2)
|
||||
? "second operand of conditional" : NULL));
|
||||
? "second operand of conditional" : NULL), complain);
|
||||
tree new_op2 = convert_to_void
|
||||
(op2, (implicit && !TREE_SIDE_EFFECTS (op1)
|
||||
? "third operand of conditional" : NULL));
|
||||
? "third operand of conditional" : NULL), complain);
|
||||
|
||||
expr = build3 (COND_EXPR, TREE_TYPE (new_op1),
|
||||
TREE_OPERAND (expr, 0), new_op1, new_op2);
|
||||
|
@ -804,7 +807,7 @@ convert_to_void (tree expr, const char *implicit)
|
|||
tree op1 = TREE_OPERAND (expr,1);
|
||||
tree new_op1 = convert_to_void
|
||||
(op1, (implicit && !TREE_NO_WARNING (expr)
|
||||
? "right-hand operand of comma" : NULL));
|
||||
? "right-hand operand of comma" : NULL), complain);
|
||||
|
||||
if (new_op1 != op1)
|
||||
{
|
||||
|
@ -834,14 +837,20 @@ convert_to_void (tree expr, const char *implicit)
|
|||
|
||||
/* Can't load the value if we don't know the type. */
|
||||
if (is_volatile && !is_complete)
|
||||
warning (0, "object of incomplete type %qT will not be accessed in %s",
|
||||
type, implicit ? implicit : "void context");
|
||||
{
|
||||
if (complain & tf_warning)
|
||||
warning (0, "object of incomplete type %qT will not be accessed in %s",
|
||||
type, implicit ? implicit : "void context");
|
||||
}
|
||||
/* Don't load the value if this is an implicit dereference, or if
|
||||
the type needs to be handled by ctors/dtors. */
|
||||
else if (is_volatile && (is_reference || TREE_ADDRESSABLE (type)))
|
||||
warning (0, "object of type %qT will not be accessed in %s",
|
||||
TREE_TYPE (TREE_OPERAND (expr, 0)),
|
||||
implicit ? implicit : "void context");
|
||||
{
|
||||
if (complain & tf_warning)
|
||||
warning (0, "object of type %qT will not be accessed in %s",
|
||||
TREE_TYPE (TREE_OPERAND (expr, 0)),
|
||||
implicit ? implicit : "void context");
|
||||
}
|
||||
if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type))
|
||||
expr = TREE_OPERAND (expr, 0);
|
||||
|
||||
|
@ -854,7 +863,7 @@ convert_to_void (tree expr, const char *implicit)
|
|||
tree type = TREE_TYPE (expr);
|
||||
int is_complete = COMPLETE_TYPE_P (complete_type (type));
|
||||
|
||||
if (TYPE_VOLATILE (type) && !is_complete)
|
||||
if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning))
|
||||
warning (0, "object %qE of incomplete type %qT will not be accessed in %s",
|
||||
expr, type, implicit ? implicit : "void context");
|
||||
break;
|
||||
|
@ -892,15 +901,19 @@ convert_to_void (tree expr, const char *implicit)
|
|||
{
|
||||
/* [over.over] enumerates the places where we can take the address
|
||||
of an overloaded function, and this is not one of them. */
|
||||
error ("%s cannot resolve address of overloaded function",
|
||||
implicit ? implicit : "void cast");
|
||||
if (complain & tf_error)
|
||||
error ("%s cannot resolve address of overloaded function",
|
||||
implicit ? implicit : "void cast");
|
||||
else
|
||||
return error_mark_node;
|
||||
expr = void_zero_node;
|
||||
}
|
||||
else if (implicit && probe == expr && is_overloaded_fn (probe))
|
||||
{
|
||||
/* Only warn when there is no &. */
|
||||
warning (OPT_Waddress, "%s is a reference, not call, to function %qE",
|
||||
implicit, expr);
|
||||
if (complain & tf_warning)
|
||||
warning (OPT_Waddress, "%s is a reference, not call, to function %qE",
|
||||
implicit, expr);
|
||||
if (TREE_CODE (expr) == COMPONENT_REF)
|
||||
expr = TREE_OPERAND (expr, 0);
|
||||
}
|
||||
|
@ -915,8 +928,10 @@ convert_to_void (tree expr, const char *implicit)
|
|||
{
|
||||
/* The middle end does not warn about expressions that have
|
||||
been explicitly cast to void, so we must do so here. */
|
||||
if (!TREE_SIDE_EFFECTS (expr))
|
||||
warning (OPT_Wunused_value, "%s has no effect", implicit);
|
||||
if (!TREE_SIDE_EFFECTS (expr)) {
|
||||
if (complain & tf_warning)
|
||||
warning (OPT_Wunused_value, "%s has no effect", implicit);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree e;
|
||||
|
@ -939,7 +954,7 @@ convert_to_void (tree expr, const char *implicit)
|
|||
|
||||
code = TREE_CODE (e);
|
||||
class = TREE_CODE_CLASS (code);
|
||||
if (class == tcc_comparison
|
||||
if ((class == tcc_comparison
|
||||
|| class == tcc_unary
|
||||
|| (class == tcc_binary
|
||||
&& !(code == MODIFY_EXPR
|
||||
|
@ -948,6 +963,7 @@ convert_to_void (tree expr, const char *implicit)
|
|||
|| code == PREINCREMENT_EXPR
|
||||
|| code == POSTDECREMENT_EXPR
|
||||
|| code == POSTINCREMENT_EXPR)))
|
||||
&& (complain & tf_warning))
|
||||
warning (OPT_Wunused_value, "value computed is not used");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5027,7 +5027,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
|
|||
saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
|
||||
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
|
||||
}
|
||||
init = build_aggr_init (decl, init, flags);
|
||||
init = build_aggr_init (decl, init, flags, tf_warning_or_error);
|
||||
if (building_stmt_tree ())
|
||||
current_stmt_tree ()->stmts_are_full_exprs_p =
|
||||
saved_stmts_are_full_exprs_p;
|
||||
|
@ -5978,7 +5978,7 @@ register_dtor_fn (tree decl)
|
|||
addr = build_address (decl);
|
||||
/* The declared type of the parameter to "__cxa_atexit" is
|
||||
"void *". For plain "T*", we could just let the
|
||||
machinery in build_function_call convert it -- but if the
|
||||
machinery in cp_build_function_call convert it -- but if the
|
||||
type is "cv-qualified T *", then we need to convert it
|
||||
before passing it in, to avoid spurious errors. */
|
||||
addr = build_nop (ptr_type_node, addr);
|
||||
|
@ -5990,7 +5990,8 @@ register_dtor_fn (tree decl)
|
|||
other value. */
|
||||
addr = null_pointer_node;
|
||||
args = tree_cons (NULL_TREE,
|
||||
build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0),
|
||||
cp_build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0,
|
||||
tf_warning_or_error),
|
||||
NULL_TREE);
|
||||
if (targetm.cxx.use_aeabi_atexit ())
|
||||
{
|
||||
|
@ -6005,7 +6006,8 @@ register_dtor_fn (tree decl)
|
|||
}
|
||||
else
|
||||
args = tree_cons (NULL_TREE, cleanup, NULL_TREE);
|
||||
return build_function_call (get_atexit_node (), args);
|
||||
return cp_build_function_call (get_atexit_node (), args,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* DECL is a VAR_DECL with static storage duration. INIT, if present,
|
||||
|
@ -7082,7 +7084,8 @@ compute_array_index_type (tree name, tree size)
|
|||
processing_template_decl = 0;
|
||||
itype = cp_build_binary_op (MINUS_EXPR,
|
||||
cp_convert (ssizetype, size),
|
||||
cp_convert (ssizetype, integer_one_node));
|
||||
cp_convert (ssizetype, integer_one_node),
|
||||
tf_warning_or_error);
|
||||
itype = fold (itype);
|
||||
processing_template_decl = saved_processing_template_decl;
|
||||
|
||||
|
@ -10820,7 +10823,8 @@ finish_enum (tree enumtype)
|
|||
saved_location = input_location;
|
||||
input_location = DECL_SOURCE_LOCATION (decl);
|
||||
value = perform_implicit_conversion (underlying_type,
|
||||
DECL_INITIAL (decl));
|
||||
DECL_INITIAL (decl),
|
||||
tf_warning_or_error);
|
||||
input_location = saved_location;
|
||||
|
||||
/* Do not clobber shared ints. */
|
||||
|
@ -11282,7 +11286,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
|
|||
gcc_assert (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE);
|
||||
|
||||
cp_function_chain->x_current_class_ref
|
||||
= build_indirect_ref (t, NULL);
|
||||
= cp_build_indirect_ref (t, NULL, tf_warning_or_error);
|
||||
cp_function_chain->x_current_class_ptr = t;
|
||||
|
||||
/* Constructors and destructors need to know whether they're "in
|
||||
|
@ -12199,8 +12203,9 @@ cxx_maybe_build_cleanup (tree decl)
|
|||
fn = lookup_name (id);
|
||||
arg = build_address (decl);
|
||||
mark_used (decl);
|
||||
cleanup = build_function_call (fn, build_tree_list (NULL_TREE,
|
||||
arg));
|
||||
cleanup = cp_build_function_call (fn, build_tree_list (NULL_TREE,
|
||||
arg),
|
||||
tf_warning_or_error);
|
||||
}
|
||||
/* Handle ordinary C++ destructors. */
|
||||
type = TREE_TYPE (decl);
|
||||
|
@ -12224,7 +12229,7 @@ cxx_maybe_build_cleanup (tree decl)
|
|||
call = build_delete (TREE_TYPE (addr), addr,
|
||||
sfk_complete_destructor, flags, 0);
|
||||
if (cleanup)
|
||||
cleanup = build_compound_expr (cleanup, call);
|
||||
cleanup = build_compound_expr (cleanup, call, tf_warning_or_error);
|
||||
else
|
||||
cleanup = call;
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ grok_array_decl (tree array_expr, tree index_exp)
|
|||
if (MAYBE_CLASS_TYPE_P (type) || MAYBE_CLASS_TYPE_P (TREE_TYPE (index_exp)))
|
||||
expr = build_new_op (ARRAY_REF, LOOKUP_NORMAL,
|
||||
array_expr, index_exp, NULL_TREE,
|
||||
/*overloaded_p=*/NULL);
|
||||
/*overloaded_p=*/NULL, tf_warning_or_error);
|
||||
else
|
||||
{
|
||||
tree p1, p2, i1, i2;
|
||||
|
@ -1190,7 +1190,7 @@ build_anon_union_vars (tree type, tree object)
|
|||
DECL_NAME (field), NULL_TREE);
|
||||
else
|
||||
ref = build_class_member_access_expr (object, field, NULL_TREE,
|
||||
false);
|
||||
false, tf_warning_or_error);
|
||||
|
||||
if (DECL_NAME (field))
|
||||
{
|
||||
|
@ -2436,13 +2436,15 @@ get_guard_cond (tree guard)
|
|||
guard_value = integer_one_node;
|
||||
if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
|
||||
guard_value = convert (TREE_TYPE (guard), guard_value);
|
||||
guard = cp_build_binary_op (BIT_AND_EXPR, guard, guard_value);
|
||||
guard = cp_build_binary_op (BIT_AND_EXPR, guard, guard_value,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
guard_value = integer_zero_node;
|
||||
if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
|
||||
guard_value = convert (TREE_TYPE (guard), guard_value);
|
||||
return cp_build_binary_op (EQ_EXPR, guard, guard_value);
|
||||
return cp_build_binary_op (EQ_EXPR, guard, guard_value,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Return an expression which sets the GUARD variable, indicating that
|
||||
|
@ -2458,7 +2460,8 @@ set_guard (tree guard)
|
|||
guard_init = integer_one_node;
|
||||
if (!same_type_p (TREE_TYPE (guard_init), TREE_TYPE (guard)))
|
||||
guard_init = convert (TREE_TYPE (guard), guard_init);
|
||||
return build_modify_expr (guard, NOP_EXPR, guard_init);
|
||||
return cp_build_modify_expr (guard, NOP_EXPR, guard_init,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Start the process of running a particular set of global constructors
|
||||
|
@ -2787,17 +2790,21 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp)
|
|||
else if (initp)
|
||||
guard_cond
|
||||
= cp_build_binary_op (EQ_EXPR,
|
||||
build_unary_op (PREINCREMENT_EXPR,
|
||||
cp_build_unary_op (PREINCREMENT_EXPR,
|
||||
guard,
|
||||
/*noconvert=*/1),
|
||||
integer_one_node);
|
||||
/*noconvert=*/1,
|
||||
tf_warning_or_error),
|
||||
integer_one_node,
|
||||
tf_warning_or_error);
|
||||
else
|
||||
guard_cond
|
||||
= cp_build_binary_op (EQ_EXPR,
|
||||
build_unary_op (PREDECREMENT_EXPR,
|
||||
cp_build_unary_op (PREDECREMENT_EXPR,
|
||||
guard,
|
||||
/*noconvert=*/1),
|
||||
integer_zero_node);
|
||||
/*noconvert=*/1,
|
||||
tf_warning_or_error),
|
||||
integer_zero_node,
|
||||
tf_warning_or_error);
|
||||
|
||||
guard_if_stmt = begin_if_stmt ();
|
||||
finish_if_stmt_cond (guard_cond, guard_if_stmt);
|
||||
|
@ -2849,8 +2856,9 @@ do_static_initialization_or_destruction (tree vars, bool initp)
|
|||
init_if_stmt = begin_if_stmt ();
|
||||
cond = initp ? integer_one_node : integer_zero_node;
|
||||
cond = cp_build_binary_op (EQ_EXPR,
|
||||
initialize_p_decl,
|
||||
cond);
|
||||
initialize_p_decl,
|
||||
cond,
|
||||
tf_warning_or_error);
|
||||
finish_if_stmt_cond (cond, init_if_stmt);
|
||||
|
||||
node = vars;
|
||||
|
@ -2882,7 +2890,8 @@ do_static_initialization_or_destruction (tree vars, bool initp)
|
|||
priority_if_stmt = begin_if_stmt ();
|
||||
cond = cp_build_binary_op (EQ_EXPR,
|
||||
priority_decl,
|
||||
build_int_cst (NULL_TREE, priority));
|
||||
build_int_cst (NULL_TREE, priority),
|
||||
tf_warning_or_error);
|
||||
finish_if_stmt_cond (cond, priority_if_stmt);
|
||||
|
||||
/* Process initializers with same priority. */
|
||||
|
@ -3031,7 +3040,8 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
|
|||
arguments = tree_cons (NULL_TREE,
|
||||
build_int_cst (NULL_TREE, constructor_p),
|
||||
arguments);
|
||||
finish_expr_stmt (build_function_call (fndecl, arguments));
|
||||
finish_expr_stmt (cp_build_function_call (fndecl, arguments,
|
||||
tf_warning_or_error));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3534,7 +3544,7 @@ build_offset_ref_call_from_tree (tree fn, tree args)
|
|||
args = build_non_dependent_args (args);
|
||||
object = build_non_dependent_expr (object);
|
||||
if (TREE_CODE (fn) == DOTSTAR_EXPR)
|
||||
object = build_unary_op (ADDR_EXPR, object, 0);
|
||||
object = cp_build_unary_op (ADDR_EXPR, object, 0, tf_warning_or_error);
|
||||
args = tree_cons (NULL_TREE, object, args);
|
||||
/* Now that the arguments are done, transform FN. */
|
||||
fn = build_non_dependent_expr (fn);
|
||||
|
@ -3548,13 +3558,14 @@ build_offset_ref_call_from_tree (tree fn, tree args)
|
|||
void B::g() { (this->*p)(); } */
|
||||
if (TREE_CODE (fn) == OFFSET_REF)
|
||||
{
|
||||
tree object_addr = build_unary_op (ADDR_EXPR, object, 0);
|
||||
tree object_addr = cp_build_unary_op (ADDR_EXPR, object, 0,
|
||||
tf_warning_or_error);
|
||||
fn = TREE_OPERAND (fn, 1);
|
||||
fn = get_member_function_from_ptrfunc (&object_addr, fn);
|
||||
args = tree_cons (NULL_TREE, object_addr, args);
|
||||
}
|
||||
|
||||
expr = build_function_call (fn, args);
|
||||
expr = cp_build_function_call (fn, args, tf_warning_or_error);
|
||||
if (processing_template_decl && expr != error_mark_node)
|
||||
return build_min_non_dep_call_list (expr, orig_fn, orig_args);
|
||||
return expr;
|
||||
|
|
|
@ -176,8 +176,9 @@ do_get_exception_ptr (void)
|
|||
fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
|
||||
}
|
||||
|
||||
return build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
|
||||
NULL_TREE));
|
||||
return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
|
||||
NULL_TREE),
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Build up a call to __cxa_begin_catch, to tell the runtime that the
|
||||
|
@ -196,8 +197,9 @@ do_begin_catch (void)
|
|||
fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
|
||||
}
|
||||
|
||||
return build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
|
||||
NULL_TREE));
|
||||
return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
|
||||
NULL_TREE),
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Returns nonzero if cleaning up an exception of type TYPE (which can be
|
||||
|
@ -235,7 +237,7 @@ do_end_catch (tree type)
|
|||
TREE_NOTHROW (fn) = 0;
|
||||
}
|
||||
|
||||
cleanup = build_function_call (fn, NULL_TREE);
|
||||
cleanup = cp_build_function_call (fn, NULL_TREE, tf_warning_or_error);
|
||||
TREE_NOTHROW (cleanup) = dtor_nothrow (type);
|
||||
|
||||
return cleanup;
|
||||
|
@ -377,7 +379,7 @@ initialize_handler_parm (tree decl, tree exp)
|
|||
pointer catch parm with the address of the temporary. */
|
||||
if (TREE_CODE (init_type) == REFERENCE_TYPE
|
||||
&& TYPE_PTR_P (TREE_TYPE (init_type)))
|
||||
exp = build_unary_op (ADDR_EXPR, exp, 1);
|
||||
exp = cp_build_unary_op (ADDR_EXPR, exp, 1, tf_warning_or_error);
|
||||
|
||||
exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
|
||||
|
||||
|
@ -434,7 +436,7 @@ expand_start_catch_block (tree decl)
|
|||
exp = build2 (POINTER_PLUS_EXPR, TREE_TYPE (exp), exp,
|
||||
fold_build1 (NEGATE_EXPR, sizetype,
|
||||
TYPE_SIZE_UNIT (TREE_TYPE (exp))));
|
||||
exp = build_indirect_ref (exp, NULL);
|
||||
exp = cp_build_indirect_ref (exp, NULL, tf_warning_or_error);
|
||||
initialize_handler_parm (decl, exp);
|
||||
return type;
|
||||
}
|
||||
|
@ -546,8 +548,10 @@ do_allocate_exception (tree type)
|
|||
fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
|
||||
}
|
||||
|
||||
return build_function_call (fn, tree_cons (NULL_TREE, size_in_bytes (type),
|
||||
NULL_TREE));
|
||||
return cp_build_function_call (fn,
|
||||
tree_cons (NULL_TREE, size_in_bytes (type),
|
||||
NULL_TREE),
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Call __cxa_free_exception from a cleanup. This is never invoked
|
||||
|
@ -566,7 +570,8 @@ do_free_exception (tree ptr)
|
|||
void_list_node));
|
||||
}
|
||||
|
||||
return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
|
||||
return cp_build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE),
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
|
||||
|
@ -644,7 +649,8 @@ build_throw (tree exp)
|
|||
return error_mark_node;
|
||||
}
|
||||
fn = OVL_CURRENT (fn);
|
||||
exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
|
||||
exp = cp_build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE),
|
||||
tf_warning_or_error);
|
||||
}
|
||||
else if (exp)
|
||||
{
|
||||
|
@ -708,7 +714,7 @@ build_throw (tree exp)
|
|||
allocate_expr = get_target_expr (allocate_expr);
|
||||
ptr = TARGET_EXPR_SLOT (allocate_expr);
|
||||
object = build_nop (build_pointer_type (temp_type), ptr);
|
||||
object = build_indirect_ref (object, NULL);
|
||||
object = cp_build_indirect_ref (object, NULL, tf_warning_or_error);
|
||||
|
||||
elided = (TREE_CODE (exp) == TARGET_EXPR);
|
||||
|
||||
|
@ -733,7 +739,7 @@ build_throw (tree exp)
|
|||
(object, complete_ctor_identifier,
|
||||
build_tree_list (NULL_TREE, exp),
|
||||
TREE_TYPE (object),
|
||||
flags));
|
||||
flags, tf_warning_or_error));
|
||||
if (exp == error_mark_node)
|
||||
{
|
||||
error (" in thrown expression");
|
||||
|
@ -812,7 +818,7 @@ build_throw (tree exp)
|
|||
tmp = tree_cons (NULL_TREE, throw_type, tmp);
|
||||
tmp = tree_cons (NULL_TREE, ptr, tmp);
|
||||
/* ??? Indicate that this function call throws throw_type. */
|
||||
tmp = build_function_call (fn, tmp);
|
||||
tmp = cp_build_function_call (fn, tmp, tf_warning_or_error);
|
||||
|
||||
/* Tack on the initialization stuff. */
|
||||
exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
|
||||
|
@ -831,7 +837,7 @@ build_throw (tree exp)
|
|||
|
||||
/* ??? Indicate that this function call allows exceptions of the type
|
||||
of the enclosing catch block (if known). */
|
||||
exp = build_function_call (fn, NULL_TREE);
|
||||
exp = cp_build_function_call (fn, NULL_TREE, tf_warning_or_error);
|
||||
}
|
||||
|
||||
exp = build1 (THROW_EXPR, void_type_node, exp);
|
||||
|
|
260
gcc/cp/init.c
260
gcc/cp/init.c
|
@ -39,8 +39,8 @@ along with GCC; see the file COPYING3. If not see
|
|||
static bool begin_init_stmts (tree *, tree *);
|
||||
static tree finish_init_stmts (bool, tree, tree);
|
||||
static void construct_virtual_base (tree, tree);
|
||||
static void expand_aggr_init_1 (tree, tree, tree, tree, int);
|
||||
static void expand_default_init (tree, tree, tree, tree, int);
|
||||
static void expand_aggr_init_1 (tree, tree, tree, tree, int, tsubst_flags_t);
|
||||
static void expand_default_init (tree, tree, tree, tree, int, tsubst_flags_t);
|
||||
static tree build_vec_delete_1 (tree, tree, tree, special_function_kind, int);
|
||||
static void perform_member_init (tree, tree);
|
||||
static tree build_builtin_delete_call (tree);
|
||||
|
@ -353,7 +353,8 @@ build_value_init_1 (tree type, bool have_ctor)
|
|||
return build_cplus_new
|
||||
(type,
|
||||
build_special_member_call (NULL_TREE, complete_ctor_identifier,
|
||||
NULL_TREE, type, LOOKUP_NORMAL));
|
||||
NULL_TREE, type, LOOKUP_NORMAL,
|
||||
tf_warning_or_error));
|
||||
else if (TREE_CODE (type) != UNION_TYPE)
|
||||
{
|
||||
tree field, init;
|
||||
|
@ -401,7 +402,7 @@ build_value_init_1 (tree type, bool have_ctor)
|
|||
cp_gimplify_init_expr will know how to handle it. */
|
||||
tree ctor = build_special_member_call
|
||||
(NULL_TREE, complete_ctor_identifier,
|
||||
NULL_TREE, type, LOOKUP_NORMAL);
|
||||
NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error);
|
||||
|
||||
ctor = build_cplus_new (type, ctor);
|
||||
init = build2 (INIT_EXPR, void_type_node,
|
||||
|
@ -487,7 +488,8 @@ perform_member_init (tree member, tree init)
|
|||
/* Get an lvalue for the data member. */
|
||||
decl = build_class_member_access_expr (current_class_ref, member,
|
||||
/*access_path=*/NULL_TREE,
|
||||
/*preserve_reference=*/true);
|
||||
/*preserve_reference=*/true,
|
||||
tf_warning_or_error);
|
||||
if (decl == error_mark_node)
|
||||
return;
|
||||
|
||||
|
@ -513,10 +515,12 @@ perform_member_init (tree member, tree init)
|
|||
/* Initialization of one array from another. */
|
||||
finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init),
|
||||
/*explicit_default_init_p=*/false,
|
||||
/* from_array=*/1));
|
||||
/* from_array=*/1,
|
||||
tf_warning_or_error));
|
||||
}
|
||||
else
|
||||
finish_expr_stmt (build_aggr_init (decl, init, 0));
|
||||
finish_expr_stmt (build_aggr_init (decl, init, 0,
|
||||
tf_warning_or_error));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -544,7 +548,8 @@ perform_member_init (tree member, tree init)
|
|||
init = build_x_compound_expr_from_list (init, "member initializer");
|
||||
|
||||
if (init)
|
||||
finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
|
||||
finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
|
||||
tf_warning_or_error));
|
||||
}
|
||||
|
||||
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
|
||||
|
@ -553,7 +558,8 @@ perform_member_init (tree member, tree init)
|
|||
|
||||
expr = build_class_member_access_expr (current_class_ref, member,
|
||||
/*access_path=*/NULL_TREE,
|
||||
/*preserve_reference=*/false);
|
||||
/*preserve_reference=*/false,
|
||||
tf_warning_or_error);
|
||||
expr = build_delete (type, expr, sfk_complete_destructor,
|
||||
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
|
||||
|
||||
|
@ -855,9 +861,11 @@ emit_mem_initializers (tree mem_inits)
|
|||
base_addr = build_base_path (PLUS_EXPR, current_class_ptr,
|
||||
subobject, 1);
|
||||
expand_aggr_init_1 (subobject, NULL_TREE,
|
||||
build_indirect_ref (base_addr, NULL),
|
||||
cp_build_indirect_ref (base_addr, NULL,
|
||||
tf_warning_or_error),
|
||||
arguments,
|
||||
LOOKUP_NORMAL);
|
||||
LOOKUP_NORMAL,
|
||||
tf_warning_or_error);
|
||||
expand_cleanup_for_base (subobject, NULL_TREE);
|
||||
}
|
||||
|
||||
|
@ -938,7 +946,7 @@ expand_virtual_init (tree binfo, tree decl)
|
|||
TREE_TYPE (vtt_parm),
|
||||
vtt_parm,
|
||||
vtt_index);
|
||||
vtbl2 = build_indirect_ref (vtbl2, NULL);
|
||||
vtbl2 = cp_build_indirect_ref (vtbl2, NULL, tf_warning_or_error);
|
||||
vtbl2 = convert (TREE_TYPE (vtbl), vtbl2);
|
||||
|
||||
/* The actual initializer is the VTT value only in the subobject
|
||||
|
@ -953,13 +961,15 @@ expand_virtual_init (tree binfo, tree decl)
|
|||
}
|
||||
|
||||
/* Compute the location of the vtpr. */
|
||||
vtbl_ptr = build_vfield_ref (build_indirect_ref (decl, NULL),
|
||||
vtbl_ptr = build_vfield_ref (cp_build_indirect_ref (decl, NULL,
|
||||
tf_warning_or_error),
|
||||
TREE_TYPE (binfo));
|
||||
gcc_assert (vtbl_ptr != error_mark_node);
|
||||
|
||||
/* Assign the vtable to the vptr. */
|
||||
vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0);
|
||||
finish_expr_stmt (build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl));
|
||||
finish_expr_stmt (cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
|
||||
tf_warning_or_error));
|
||||
}
|
||||
|
||||
/* If an exception is thrown in a constructor, those base classes already
|
||||
|
@ -981,7 +991,8 @@ expand_cleanup_for_base (tree binfo, tree flag)
|
|||
base_dtor_identifier,
|
||||
NULL_TREE,
|
||||
binfo,
|
||||
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL);
|
||||
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
|
||||
tf_warning_or_error);
|
||||
if (flag)
|
||||
expr = fold_build3 (COND_EXPR, void_type_node,
|
||||
c_common_truthvalue_conversion (flag),
|
||||
|
@ -1025,7 +1036,7 @@ construct_virtual_base (tree vbase, tree arguments)
|
|||
exp = convert_to_base_statically (current_class_ref, vbase);
|
||||
|
||||
expand_aggr_init_1 (vbase, current_class_ref, exp, arguments,
|
||||
LOOKUP_COMPLAIN);
|
||||
LOOKUP_COMPLAIN, tf_warning_or_error);
|
||||
finish_then_clause (inner_if_stmt);
|
||||
finish_if_stmt (inner_if_stmt);
|
||||
|
||||
|
@ -1230,7 +1241,7 @@ expand_member_init (tree name)
|
|||
perform the initialization, but not both, as it would be ambiguous. */
|
||||
|
||||
tree
|
||||
build_aggr_init (tree exp, tree init, int flags)
|
||||
build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
|
||||
{
|
||||
tree stmt_expr;
|
||||
tree compound_stmt;
|
||||
|
@ -1257,7 +1268,8 @@ build_aggr_init (tree exp, tree init, int flags)
|
|||
initialization form -- unless the initializer is "()". */
|
||||
if (init && TREE_CODE (init) == TREE_LIST)
|
||||
{
|
||||
error ("bad array initializer");
|
||||
if (complain & tf_error)
|
||||
error ("bad array initializer");
|
||||
return error_mark_node;
|
||||
}
|
||||
/* Must arrange to initialize each element of EXP
|
||||
|
@ -1270,7 +1282,8 @@ build_aggr_init (tree exp, tree init, int flags)
|
|||
stmt_expr = build_vec_init (exp, NULL_TREE, init,
|
||||
/*explicit_default_init_p=*/false,
|
||||
itype && same_type_p (itype,
|
||||
TREE_TYPE (exp)));
|
||||
TREE_TYPE (exp)),
|
||||
complain);
|
||||
TREE_READONLY (exp) = was_const;
|
||||
TREE_THIS_VOLATILE (exp) = was_volatile;
|
||||
TREE_TYPE (exp) = type;
|
||||
|
@ -1287,7 +1300,7 @@ build_aggr_init (tree exp, tree init, int flags)
|
|||
destroy_temps = stmts_are_full_exprs_p ();
|
||||
current_stmt_tree ()->stmts_are_full_exprs_p = 0;
|
||||
expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
|
||||
init, LOOKUP_NORMAL|flags);
|
||||
init, LOOKUP_NORMAL|flags, complain);
|
||||
stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
|
||||
current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
|
||||
TREE_READONLY (exp) = was_const;
|
||||
|
@ -1297,7 +1310,8 @@ build_aggr_init (tree exp, tree init, int flags)
|
|||
}
|
||||
|
||||
static void
|
||||
expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags)
|
||||
expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
tree type = TREE_TYPE (exp);
|
||||
tree ctor_name;
|
||||
|
@ -1364,9 +1378,10 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags)
|
|||
else
|
||||
ctor_name = base_ctor_identifier;
|
||||
|
||||
rval = build_special_member_call (exp, ctor_name, parms, binfo, flags);
|
||||
rval = build_special_member_call (exp, ctor_name, parms, binfo, flags,
|
||||
complain);
|
||||
if (TREE_SIDE_EFFECTS (rval))
|
||||
finish_expr_stmt (convert_to_void (rval, NULL));
|
||||
finish_expr_stmt (convert_to_void (rval, NULL, complain));
|
||||
}
|
||||
|
||||
/* This function is responsible for initializing EXP with INIT
|
||||
|
@ -1390,7 +1405,8 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags)
|
|||
for its description. */
|
||||
|
||||
static void
|
||||
expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags)
|
||||
expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
tree type = TREE_TYPE (exp);
|
||||
|
||||
|
@ -1417,7 +1433,7 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags)
|
|||
|
||||
/* We know that expand_default_init can handle everything we want
|
||||
at this point. */
|
||||
expand_default_init (binfo, true_exp, exp, init, flags);
|
||||
expand_default_init (binfo, true_exp, exp, init, flags, complain);
|
||||
}
|
||||
|
||||
/* Report an error if TYPE is not a user-defined, class type. If
|
||||
|
@ -1574,7 +1590,8 @@ build_offset_ref (tree type, tree member, bool address_p)
|
|||
if (flag_ms_extensions)
|
||||
{
|
||||
PTRMEM_OK_P (member) = 1;
|
||||
return build_unary_op (ADDR_EXPR, member, 0);
|
||||
return cp_build_unary_op (ADDR_EXPR, member, 0,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
error ("invalid use of non-static member function %qD",
|
||||
TREE_OPERAND (member, 1));
|
||||
|
@ -1765,7 +1782,7 @@ avoid_placement_new_aliasing (tree t, tree placement)
|
|||
|
||||
static tree
|
||||
build_new_1 (tree placement, tree type, tree nelts, tree init,
|
||||
bool globally_qualified_p)
|
||||
bool globally_qualified_p, tsubst_flags_t complain)
|
||||
{
|
||||
tree size, rval;
|
||||
/* True iff this is a call to "operator new[]" instead of just
|
||||
|
@ -1855,11 +1872,13 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
TREE_CODE (elt_type) == ARRAY_TYPE;
|
||||
elt_type = TREE_TYPE (elt_type))
|
||||
nelts = cp_build_binary_op (MULT_EXPR, nelts,
|
||||
array_type_nelts_top (elt_type));
|
||||
array_type_nelts_top (elt_type),
|
||||
complain);
|
||||
|
||||
if (TREE_CODE (elt_type) == VOID_TYPE)
|
||||
{
|
||||
error ("invalid type %<void%> for new");
|
||||
if (complain & tf_error)
|
||||
error ("invalid type %<void%> for new");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -1869,7 +1888,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || init);
|
||||
if (CP_TYPE_CONST_P (elt_type) && !is_initialized)
|
||||
{
|
||||
error ("uninitialized const in %<new%> of %q#T", elt_type);
|
||||
if (complain & tf_error)
|
||||
error ("uninitialized const in %<new%> of %q#T", elt_type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -1907,19 +1927,22 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
if (!get_global_value_if_present (get_identifier (alloc_name),
|
||||
&alloc_fn))
|
||||
{
|
||||
error ("call to Java constructor with %qs undefined", alloc_name);
|
||||
if (complain & tf_error)
|
||||
error ("call to Java constructor with %qs undefined", alloc_name);
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (really_overloaded_fn (alloc_fn))
|
||||
{
|
||||
error ("%qD should never be overloaded", alloc_fn);
|
||||
if (complain & tf_error)
|
||||
error ("%qD should never be overloaded", alloc_fn);
|
||||
return error_mark_node;
|
||||
}
|
||||
alloc_fn = OVL_CURRENT (alloc_fn);
|
||||
class_addr = build1 (ADDR_EXPR, jclass_node, class_decl);
|
||||
alloc_call = (build_function_call
|
||||
alloc_call = (cp_build_function_call
|
||||
(alloc_fn,
|
||||
build_tree_list (NULL_TREE, class_addr)));
|
||||
build_tree_list (NULL_TREE, class_addr),
|
||||
complain));
|
||||
}
|
||||
else if (TYPE_FOR_JAVA (elt_type) && MAYBE_CLASS_TYPE_P (elt_type))
|
||||
{
|
||||
|
@ -1952,20 +1975,25 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
fns = lookup_fnfields (elt_type, fnname, /*protect=*/2);
|
||||
if (fns == NULL_TREE)
|
||||
{
|
||||
error ("no suitable %qD found in class %qT", fnname, elt_type);
|
||||
if (complain & tf_error)
|
||||
error ("no suitable %qD found in class %qT", fnname, elt_type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (fns) == TREE_LIST)
|
||||
{
|
||||
error ("request for member %qD is ambiguous", fnname);
|
||||
print_candidates (fns);
|
||||
if (complain & tf_error)
|
||||
{
|
||||
error ("request for member %qD is ambiguous", fnname);
|
||||
print_candidates (fns);
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
alloc_call = build_new_method_call (build_dummy_object (elt_type),
|
||||
fns, args,
|
||||
/*conversion_path=*/NULL_TREE,
|
||||
LOOKUP_NORMAL,
|
||||
&alloc_fn);
|
||||
&alloc_fn,
|
||||
complain);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2085,7 +2113,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
size_ptr_type = build_pointer_type (sizetype);
|
||||
cookie_ptr = build2 (POINTER_PLUS_EXPR, size_ptr_type,
|
||||
fold_convert (size_ptr_type, data_addr), cookie_ptr);
|
||||
cookie = build_indirect_ref (cookie_ptr, NULL);
|
||||
cookie = cp_build_indirect_ref (cookie_ptr, NULL, complain);
|
||||
|
||||
cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
|
||||
|
||||
|
@ -2096,7 +2124,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
fold_build1 (NEGATE_EXPR, sizetype,
|
||||
size_in_bytes (sizetype)));
|
||||
|
||||
cookie = build_indirect_ref (cookie_ptr, NULL);
|
||||
cookie = cp_build_indirect_ref (cookie_ptr, NULL, complain);
|
||||
cookie = build2 (MODIFY_EXPR, sizetype, cookie,
|
||||
size_in_bytes(elt_type));
|
||||
cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
|
||||
|
@ -2119,7 +2147,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
{
|
||||
bool stable;
|
||||
|
||||
init_expr = build_indirect_ref (data_addr, NULL);
|
||||
init_expr = cp_build_indirect_ref (data_addr, NULL, complain);
|
||||
|
||||
if (array_p)
|
||||
{
|
||||
|
@ -2131,15 +2159,21 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
explicit_default_init_p = true;
|
||||
}
|
||||
else if (init)
|
||||
pedwarn ("ISO C++ forbids initialization in array new");
|
||||
|
||||
{
|
||||
if (complain & tf_error)
|
||||
pedwarn ("ISO C++ forbids initialization in array new");
|
||||
else
|
||||
return error_mark_node;
|
||||
}
|
||||
init_expr
|
||||
= build_vec_init (init_expr,
|
||||
cp_build_binary_op (MINUS_EXPR, outer_nelts,
|
||||
integer_one_node),
|
||||
integer_one_node,
|
||||
complain),
|
||||
init,
|
||||
explicit_default_init_p,
|
||||
/*from_array=*/0);
|
||||
/*from_array=*/0,
|
||||
complain);
|
||||
|
||||
/* An array initialization is stable because the initialization
|
||||
of each element is a full-expression, so the temporaries don't
|
||||
|
@ -2156,7 +2190,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
init_expr = build_special_member_call (init_expr,
|
||||
complete_ctor_identifier,
|
||||
init, elt_type,
|
||||
LOOKUP_NORMAL);
|
||||
LOOKUP_NORMAL,
|
||||
complain);
|
||||
stable = stabilize_init (init_expr, &init_preeval_expr);
|
||||
}
|
||||
else
|
||||
|
@ -2171,7 +2206,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
gcc_assert (TREE_CODE (init) != CONSTRUCTOR
|
||||
|| TREE_TYPE (init) != NULL_TREE);
|
||||
|
||||
init_expr = build_modify_expr (init_expr, INIT_EXPR, init);
|
||||
init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, init,
|
||||
complain);
|
||||
stable = stabilize_init (init_expr, &init_preeval_expr);
|
||||
}
|
||||
}
|
||||
|
@ -2263,8 +2299,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
if (check_new)
|
||||
{
|
||||
tree ifexp = cp_build_binary_op (NE_EXPR, alloc_node,
|
||||
integer_zero_node);
|
||||
rval = build_conditional_expr (ifexp, rval, alloc_node);
|
||||
integer_zero_node,
|
||||
complain);
|
||||
rval = build_conditional_expr (ifexp, rval, alloc_node,
|
||||
complain);
|
||||
}
|
||||
|
||||
/* Perform the allocation before anything else, so that ALLOC_NODE
|
||||
|
@ -2299,7 +2337,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
|
|||
|
||||
tree
|
||||
build_new (tree placement, tree type, tree nelts, tree init,
|
||||
int use_global_new)
|
||||
int use_global_new, tsubst_flags_t complain)
|
||||
{
|
||||
tree rval;
|
||||
tree orig_placement;
|
||||
|
@ -2333,7 +2371,12 @@ build_new (tree placement, tree type, tree nelts, tree init,
|
|||
if (nelts)
|
||||
{
|
||||
if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, nelts, false))
|
||||
pedwarn ("size in array new must have integral type");
|
||||
{
|
||||
if (complain & tf_error)
|
||||
pedwarn ("size in array new must have integral type");
|
||||
else
|
||||
return error_mark_node;
|
||||
}
|
||||
nelts = cp_save_expr (cp_convert (sizetype, nelts));
|
||||
}
|
||||
|
||||
|
@ -2342,13 +2385,17 @@ build_new (tree placement, tree type, tree nelts, tree init,
|
|||
returned by new.'' ARM 5.3.3 */
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
{
|
||||
error ("new cannot be applied to a reference type");
|
||||
if (complain & tf_error)
|
||||
error ("new cannot be applied to a reference type");
|
||||
else
|
||||
return error_mark_node;
|
||||
type = TREE_TYPE (type);
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == FUNCTION_TYPE)
|
||||
{
|
||||
error ("new cannot be applied to a function type");
|
||||
if (complain & tf_error)
|
||||
error ("new cannot be applied to a function type");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -2358,7 +2405,7 @@ build_new (tree placement, tree type, tree nelts, tree init,
|
|||
if (!complete_type_or_else (type, NULL_TREE))
|
||||
return error_mark_node;
|
||||
|
||||
rval = build_new_1 (placement, type, nelts, init, use_global_new);
|
||||
rval = build_new_1 (placement, type, nelts, init, use_global_new, complain);
|
||||
if (rval == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
@ -2464,10 +2511,11 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
|
|||
convert (sizetype, maxindex));
|
||||
|
||||
tbase = create_temporary_var (ptype);
|
||||
tbase_init = build_modify_expr (tbase, NOP_EXPR,
|
||||
fold_build2 (POINTER_PLUS_EXPR, ptype,
|
||||
fold_convert (ptype, base),
|
||||
virtual_size));
|
||||
tbase_init = cp_build_modify_expr (tbase, NOP_EXPR,
|
||||
fold_build2 (POINTER_PLUS_EXPR, ptype,
|
||||
fold_convert (ptype, base),
|
||||
virtual_size),
|
||||
tf_warning_or_error);
|
||||
DECL_REGISTER (tbase) = 1;
|
||||
controller = build3 (BIND_EXPR, void_type_node, tbase,
|
||||
NULL_TREE, NULL_TREE);
|
||||
|
@ -2478,14 +2526,17 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
|
|||
fold_convert (ptype, base)));
|
||||
tmp = fold_build1 (NEGATE_EXPR, sizetype, size_exp);
|
||||
body = build_compound_expr
|
||||
(body, build_modify_expr (tbase, NOP_EXPR,
|
||||
build2 (POINTER_PLUS_EXPR, ptype, tbase, tmp)));
|
||||
(body, cp_build_modify_expr (tbase, NOP_EXPR,
|
||||
build2 (POINTER_PLUS_EXPR, ptype, tbase, tmp),
|
||||
tf_warning_or_error),
|
||||
tf_warning_or_error);
|
||||
body = build_compound_expr
|
||||
(body, build_delete (ptype, tbase, sfk_complete_destructor,
|
||||
LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1));
|
||||
LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1),
|
||||
tf_warning_or_error);
|
||||
|
||||
loop = build1 (LOOP_EXPR, void_type_node, body);
|
||||
loop = build_compound_expr (tbase_init, loop);
|
||||
loop = build_compound_expr (tbase_init, loop, tf_warning_or_error);
|
||||
|
||||
no_destructor:
|
||||
/* If the delete flag is one, or anything else with the low bit set,
|
||||
|
@ -2511,7 +2562,8 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
|
|||
cp_build_binary_op (MINUS_EXPR,
|
||||
cp_convert (string_type_node,
|
||||
base),
|
||||
cookie_size));
|
||||
cookie_size,
|
||||
tf_warning_or_error));
|
||||
/* True size with header. */
|
||||
virtual_size = size_binop (PLUS_EXPR, virtual_size, cookie_size);
|
||||
}
|
||||
|
@ -2530,7 +2582,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
|
|||
else if (!body)
|
||||
body = deallocate_expr;
|
||||
else
|
||||
body = build_compound_expr (body, deallocate_expr);
|
||||
body = build_compound_expr (body, deallocate_expr, tf_warning_or_error);
|
||||
|
||||
if (!body)
|
||||
body = integer_zero_node;
|
||||
|
@ -2553,7 +2605,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
|
|||
/* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR. */
|
||||
body = build2 (COMPOUND_EXPR, void_type_node, base, body);
|
||||
|
||||
return convert_to_void (body, /*implicit=*/NULL);
|
||||
return convert_to_void (body, /*implicit=*/NULL, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Create an unnamed variable of the indicated TYPE. */
|
||||
|
@ -2588,7 +2640,8 @@ get_temp_regvar (tree type, tree init)
|
|||
decl = create_temporary_var (type);
|
||||
add_decl_expr (decl);
|
||||
|
||||
finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
|
||||
finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
|
||||
tf_warning_or_error));
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
@ -2616,7 +2669,7 @@ get_temp_regvar (tree type, tree init)
|
|||
tree
|
||||
build_vec_init (tree base, tree maxindex, tree init,
|
||||
bool explicit_default_init_p,
|
||||
int from_array)
|
||||
int from_array, tsubst_flags_t complain)
|
||||
{
|
||||
tree rval;
|
||||
tree base2 = NULL_TREE;
|
||||
|
@ -2737,14 +2790,16 @@ build_vec_init (tree base, tree maxindex, tree init,
|
|||
|
||||
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
|
||||
if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
|
||||
finish_expr_stmt (build_aggr_init (baseref, elt, 0));
|
||||
finish_expr_stmt (build_aggr_init (baseref, elt, 0, complain));
|
||||
else
|
||||
finish_expr_stmt (build_modify_expr (baseref, NOP_EXPR,
|
||||
elt));
|
||||
finish_expr_stmt (cp_build_modify_expr (baseref, NOP_EXPR,
|
||||
elt, complain));
|
||||
current_stmt_tree ()->stmts_are_full_exprs_p = 0;
|
||||
|
||||
finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base, 0));
|
||||
finish_expr_stmt (build_unary_op (PREDECREMENT_EXPR, iterator, 0));
|
||||
finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base, 0,
|
||||
complain));
|
||||
finish_expr_stmt (cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
|
||||
complain));
|
||||
}
|
||||
|
||||
/* Clear out INIT so that we don't get confused below. */
|
||||
|
@ -2766,7 +2821,8 @@ build_vec_init (tree base, tree maxindex, tree init,
|
|||
&& TYPE_NEEDS_CONSTRUCTING (type)
|
||||
&& ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
|
||||
{
|
||||
error ("initializer ends prematurely");
|
||||
if (complain & tf_error)
|
||||
error ("initializer ends prematurely");
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
|
@ -2794,7 +2850,8 @@ build_vec_init (tree base, tree maxindex, tree init,
|
|||
finish_for_cond (build2 (NE_EXPR, boolean_type_node, iterator,
|
||||
build_int_cst (TREE_TYPE (iterator), -1)),
|
||||
for_stmt);
|
||||
finish_for_expr (build_unary_op (PREDECREMENT_EXPR, iterator, 0),
|
||||
finish_for_expr (cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
|
||||
complain),
|
||||
for_stmt);
|
||||
|
||||
to = build1 (INDIRECT_REF, type, base);
|
||||
|
@ -2809,11 +2866,13 @@ build_vec_init (tree base, tree maxindex, tree init,
|
|||
from = NULL_TREE;
|
||||
|
||||
if (from_array == 2)
|
||||
elt_init = build_modify_expr (to, NOP_EXPR, from);
|
||||
elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
|
||||
complain);
|
||||
else if (TYPE_NEEDS_CONSTRUCTING (type))
|
||||
elt_init = build_aggr_init (to, from, 0);
|
||||
elt_init = build_aggr_init (to, from, 0, complain);
|
||||
else if (from)
|
||||
elt_init = build_modify_expr (to, NOP_EXPR, from);
|
||||
elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
|
||||
complain);
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
@ -2825,23 +2884,26 @@ build_vec_init (tree base, tree maxindex, tree init,
|
|||
elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
|
||||
0, 0,
|
||||
/*explicit_default_init_p=*/false,
|
||||
0);
|
||||
0, complain);
|
||||
}
|
||||
else if (!TYPE_NEEDS_CONSTRUCTING (type))
|
||||
elt_init = (build_modify_expr
|
||||
elt_init = (cp_build_modify_expr
|
||||
(to, INIT_EXPR,
|
||||
build_zero_init (type, size_one_node,
|
||||
/*static_storage_p=*/false)));
|
||||
/*static_storage_p=*/false),
|
||||
complain));
|
||||
else
|
||||
elt_init = build_aggr_init (to, init, 0);
|
||||
elt_init = build_aggr_init (to, init, 0, complain);
|
||||
|
||||
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
|
||||
finish_expr_stmt (elt_init);
|
||||
current_stmt_tree ()->stmts_are_full_exprs_p = 0;
|
||||
|
||||
finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base, 0));
|
||||
finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base, 0,
|
||||
complain));
|
||||
if (base2)
|
||||
finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base2, 0));
|
||||
finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base2, 0,
|
||||
complain));
|
||||
|
||||
finish_for_stmt (for_stmt);
|
||||
}
|
||||
|
@ -2851,13 +2913,15 @@ build_vec_init (tree base, tree maxindex, tree init,
|
|||
&& from_array != 2)
|
||||
{
|
||||
tree e;
|
||||
tree m = cp_build_binary_op (MINUS_EXPR, maxindex, iterator);
|
||||
tree m = cp_build_binary_op (MINUS_EXPR, maxindex, iterator,
|
||||
complain);
|
||||
|
||||
/* Flatten multi-dimensional array since build_vec_delete only
|
||||
expects one-dimensional array. */
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
m = cp_build_binary_op (MULT_EXPR, m,
|
||||
array_type_nelts_total (type));
|
||||
array_type_nelts_total (type),
|
||||
complain);
|
||||
|
||||
finish_cleanup_try_block (try_block);
|
||||
e = build_vec_delete_1 (rval, m,
|
||||
|
@ -2875,7 +2939,7 @@ build_vec_init (tree base, tree maxindex, tree init,
|
|||
/* Now convert make the result have the correct type. */
|
||||
atype = build_pointer_type (atype);
|
||||
stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
|
||||
stmt_expr = build_indirect_ref (stmt_expr, NULL);
|
||||
stmt_expr = cp_build_indirect_ref (stmt_expr, NULL, complain);
|
||||
|
||||
current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
|
||||
return stmt_expr;
|
||||
|
@ -2911,7 +2975,8 @@ build_dtor_call (tree exp, special_function_kind dtor_kind, int flags)
|
|||
/*args=*/NULL_TREE,
|
||||
/*conversion_path=*/NULL_TREE,
|
||||
flags,
|
||||
/*fn_p=*/NULL);
|
||||
/*fn_p=*/NULL,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Generate a call to a destructor. TYPE is the type to cast ADDR to.
|
||||
|
@ -2993,7 +3058,7 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
|
|||
/* Don't check PROTECT here; leave that decision to the
|
||||
destructor. If the destructor is accessible, call it,
|
||||
else report error. */
|
||||
addr = build_unary_op (ADDR_EXPR, addr, 0);
|
||||
addr = cp_build_unary_op (ADDR_EXPR, addr, 0, tf_warning_or_error);
|
||||
if (TREE_SIDE_EFFECTS (addr))
|
||||
addr = save_expr (addr);
|
||||
|
||||
|
@ -3065,7 +3130,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
|
|||
/*alloc_fn=*/NULL_TREE);
|
||||
}
|
||||
|
||||
expr = build_dtor_call (build_indirect_ref (addr, NULL),
|
||||
expr = build_dtor_call (cp_build_indirect_ref (addr, NULL,
|
||||
tf_warning_or_error),
|
||||
auto_delete, flags);
|
||||
if (do_delete)
|
||||
expr = build2 (COMPOUND_EXPR, void_type_node, expr, do_delete);
|
||||
|
@ -3079,7 +3145,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
|
|||
ifexp = integer_one_node;
|
||||
else
|
||||
/* Handle deleting a null pointer. */
|
||||
ifexp = fold (cp_build_binary_op (NE_EXPR, addr, integer_zero_node));
|
||||
ifexp = fold (cp_build_binary_op (NE_EXPR, addr, integer_zero_node,
|
||||
tf_warning_or_error));
|
||||
|
||||
if (ifexp != integer_one_node)
|
||||
expr = build3 (COND_EXPR, void_type_node,
|
||||
|
@ -3123,7 +3190,8 @@ push_base_cleanups (void)
|
|||
NULL_TREE,
|
||||
base_binfo,
|
||||
(LOOKUP_NORMAL
|
||||
| LOOKUP_NONVIRTUAL));
|
||||
| LOOKUP_NONVIRTUAL),
|
||||
tf_warning_or_error);
|
||||
expr = build3 (COND_EXPR, void_type_node, cond,
|
||||
expr, void_zero_node);
|
||||
finish_decl_cleanup (NULL_TREE, expr);
|
||||
|
@ -3142,7 +3210,8 @@ push_base_cleanups (void)
|
|||
expr = build_special_member_call (current_class_ref,
|
||||
base_dtor_identifier,
|
||||
NULL_TREE, base_binfo,
|
||||
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL);
|
||||
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
|
||||
tf_warning_or_error);
|
||||
finish_decl_cleanup (NULL_TREE, expr);
|
||||
}
|
||||
|
||||
|
@ -3158,7 +3227,8 @@ push_base_cleanups (void)
|
|||
tree this_member = (build_class_member_access_expr
|
||||
(current_class_ref, member,
|
||||
/*access_path=*/NULL_TREE,
|
||||
/*preserve_reference=*/false));
|
||||
/*preserve_reference=*/false,
|
||||
tf_warning_or_error));
|
||||
tree this_type = TREE_TYPE (member);
|
||||
expr = build_delete (this_type, this_member,
|
||||
sfk_complete_destructor,
|
||||
|
@ -3211,7 +3281,7 @@ build_vec_delete (tree base, tree maxindex,
|
|||
build_pointer_type (sizetype),
|
||||
base,
|
||||
cookie_addr);
|
||||
maxindex = build_indirect_ref (cookie_addr, NULL);
|
||||
maxindex = cp_build_indirect_ref (cookie_addr, NULL, tf_warning_or_error);
|
||||
}
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
|
@ -3219,7 +3289,7 @@ build_vec_delete (tree base, tree maxindex,
|
|||
bad name. */
|
||||
maxindex = array_type_nelts_total (type);
|
||||
type = strip_array_types (type);
|
||||
base = build_unary_op (ADDR_EXPR, base, 1);
|
||||
base = cp_build_unary_op (ADDR_EXPR, base, 1, tf_warning_or_error);
|
||||
if (TREE_SIDE_EFFECTS (base))
|
||||
{
|
||||
base_init = get_target_expr (base);
|
||||
|
|
|
@ -674,7 +674,8 @@ do_build_assign_ref (tree fndecl)
|
|||
build_tree_list (NULL_TREE,
|
||||
converted_parm),
|
||||
base_binfo,
|
||||
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL));
|
||||
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
|
||||
tf_warning_or_error));
|
||||
}
|
||||
|
||||
/* Assign to each of the non-static data members. */
|
||||
|
@ -729,7 +730,8 @@ do_build_assign_ref (tree fndecl)
|
|||
init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
|
||||
|
||||
if (DECL_NAME (field))
|
||||
init = build_modify_expr (comp, NOP_EXPR, init);
|
||||
init = cp_build_modify_expr (comp, NOP_EXPR, init,
|
||||
tf_warning_or_error);
|
||||
else
|
||||
init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
|
||||
finish_expr_stmt (init);
|
||||
|
|
|
@ -4333,19 +4333,20 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|
|||
{
|
||||
case RID_DYNCAST:
|
||||
postfix_expression
|
||||
= build_dynamic_cast (type, expression);
|
||||
= build_dynamic_cast (type, expression, tf_warning_or_error);
|
||||
break;
|
||||
case RID_STATCAST:
|
||||
postfix_expression
|
||||
= build_static_cast (type, expression);
|
||||
= build_static_cast (type, expression, tf_warning_or_error);
|
||||
break;
|
||||
case RID_REINTCAST:
|
||||
postfix_expression
|
||||
= build_reinterpret_cast (type, expression);
|
||||
= build_reinterpret_cast (type, expression,
|
||||
tf_warning_or_error);
|
||||
break;
|
||||
case RID_CONSTCAST:
|
||||
postfix_expression
|
||||
= build_const_cast (type, expression);
|
||||
= build_const_cast (type, expression, tf_warning_or_error);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
|
@ -4644,12 +4645,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|
|||
(instance, fn, args, NULL_TREE,
|
||||
(idk == CP_ID_KIND_QUALIFIED
|
||||
? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL),
|
||||
/*fn_p=*/NULL));
|
||||
/*fn_p=*/NULL,
|
||||
tf_warning_or_error));
|
||||
else
|
||||
postfix_expression
|
||||
= finish_call_expr (postfix_expression, args,
|
||||
/*disallow_virtual=*/false,
|
||||
/*koenig_p=*/false);
|
||||
/*koenig_p=*/false,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
else if (TREE_CODE (postfix_expression) == OFFSET_REF
|
||||
|| TREE_CODE (postfix_expression) == MEMBER_REF
|
||||
|
@ -4662,13 +4665,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|
|||
postfix_expression
|
||||
= finish_call_expr (postfix_expression, args,
|
||||
/*disallow_virtual=*/true,
|
||||
koenig_p);
|
||||
koenig_p,
|
||||
tf_warning_or_error);
|
||||
else
|
||||
/* All other function calls. */
|
||||
postfix_expression
|
||||
= finish_call_expr (postfix_expression, args,
|
||||
/*disallow_virtual=*/false,
|
||||
koenig_p);
|
||||
koenig_p,
|
||||
tf_warning_or_error);
|
||||
|
||||
/* The POSTFIX_EXPRESSION is certainly no longer an id. */
|
||||
idk = CP_ID_KIND_NONE;
|
||||
|
@ -4937,7 +4942,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
|
|||
(name, BINFO_TYPE (BASELINK_ACCESS_BINFO (name)), scope);
|
||||
postfix_expression
|
||||
= finish_class_member_access_expr (postfix_expression, name,
|
||||
template_p);
|
||||
template_p,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5250,7 +5256,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
|
|||
if (TYPE_P (operand))
|
||||
return cxx_sizeof_or_alignof_type (operand, op, true);
|
||||
else
|
||||
return cxx_sizeof_or_alignof_expr (operand, op);
|
||||
return cxx_sizeof_or_alignof_expr (operand, op, true);
|
||||
}
|
||||
|
||||
case RID_NEW:
|
||||
|
@ -5287,7 +5293,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
|
|||
/* Create the complete representation. */
|
||||
return build_x_unary_op ((keyword == RID_REALPART
|
||||
? REALPART_EXPR : IMAGPART_EXPR),
|
||||
expression);
|
||||
expression,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -5362,14 +5369,16 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
|
|||
{
|
||||
case INDIRECT_REF:
|
||||
non_constant_p = "`*'";
|
||||
expression = build_x_indirect_ref (cast_expression, "unary *");
|
||||
expression = build_x_indirect_ref (cast_expression, "unary *",
|
||||
tf_warning_or_error);
|
||||
break;
|
||||
|
||||
case ADDR_EXPR:
|
||||
non_constant_p = "`&'";
|
||||
/* Fall through. */
|
||||
case BIT_NOT_EXPR:
|
||||
expression = build_x_unary_op (unary_operator, cast_expression);
|
||||
expression = build_x_unary_op (unary_operator, cast_expression,
|
||||
tf_warning_or_error);
|
||||
break;
|
||||
|
||||
case PREINCREMENT_EXPR:
|
||||
|
@ -5500,7 +5509,8 @@ cp_parser_new_expression (cp_parser* parser)
|
|||
return error_mark_node;
|
||||
|
||||
/* Create a representation of the new-expression. */
|
||||
return build_new (placement, type, nelts, initializer, global_scope_p);
|
||||
return build_new (placement, type, nelts, initializer, global_scope_p,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Parse a new-placement.
|
||||
|
@ -5870,7 +5880,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
|
|||
return error_mark_node;
|
||||
|
||||
/* Perform the cast. */
|
||||
expr = build_c_cast (type, expr);
|
||||
expr = build_c_cast (type, expr, tf_warning_or_error);
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
|
@ -6059,7 +6069,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p)
|
|||
|
||||
overloaded_p = false;
|
||||
lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type,
|
||||
&overloaded_p);
|
||||
&overloaded_p, tf_warning_or_error);
|
||||
lhs_type = tree_type;
|
||||
|
||||
/* If the binary operator required the use of an overloaded operator,
|
||||
|
@ -6115,7 +6125,8 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
|
|||
/* Build the conditional-expression. */
|
||||
return build_x_conditional_expr (logical_or_expr,
|
||||
expr,
|
||||
assignment_expr);
|
||||
assignment_expr,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Parse an assignment-expression.
|
||||
|
@ -6170,7 +6181,8 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p)
|
|||
/* Build the assignment expression. */
|
||||
expr = build_x_modify_expr (expr,
|
||||
assignment_operator,
|
||||
rhs);
|
||||
rhs,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6290,7 +6302,8 @@ cp_parser_expression (cp_parser* parser, bool cast_p)
|
|||
expression = assignment_expression;
|
||||
else
|
||||
expression = build_x_compound_expr (expression,
|
||||
assignment_expression);
|
||||
assignment_expression,
|
||||
tf_warning_or_error);
|
||||
/* If the next token is not a comma, then we are done with the
|
||||
expression. */
|
||||
if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
|
||||
|
@ -6410,7 +6423,8 @@ cp_parser_builtin_offsetof (cp_parser *parser)
|
|||
cp_parser_require (parser, CPP_COMMA, "`,'");
|
||||
|
||||
/* Build the (type *)null that begins the traditional offsetof macro. */
|
||||
expr = build_static_cast (build_pointer_type (type), null_pointer_node);
|
||||
expr = build_static_cast (build_pointer_type (type), null_pointer_node,
|
||||
tf_warning_or_error);
|
||||
|
||||
/* Parse the offsetof-member-designator. We begin as if we saw "expr->". */
|
||||
expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, expr,
|
||||
|
@ -10320,7 +10334,8 @@ cp_parser_template_argument (cp_parser* parser)
|
|||
if (cp_parser_parse_definitely (parser))
|
||||
{
|
||||
if (address_p)
|
||||
argument = build_x_unary_op (ADDR_EXPR, argument);
|
||||
argument = build_x_unary_op (ADDR_EXPR, argument,
|
||||
tf_warning_or_error);
|
||||
return argument;
|
||||
}
|
||||
}
|
||||
|
@ -17181,7 +17196,8 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
|
|||
/*allow_expansion_p=*/true,
|
||||
/*non_constant_p=*/NULL);
|
||||
|
||||
cast = build_functional_cast (type, expression_list);
|
||||
cast = build_functional_cast (type, expression_list,
|
||||
tf_warning_or_error);
|
||||
/* [expr.const]/1: In an integral constant expression "only type
|
||||
conversions to integral or enumeration type can be used". */
|
||||
if (TREE_CODE (type) == TYPE_DECL)
|
||||
|
|
60
gcc/cp/pt.c
60
gcc/cp/pt.c
|
@ -10684,7 +10684,7 @@ tsubst_copy_and_build (tree t,
|
|||
r = convert_from_reference (r);
|
||||
}
|
||||
else
|
||||
r = build_x_indirect_ref (r, "unary *");
|
||||
r = build_x_indirect_ref (r, "unary *", complain);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -10706,8 +10706,9 @@ tsubst_copy_and_build (tree t,
|
|||
if (integral_constant_expression_p
|
||||
&& !cast_valid_in_integral_constant_expression_p (type))
|
||||
{
|
||||
error ("a cast to a type other than an integral or "
|
||||
"enumeration type cannot appear in a constant-expression");
|
||||
if (complain & tf_error)
|
||||
error ("a cast to a type other than an integral or "
|
||||
"enumeration type cannot appear in a constant-expression");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -10716,15 +10717,15 @@ tsubst_copy_and_build (tree t,
|
|||
switch (TREE_CODE (t))
|
||||
{
|
||||
case CAST_EXPR:
|
||||
return build_functional_cast (type, op);
|
||||
return build_functional_cast (type, op, complain);
|
||||
case REINTERPRET_CAST_EXPR:
|
||||
return build_reinterpret_cast (type, op);
|
||||
return build_reinterpret_cast (type, op, complain);
|
||||
case CONST_CAST_EXPR:
|
||||
return build_const_cast (type, op);
|
||||
return build_const_cast (type, op, complain);
|
||||
case DYNAMIC_CAST_EXPR:
|
||||
return build_dynamic_cast (type, op);
|
||||
return build_dynamic_cast (type, op, complain);
|
||||
case STATIC_CAST_EXPR:
|
||||
return build_static_cast (type, op);
|
||||
return build_static_cast (type, op, complain);
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
@ -10734,7 +10735,7 @@ tsubst_copy_and_build (tree t,
|
|||
case POSTINCREMENT_EXPR:
|
||||
op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
|
||||
args, complain, in_decl);
|
||||
return build_x_unary_op (TREE_CODE (t), op1);
|
||||
return build_x_unary_op (TREE_CODE (t), op1, complain);
|
||||
|
||||
case PREDECREMENT_EXPR:
|
||||
case PREINCREMENT_EXPR:
|
||||
|
@ -10745,7 +10746,8 @@ tsubst_copy_and_build (tree t,
|
|||
case UNARY_PLUS_EXPR: /* Unary + */
|
||||
case REALPART_EXPR:
|
||||
case IMAGPART_EXPR:
|
||||
return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)));
|
||||
return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)),
|
||||
complain);
|
||||
|
||||
case ADDR_EXPR:
|
||||
op1 = TREE_OPERAND (t, 0);
|
||||
|
@ -10757,7 +10759,7 @@ tsubst_copy_and_build (tree t,
|
|||
in_decl);
|
||||
if (TREE_CODE (op1) == LABEL_DECL)
|
||||
return finish_label_address_expr (DECL_NAME (op1));
|
||||
return build_x_unary_op (ADDR_EXPR, op1);
|
||||
return build_x_unary_op (ADDR_EXPR, op1, complain);
|
||||
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
|
@ -10800,7 +10802,8 @@ tsubst_copy_and_build (tree t,
|
|||
(TREE_NO_WARNING (TREE_OPERAND (t, 1))
|
||||
? ERROR_MARK
|
||||
: TREE_CODE (TREE_OPERAND (t, 1))),
|
||||
/*overloaded_p=*/NULL);
|
||||
/*overloaded_p=*/NULL,
|
||||
complain);
|
||||
|
||||
case SCOPE_REF:
|
||||
return tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true,
|
||||
|
@ -10816,7 +10819,8 @@ tsubst_copy_and_build (tree t,
|
|||
(TREE_NO_WARNING (TREE_OPERAND (t, 1))
|
||||
? ERROR_MARK
|
||||
: TREE_CODE (TREE_OPERAND (t, 1))),
|
||||
/*overloaded_p=*/NULL);
|
||||
/*overloaded_p=*/NULL,
|
||||
complain);
|
||||
|
||||
case SIZEOF_EXPR:
|
||||
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
|
||||
|
@ -10849,16 +10853,19 @@ tsubst_copy_and_build (tree t,
|
|||
--skip_evaluation;
|
||||
}
|
||||
if (TYPE_P (op1))
|
||||
return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), true);
|
||||
return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t),
|
||||
complain & tf_error);
|
||||
else
|
||||
return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t));
|
||||
return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t),
|
||||
complain & tf_error);
|
||||
|
||||
case MODOP_EXPR:
|
||||
{
|
||||
tree r = build_x_modify_expr
|
||||
(RECUR (TREE_OPERAND (t, 0)),
|
||||
TREE_CODE (TREE_OPERAND (t, 1)),
|
||||
RECUR (TREE_OPERAND (t, 2)));
|
||||
RECUR (TREE_OPERAND (t, 2)),
|
||||
complain);
|
||||
/* TREE_NO_WARNING must be set if either the expression was
|
||||
parenthesized or it uses an operator such as >>= rather
|
||||
than plain assignment. In the former case, it was already
|
||||
|
@ -10896,7 +10903,8 @@ tsubst_copy_and_build (tree t,
|
|||
RECUR (TREE_OPERAND (t, 1)),
|
||||
RECUR (TREE_OPERAND (t, 2)),
|
||||
init,
|
||||
NEW_EXPR_USE_GLOBAL (t));
|
||||
NEW_EXPR_USE_GLOBAL (t),
|
||||
complain);
|
||||
}
|
||||
|
||||
case DELETE_EXPR:
|
||||
|
@ -10908,7 +10916,8 @@ tsubst_copy_and_build (tree t,
|
|||
|
||||
case COMPOUND_EXPR:
|
||||
return build_x_compound_expr (RECUR (TREE_OPERAND (t, 0)),
|
||||
RECUR (TREE_OPERAND (t, 1)));
|
||||
RECUR (TREE_OPERAND (t, 1)),
|
||||
complain);
|
||||
|
||||
case CALL_EXPR:
|
||||
{
|
||||
|
@ -10982,25 +10991,29 @@ tsubst_copy_and_build (tree t,
|
|||
if (!BASELINK_P (TREE_OPERAND (function, 1)))
|
||||
return finish_call_expr (function, call_args,
|
||||
/*disallow_virtual=*/false,
|
||||
/*koenig_p=*/false);
|
||||
/*koenig_p=*/false,
|
||||
complain);
|
||||
else
|
||||
return (build_new_method_call
|
||||
(TREE_OPERAND (function, 0),
|
||||
TREE_OPERAND (function, 1),
|
||||
call_args, NULL_TREE,
|
||||
qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
|
||||
/*fn_p=*/NULL));
|
||||
/*fn_p=*/NULL,
|
||||
complain));
|
||||
}
|
||||
return finish_call_expr (function, call_args,
|
||||
/*disallow_virtual=*/qualified_p,
|
||||
koenig_p);
|
||||
koenig_p,
|
||||
complain);
|
||||
}
|
||||
|
||||
case COND_EXPR:
|
||||
return build_x_conditional_expr
|
||||
(RECUR (TREE_OPERAND (t, 0)),
|
||||
RECUR (TREE_OPERAND (t, 1)),
|
||||
RECUR (TREE_OPERAND (t, 2)));
|
||||
RECUR (TREE_OPERAND (t, 2)),
|
||||
complain);
|
||||
|
||||
case PSEUDO_DTOR_EXPR:
|
||||
return finish_pseudo_destructor_expr
|
||||
|
@ -11184,7 +11197,8 @@ tsubst_copy_and_build (tree t,
|
|||
return finish_non_static_data_member (member, object, NULL_TREE);
|
||||
|
||||
return finish_class_member_access_expr (object, member,
|
||||
/*template_p=*/false);
|
||||
/*template_p=*/false,
|
||||
complain);
|
||||
}
|
||||
|
||||
case THROW_EXPR:
|
||||
|
|
|
@ -104,7 +104,7 @@ static GTY (()) VEC(tinfo_s,gc) *tinfo_descs;
|
|||
|
||||
static tree ifnonnull (tree, tree);
|
||||
static tree tinfo_name (tree);
|
||||
static tree build_dynamic_cast_1 (tree, tree);
|
||||
static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
|
||||
static tree throw_bad_cast (void);
|
||||
static tree throw_bad_typeid (void);
|
||||
static tree get_tinfo_decl_dynamic (tree);
|
||||
|
@ -188,7 +188,9 @@ build_headof (tree exp)
|
|||
index = build_int_cst (NULL_TREE,
|
||||
-2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
|
||||
|
||||
offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
|
||||
offset = build_vtbl_ref (cp_build_indirect_ref (exp, NULL,
|
||||
tf_warning_or_error),
|
||||
index);
|
||||
|
||||
type = build_qualified_type (ptr_type_node,
|
||||
cp_type_quals (TREE_TYPE (exp)));
|
||||
|
@ -272,7 +274,7 @@ get_tinfo_decl_dynamic (tree exp)
|
|||
/* Otherwise return the type_info for the static type of the expr. */
|
||||
t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
|
||||
|
||||
return build_indirect_ref (t, NULL);
|
||||
return cp_build_indirect_ref (t, NULL, tf_warning_or_error);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -463,7 +465,8 @@ get_typeid (tree type)
|
|||
if (!type)
|
||||
return error_mark_node;
|
||||
|
||||
return build_indirect_ref (get_tinfo_ptr (type), NULL);
|
||||
return cp_build_indirect_ref (get_tinfo_ptr (type), NULL,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Check whether TEST is null before returning RESULT. If TEST is used in
|
||||
|
@ -483,7 +486,7 @@ ifnonnull (tree test, tree result)
|
|||
paper. */
|
||||
|
||||
static tree
|
||||
build_dynamic_cast_1 (tree type, tree expr)
|
||||
build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
|
||||
{
|
||||
enum tree_code tc = TREE_CODE (type);
|
||||
tree exprtype = TREE_TYPE (expr);
|
||||
|
@ -626,8 +629,9 @@ build_dynamic_cast_1 (tree type, tree expr)
|
|||
&& TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
|
||||
{
|
||||
tree expr = throw_bad_cast ();
|
||||
warning (0, "dynamic_cast of %q#D to %q#T can never succeed",
|
||||
old_expr, type);
|
||||
if (complain & tf_warning)
|
||||
warning (0, "dynamic_cast of %q#D to %q#T can never succeed",
|
||||
old_expr, type);
|
||||
/* Bash it to the expected type. */
|
||||
TREE_TYPE (expr) = type;
|
||||
return expr;
|
||||
|
@ -640,8 +644,9 @@ build_dynamic_cast_1 (tree type, tree expr)
|
|||
if (TREE_CODE (op) == VAR_DECL
|
||||
&& TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
|
||||
{
|
||||
warning (0, "dynamic_cast of %q#D to %q#T can never succeed",
|
||||
op, type);
|
||||
if (complain & tf_warning)
|
||||
warning (0, "dynamic_cast of %q#D to %q#T can never succeed",
|
||||
op, type);
|
||||
retval = build_int_cst (type, 0);
|
||||
return retval;
|
||||
}
|
||||
|
@ -650,7 +655,8 @@ build_dynamic_cast_1 (tree type, tree expr)
|
|||
/* Use of dynamic_cast when -fno-rtti is prohibited. */
|
||||
if (!flag_rtti)
|
||||
{
|
||||
error ("%<dynamic_cast%> not permitted with -fno-rtti");
|
||||
if (complain & tf_error)
|
||||
error ("%<dynamic_cast%> not permitted with -fno-rtti");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -658,10 +664,10 @@ build_dynamic_cast_1 (tree type, tree expr)
|
|||
static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
|
||||
td2 = get_tinfo_decl (target_type);
|
||||
mark_used (td2);
|
||||
td2 = build_unary_op (ADDR_EXPR, td2, 0);
|
||||
td2 = cp_build_unary_op (ADDR_EXPR, td2, 0, complain);
|
||||
td3 = get_tinfo_decl (static_type);
|
||||
mark_used (td3);
|
||||
td3 = build_unary_op (ADDR_EXPR, td3, 0);
|
||||
td3 = cp_build_unary_op (ADDR_EXPR, td3, 0, complain);
|
||||
|
||||
/* Determine how T and V are related. */
|
||||
boff = dcast_base_hint (static_type, target_type);
|
||||
|
@ -671,7 +677,7 @@ build_dynamic_cast_1 (tree type, tree expr)
|
|||
|
||||
expr1 = expr;
|
||||
if (tc == REFERENCE_TYPE)
|
||||
expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
|
||||
expr1 = cp_build_unary_op (ADDR_EXPR, expr1, 0, complain);
|
||||
|
||||
elems[0] = expr1;
|
||||
elems[1] = td3;
|
||||
|
@ -726,13 +732,14 @@ build_dynamic_cast_1 (tree type, tree expr)
|
|||
errstr = "source type is not polymorphic";
|
||||
|
||||
fail:
|
||||
error ("cannot dynamic_cast %qE (of type %q#T) to type %q#T (%s)",
|
||||
expr, exprtype, type, errstr);
|
||||
if (complain & tf_error)
|
||||
error ("cannot dynamic_cast %qE (of type %q#T) to type %q#T (%s)",
|
||||
expr, exprtype, type, errstr);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
tree
|
||||
build_dynamic_cast (tree type, tree expr)
|
||||
build_dynamic_cast (tree type, tree expr, tsubst_flags_t complain)
|
||||
{
|
||||
if (type == error_mark_node || expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
@ -744,7 +751,7 @@ build_dynamic_cast (tree type, tree expr)
|
|||
return convert_from_reference (expr);
|
||||
}
|
||||
|
||||
return convert_from_reference (build_dynamic_cast_1 (type, expr));
|
||||
return convert_from_reference (build_dynamic_cast_1 (type, expr, complain));
|
||||
}
|
||||
|
||||
/* Return the runtime bit mask encoding the qualifiers of TYPE. */
|
||||
|
@ -876,7 +883,8 @@ tinfo_base_init (tinfo_s *ti, tree target)
|
|||
}
|
||||
|
||||
vtable_ptr = get_vtable_decl (real_type, /*complete=*/1);
|
||||
vtable_ptr = build_unary_op (ADDR_EXPR, vtable_ptr, 0);
|
||||
vtable_ptr = cp_build_unary_op (ADDR_EXPR, vtable_ptr, 0,
|
||||
tf_warning_or_error);
|
||||
|
||||
/* We need to point into the middle of the vtable. */
|
||||
vtable_ptr = build2
|
||||
|
|
|
@ -536,7 +536,7 @@ simplify_loop_decl_cond (tree *cond_p, tree body)
|
|||
*cond_p = boolean_true_node;
|
||||
|
||||
if_stmt = begin_if_stmt ();
|
||||
cond = build_unary_op (TRUTH_NOT_EXPR, cond, 0);
|
||||
cond = cp_build_unary_op (TRUTH_NOT_EXPR, cond, 0, tf_warning_or_error);
|
||||
finish_if_stmt_cond (cond, if_stmt);
|
||||
finish_break_stmt ();
|
||||
finish_then_clause (if_stmt);
|
||||
|
@ -614,10 +614,11 @@ finish_expr_stmt (tree expr)
|
|||
{
|
||||
if (warn_sequence_point)
|
||||
verify_sequence_points (expr);
|
||||
expr = convert_to_void (expr, "statement");
|
||||
expr = convert_to_void (expr, "statement", tf_warning_or_error);
|
||||
}
|
||||
else if (!type_dependent_expression_p (expr))
|
||||
convert_to_void (build_non_dependent_expr (expr), "statement");
|
||||
convert_to_void (build_non_dependent_expr (expr), "statement",
|
||||
tf_warning_or_error);
|
||||
|
||||
if (check_for_bare_parameter_packs (expr))
|
||||
expr = error_mark_node;
|
||||
|
@ -872,10 +873,12 @@ finish_for_expr (tree expr, tree for_stmt)
|
|||
{
|
||||
if (warn_sequence_point)
|
||||
verify_sequence_points (expr);
|
||||
expr = convert_to_void (expr, "3rd expression in for");
|
||||
expr = convert_to_void (expr, "3rd expression in for",
|
||||
tf_warning_or_error);
|
||||
}
|
||||
else if (!type_dependent_expression_p (expr))
|
||||
convert_to_void (build_non_dependent_expr (expr), "3rd expression in for");
|
||||
convert_to_void (build_non_dependent_expr (expr), "3rd expression in for",
|
||||
tf_warning_or_error);
|
||||
expr = maybe_cleanup_point_expr_void (expr);
|
||||
if (check_for_bare_parameter_packs (expr))
|
||||
expr = error_mark_node;
|
||||
|
@ -1247,7 +1250,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
|
|||
otherwise we'll get an error. Gross, but ... */
|
||||
STRIP_NOPS (operand);
|
||||
|
||||
if (!lvalue_or_else (operand, lv_asm))
|
||||
if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
|
||||
operand = error_mark_node;
|
||||
|
||||
if (operand != error_mark_node
|
||||
|
@ -1505,7 +1508,8 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
|
|||
|
||||
return build_class_member_access_expr (object, decl,
|
||||
/*access_path=*/NULL_TREE,
|
||||
/*preserve_reference=*/false);
|
||||
/*preserve_reference=*/false,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1643,7 +1647,8 @@ finish_qualified_id_expr (tree qualifying_class,
|
|||
(maybe_dummy_object (qualifying_class, NULL),
|
||||
expr,
|
||||
BASELINK_ACCESS_BINFO (expr),
|
||||
/*preserve_reference=*/false));
|
||||
/*preserve_reference=*/false,
|
||||
tf_warning_or_error));
|
||||
else if (done)
|
||||
/* The expression is a qualified name whose address is not
|
||||
being taken. */
|
||||
|
@ -1832,7 +1837,8 @@ perform_koenig_lookup (tree fn, tree args)
|
|||
Returns code for the call. */
|
||||
|
||||
tree
|
||||
finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
|
||||
finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
tree result;
|
||||
tree orig_fn;
|
||||
|
@ -1931,7 +1937,8 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
|
|||
result = build_new_method_call (object, fn, args, NULL_TREE,
|
||||
(disallow_virtual
|
||||
? LOOKUP_NONVIRTUAL : 0),
|
||||
/*fn_p=*/NULL);
|
||||
/*fn_p=*/NULL,
|
||||
complain);
|
||||
}
|
||||
else if (is_overloaded_fn (fn))
|
||||
{
|
||||
|
@ -1943,7 +1950,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
|
|||
|
||||
if (!result)
|
||||
/* A call to a namespace-scope function. */
|
||||
result = build_new_function_call (fn, args, koenig_p);
|
||||
result = build_new_function_call (fn, args, koenig_p, complain);
|
||||
}
|
||||
else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
|
||||
{
|
||||
|
@ -1960,11 +1967,11 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
|
|||
/* If the "function" is really an object of class type, it might
|
||||
have an overloaded `operator ()'. */
|
||||
result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE,
|
||||
/*overloaded_p=*/NULL);
|
||||
/*overloaded_p=*/NULL, complain);
|
||||
|
||||
if (!result)
|
||||
/* A call where the function is unknown. */
|
||||
result = build_function_call (fn, args);
|
||||
result = cp_build_function_call (fn, args, complain);
|
||||
|
||||
if (processing_template_decl)
|
||||
{
|
||||
|
@ -1981,7 +1988,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
|
|||
tree
|
||||
finish_increment_expr (tree expr, enum tree_code code)
|
||||
{
|
||||
return build_x_unary_op (code, expr);
|
||||
return build_x_unary_op (code, expr, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Finish a use of `this'. Returns an expression for `this'. */
|
||||
|
@ -2070,7 +2077,7 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor)
|
|||
tree
|
||||
finish_unary_op_expr (enum tree_code code, tree expr)
|
||||
{
|
||||
tree result = build_x_unary_op (code, expr);
|
||||
tree result = build_x_unary_op (code, expr, tf_warning_or_error);
|
||||
/* Inside a template, build_x_unary_op does not fold the
|
||||
expression. So check whether the result is folded before
|
||||
setting TREE_NEGATED_INT. */
|
||||
|
@ -2952,7 +2959,8 @@ finish_id_expression (tree id_expression,
|
|||
/* A set of member functions. */
|
||||
decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
|
||||
return finish_class_member_access_expr (decl, id_expression,
|
||||
/*template_p=*/false);
|
||||
/*template_p=*/false,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
decl = baselink_for_fns (decl);
|
||||
|
@ -3119,7 +3127,8 @@ simplify_aggr_init_expr (tree *tp)
|
|||
SLOT. */
|
||||
push_deferring_access_checks (dk_no_check);
|
||||
call_expr = build_aggr_init (slot, call_expr,
|
||||
DIRECT_BIND | LOOKUP_ONLYCONVERTING);
|
||||
DIRECT_BIND | LOOKUP_ONLYCONVERTING,
|
||||
tf_warning_or_error);
|
||||
pop_deferring_access_checks ();
|
||||
call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot);
|
||||
}
|
||||
|
@ -3668,7 +3677,8 @@ finish_omp_clauses (tree clauses)
|
|||
}
|
||||
t = build_special_member_call (NULL_TREE,
|
||||
complete_ctor_identifier,
|
||||
t, inner_type, LOOKUP_NORMAL);
|
||||
t, inner_type, LOOKUP_NORMAL,
|
||||
tf_warning_or_error);
|
||||
|
||||
if (targetm.cxx.cdtor_returns_this () || errorcount)
|
||||
/* Because constructors and destructors return this,
|
||||
|
@ -3690,7 +3700,8 @@ finish_omp_clauses (tree clauses)
|
|||
t = build_int_cst (build_pointer_type (inner_type), 0);
|
||||
t = build1 (INDIRECT_REF, inner_type, t);
|
||||
t = build_special_member_call (t, complete_dtor_identifier,
|
||||
NULL, inner_type, LOOKUP_NORMAL);
|
||||
NULL, inner_type, LOOKUP_NORMAL,
|
||||
tf_warning_or_error);
|
||||
|
||||
if (targetm.cxx.cdtor_returns_this () || errorcount)
|
||||
/* Because constructors and destructors return this,
|
||||
|
@ -3713,7 +3724,8 @@ finish_omp_clauses (tree clauses)
|
|||
t = build1 (INDIRECT_REF, inner_type, t);
|
||||
t = build_special_member_call (t, ansi_assopname (NOP_EXPR),
|
||||
build_tree_list (NULL, t),
|
||||
inner_type, LOOKUP_NORMAL);
|
||||
inner_type, LOOKUP_NORMAL,
|
||||
tf_warning_or_error);
|
||||
|
||||
/* We'll have called convert_from_reference on the call, which
|
||||
may well have added an indirect_ref. It's unneeded here,
|
||||
|
@ -3937,7 +3949,7 @@ finish_omp_for (location_t locus, tree decl, tree init, tree cond,
|
|||
|
||||
if (!processing_template_decl)
|
||||
init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
|
||||
init = build_modify_expr (decl, NOP_EXPR, init);
|
||||
init = cp_build_modify_expr (decl, NOP_EXPR, init, tf_warning_or_error);
|
||||
if (cond && TREE_SIDE_EFFECTS (cond) && COMPARISON_CLASS_P (cond))
|
||||
{
|
||||
int n = TREE_SIDE_EFFECTS (TREE_OPERAND (cond, 1)) != 0;
|
||||
|
@ -4006,7 +4018,7 @@ void
|
|||
finish_omp_barrier (void)
|
||||
{
|
||||
tree fn = built_in_decls[BUILT_IN_GOMP_BARRIER];
|
||||
tree stmt = finish_call_expr (fn, NULL, false, false);
|
||||
tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
|
||||
finish_expr_stmt (stmt);
|
||||
}
|
||||
|
||||
|
@ -4014,7 +4026,7 @@ void
|
|||
finish_omp_flush (void)
|
||||
{
|
||||
tree fn = built_in_decls[BUILT_IN_SYNCHRONIZE];
|
||||
tree stmt = finish_call_expr (fn, NULL, false, false);
|
||||
tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
|
||||
finish_expr_stmt (stmt);
|
||||
}
|
||||
|
||||
|
|
|
@ -1992,7 +1992,7 @@ tree
|
|||
build_dummy_object (tree type)
|
||||
{
|
||||
tree decl = build1 (NOP_EXPR, build_pointer_type (type), void_zero_node);
|
||||
return build_indirect_ref (decl, NULL);
|
||||
return cp_build_indirect_ref (decl, NULL, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* We've gotten a reference to a member of TYPE. Return *this if appropriate,
|
||||
|
@ -2569,10 +2569,10 @@ stabilize_expr (tree exp, tree* initp)
|
|||
}
|
||||
else
|
||||
{
|
||||
exp = build_unary_op (ADDR_EXPR, exp, 1);
|
||||
exp = cp_build_unary_op (ADDR_EXPR, exp, 1, tf_warning_or_error);
|
||||
init_expr = get_target_expr (exp);
|
||||
exp = TARGET_EXPR_SLOT (init_expr);
|
||||
exp = build_indirect_ref (exp, 0);
|
||||
exp = cp_build_indirect_ref (exp, 0, tf_warning_or_error);
|
||||
}
|
||||
*initp = init_expr;
|
||||
|
||||
|
|
947
gcc/cp/typeck.c
947
gcc/cp/typeck.c
File diff suppressed because it is too large
Load Diff
|
@ -707,7 +707,8 @@ digest_init (tree type, tree init)
|
|||
tree *exp;
|
||||
|
||||
init = convert_for_initialization (0, type, init, LOOKUP_NORMAL,
|
||||
"initialization", NULL_TREE, 0);
|
||||
"initialization", NULL_TREE, 0,
|
||||
tf_warning_or_error);
|
||||
exp = &init;
|
||||
|
||||
/* Skip any conversions since we'll be outputting the underlying
|
||||
|
@ -751,7 +752,8 @@ digest_init (tree type, tree init)
|
|||
|
||||
return convert_for_initialization (NULL_TREE, type, init,
|
||||
LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING,
|
||||
"initialization", NULL_TREE, 0);
|
||||
"initialization", NULL_TREE, 0,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -849,7 +851,8 @@ process_init_constructor_array (tree type, tree init)
|
|||
TARGET_EXPRs. If the type in question is a class, just build
|
||||
one up; if it's an array, recurse. */
|
||||
if (MAYBE_CLASS_TYPE_P (TREE_TYPE (type)))
|
||||
next = build_functional_cast (TREE_TYPE (type), NULL_TREE);
|
||||
next = build_functional_cast (TREE_TYPE (type), NULL_TREE,
|
||||
tf_warning_or_error);
|
||||
else
|
||||
next = build_constructor (NULL_TREE, NULL);
|
||||
next = digest_init (TREE_TYPE (type), next);
|
||||
|
@ -936,7 +939,8 @@ process_init_constructor_record (tree type, tree init)
|
|||
for us, so build up TARGET_EXPRs. If the type in question is
|
||||
a class, just build one up; if it's an array, recurse. */
|
||||
if (MAYBE_CLASS_TYPE_P (TREE_TYPE (field)))
|
||||
next = build_functional_cast (TREE_TYPE (field), NULL_TREE);
|
||||
next = build_functional_cast (TREE_TYPE (field), NULL_TREE,
|
||||
tf_warning_or_error);
|
||||
else
|
||||
next = build_constructor (NULL_TREE, NULL);
|
||||
|
||||
|
@ -1165,7 +1169,8 @@ build_x_arrow (tree expr)
|
|||
{
|
||||
while ((expr = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, expr,
|
||||
NULL_TREE, NULL_TREE,
|
||||
/*overloaded_p=*/NULL)))
|
||||
/*overloaded_p=*/NULL,
|
||||
tf_warning_or_error)))
|
||||
{
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
@ -1205,7 +1210,7 @@ build_x_arrow (tree expr)
|
|||
return expr;
|
||||
}
|
||||
|
||||
return build_indirect_ref (last_rval, NULL);
|
||||
return cp_build_indirect_ref (last_rval, NULL, tf_warning_or_error);
|
||||
}
|
||||
|
||||
if (types_memoized)
|
||||
|
@ -1297,7 +1302,7 @@ build_m_component_ref (tree datum, tree component)
|
|||
datum = build2 (POINTER_PLUS_EXPR, ptype,
|
||||
fold_convert (ptype, datum),
|
||||
build_nop (sizetype, component));
|
||||
return build_indirect_ref (datum, 0);
|
||||
return cp_build_indirect_ref (datum, 0, tf_warning_or_error);
|
||||
}
|
||||
else
|
||||
return build2 (OFFSET_REF, type, datum, component);
|
||||
|
@ -1306,7 +1311,7 @@ build_m_component_ref (tree datum, tree component)
|
|||
/* Return a tree node for the expression TYPENAME '(' PARMS ')'. */
|
||||
|
||||
tree
|
||||
build_functional_cast (tree exp, tree parms)
|
||||
build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
|
||||
{
|
||||
/* This is either a call to a constructor,
|
||||
or a C cast in C++'s `functional' notation. */
|
||||
|
@ -1337,7 +1342,7 @@ build_functional_cast (tree exp, tree parms)
|
|||
|
||||
/* This must build a C cast. */
|
||||
parms = build_x_compound_expr_from_list (parms, "functional cast");
|
||||
return build_c_cast (type, parms);
|
||||
return build_c_cast (type, parms, complain);
|
||||
}
|
||||
|
||||
/* Prepare to evaluate as a call to a constructor. If this expression
|
||||
|
@ -1358,7 +1363,7 @@ build_functional_cast (tree exp, tree parms)
|
|||
conversion is equivalent (in definedness, and if defined in
|
||||
meaning) to the corresponding cast expression. */
|
||||
if (parms && TREE_CHAIN (parms) == NULL_TREE)
|
||||
return build_c_cast (type, TREE_VALUE (parms));
|
||||
return build_c_cast (type, TREE_VALUE (parms), complain);
|
||||
|
||||
/* [expr.type.conv]
|
||||
|
||||
|
@ -1378,7 +1383,7 @@ build_functional_cast (tree exp, tree parms)
|
|||
|
||||
/* Call the constructor. */
|
||||
exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, parms,
|
||||
type, LOOKUP_NORMAL);
|
||||
type, LOOKUP_NORMAL, complain);
|
||||
|
||||
if (exp == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
2008-03-25 Douglas Gregor <doug.gregor@gmail.com>
|
||||
|
||||
* g++.dg/template/sfinae4.C: New.
|
||||
* g++.dg/template/sfinae5.C: New.
|
||||
* g++.dg/template/sfinae6.C: New.
|
||||
* g++.dg/template/sfinae6_neg.C: New.
|
||||
* g++.dg/template/sfinae7.C: New.
|
||||
* g++.dg/template/sfinae8.C: New.
|
||||
* g++.dg/template/sfinae9.C: New.
|
||||
* g++.dg/template/sfinae10.C: New.
|
||||
* g++.dg/template/sfinae11.C: New.
|
||||
* g++.dg/template/sfinae12.C: New.
|
||||
* g++.dg/template/sfinae13.C: New.
|
||||
* g++.dg/template/sfinae14C: New.
|
||||
|
||||
2008-03-25 Naveen.H.S <naveen.hs@kpitcummins.com>
|
||||
|
||||
* gcc.target/sh/sh2a-bclr.c: New test.
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of various unary operators with SFINAE
|
||||
|
||||
// Boilerplate helpers
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
template<typename T> struct type { };
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
#define JOIN( X, Y ) DO_JOIN( X, Y )
|
||||
#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
||||
#define DO_JOIN2( X, Y ) X##Y
|
||||
|
||||
#define DEFINE_PREFIX_UNARY_TRAIT(Name,Op) \
|
||||
template<typename T> \
|
||||
typename enable_if<(sizeof(Op create_a<T>(), 1) > 0), \
|
||||
yes_type>::type \
|
||||
JOIN(check_,Name)(int); \
|
||||
\
|
||||
template<typename T> \
|
||||
no_type JOIN(check_,Name)(...); \
|
||||
\
|
||||
template<typename T> \
|
||||
struct Name \
|
||||
{ \
|
||||
static const bool value = \
|
||||
(sizeof(JOIN(check_,Name)<T&>(0)) == sizeof(yes_type)); \
|
||||
}
|
||||
|
||||
#define DEFINE_POSTFIX_UNARY_TRAIT(Name,Op) \
|
||||
template<typename T> \
|
||||
typename enable_if<(sizeof(create_a<T>() Op, 1) > 0), \
|
||||
yes_type>::type \
|
||||
JOIN(check_,Name)(int); \
|
||||
\
|
||||
template<typename T> \
|
||||
no_type JOIN(check_,Name)(...); \
|
||||
\
|
||||
template<typename T> \
|
||||
struct Name \
|
||||
{ \
|
||||
static const bool value = \
|
||||
(sizeof(JOIN(check_,Name)<T&>(0)) == sizeof(yes_type)); \
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
||||
#else
|
||||
# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
||||
#endif
|
||||
|
||||
struct W {
|
||||
W operator+();
|
||||
W operator-();
|
||||
int operator*();
|
||||
W operator~();
|
||||
bool operator!();
|
||||
W& operator++();
|
||||
W& operator--();
|
||||
W& operator++(int);
|
||||
W& operator--(int);
|
||||
};
|
||||
|
||||
struct X { };
|
||||
X operator+(X);
|
||||
X operator-(X);
|
||||
int operator*(X);
|
||||
X operator~(X);
|
||||
bool operator!(X);
|
||||
X& operator++(X&);
|
||||
X& operator--(X&);
|
||||
X& operator++(X&, int);
|
||||
X& operator--(X&, int);
|
||||
|
||||
struct Y { };
|
||||
|
||||
struct Z {
|
||||
private:
|
||||
Z operator+(); // { dg-error "is private" }
|
||||
Z operator-(); // { dg-error "is private" }
|
||||
int operator*(); // { dg-error "is private" }
|
||||
Z operator~(); // { dg-error "is private" }
|
||||
bool operator!(); // { dg-error "is private" }
|
||||
Z& operator++(); // { dg-error "is private" }
|
||||
Z& operator--(); // { dg-error "is private" }
|
||||
Z& operator++(int); // { dg-error "is private" }
|
||||
Z& operator--(int); // { dg-error "is private" }
|
||||
};
|
||||
|
||||
// has_unary_plus
|
||||
DEFINE_PREFIX_UNARY_TRAIT(has_unary_plus, +); // { dg-error "within this context" }
|
||||
STATIC_ASSERT((has_unary_plus<int>::value));
|
||||
STATIC_ASSERT((!has_unary_plus<int X::*>::value));
|
||||
STATIC_ASSERT((has_unary_plus<W>::value));
|
||||
STATIC_ASSERT((has_unary_plus<X>::value));
|
||||
STATIC_ASSERT((!has_unary_plus<Y>::value));
|
||||
|
||||
// is_negatable
|
||||
DEFINE_PREFIX_UNARY_TRAIT(is_negatable, -); // { dg-error "within this context" }
|
||||
STATIC_ASSERT((is_negatable<int>::value));
|
||||
STATIC_ASSERT((!is_negatable<int X::*>::value));
|
||||
STATIC_ASSERT((is_negatable<W>::value));
|
||||
STATIC_ASSERT((is_negatable<X>::value));
|
||||
STATIC_ASSERT((!is_negatable<Y>::value));
|
||||
|
||||
// is_dereferenceable
|
||||
DEFINE_PREFIX_UNARY_TRAIT(is_dereferenceable, *); // { dg-error "within this context" }
|
||||
STATIC_ASSERT((!is_dereferenceable<int>::value));
|
||||
STATIC_ASSERT((is_dereferenceable<int*>::value));
|
||||
STATIC_ASSERT((is_dereferenceable<W>::value));
|
||||
STATIC_ASSERT((is_dereferenceable<X>::value));
|
||||
STATIC_ASSERT((!is_dereferenceable<Y>::value));
|
||||
|
||||
// has_bitwise_not
|
||||
DEFINE_PREFIX_UNARY_TRAIT(has_bitwise_not, ~); // { dg-error "within this context" }
|
||||
STATIC_ASSERT((has_bitwise_not<int>::value));
|
||||
STATIC_ASSERT((!has_bitwise_not<int*>::value));
|
||||
STATIC_ASSERT((has_bitwise_not<W>::value));
|
||||
STATIC_ASSERT((has_bitwise_not<X>::value));
|
||||
STATIC_ASSERT((!has_bitwise_not<Y>::value));
|
||||
|
||||
// has_truth_not
|
||||
DEFINE_PREFIX_UNARY_TRAIT(has_truth_not, !); // { dg-error "within this context" }
|
||||
STATIC_ASSERT((has_truth_not<int>::value));
|
||||
STATIC_ASSERT((has_truth_not<int*>::value));
|
||||
STATIC_ASSERT((has_truth_not<W>::value));
|
||||
STATIC_ASSERT((has_truth_not<X>::value));
|
||||
STATIC_ASSERT((!has_truth_not<Y>::value));
|
||||
|
||||
// has_preincrement
|
||||
DEFINE_PREFIX_UNARY_TRAIT(has_preincrement, ++); // { dg-error "within this context" }
|
||||
STATIC_ASSERT((has_preincrement<int>::value));
|
||||
STATIC_ASSERT((has_preincrement<int*>::value));
|
||||
STATIC_ASSERT((!has_preincrement<int X::*>::value));
|
||||
STATIC_ASSERT((has_preincrement<W>::value));
|
||||
STATIC_ASSERT((has_preincrement<X>::value));
|
||||
STATIC_ASSERT((!has_preincrement<Y>::value));
|
||||
|
||||
// has_predecrement
|
||||
DEFINE_PREFIX_UNARY_TRAIT(has_predecrement, --); // { dg-error "within this context" }
|
||||
STATIC_ASSERT((has_predecrement<int>::value));
|
||||
STATIC_ASSERT((has_predecrement<int*>::value));
|
||||
STATIC_ASSERT((!has_predecrement<int X::*>::value));
|
||||
STATIC_ASSERT((has_predecrement<W>::value));
|
||||
STATIC_ASSERT((has_predecrement<X>::value));
|
||||
STATIC_ASSERT((!has_predecrement<Y>::value));
|
||||
|
||||
// has_postincrement
|
||||
DEFINE_POSTFIX_UNARY_TRAIT(has_postincrement, ++); // { dg-error "within this context" }
|
||||
STATIC_ASSERT((has_postincrement<int>::value));
|
||||
STATIC_ASSERT((has_postincrement<int*>::value));
|
||||
STATIC_ASSERT((!has_postincrement<int X::*>::value));
|
||||
STATIC_ASSERT((has_postincrement<W>::value));
|
||||
STATIC_ASSERT((has_postincrement<X>::value));
|
||||
STATIC_ASSERT((!has_postincrement<Y>::value));
|
||||
|
||||
// has_postdecrement
|
||||
DEFINE_POSTFIX_UNARY_TRAIT(has_postdecrement, --); // { dg-error "within this context" }
|
||||
STATIC_ASSERT((has_postdecrement<int>::value));
|
||||
STATIC_ASSERT((has_postdecrement<int*>::value));
|
||||
STATIC_ASSERT((!has_postdecrement<int X::*>::value));
|
||||
STATIC_ASSERT((has_postdecrement<W>::value));
|
||||
STATIC_ASSERT((has_postdecrement<X>::value));
|
||||
STATIC_ASSERT((!has_postdecrement<Y>::value));
|
||||
|
||||
// Check for private members
|
||||
STATIC_ASSERT((has_unary_plus<Z>::value)); // { dg-error "instantiated from here" }
|
||||
STATIC_ASSERT((is_negatable<Z>::value)); // { dg-error "instantiated from here" }
|
||||
STATIC_ASSERT((is_dereferenceable<Z>::value)); // { dg-error "instantiated from here" }
|
||||
STATIC_ASSERT((has_bitwise_not<Z>::value)); // { dg-error "instantiated from here" }
|
||||
STATIC_ASSERT((has_truth_not<Z>::value)); // { dg-error "instantiated from here" }
|
||||
STATIC_ASSERT((has_preincrement<Z>::value)); // { dg-error "instantiated from here" }
|
||||
STATIC_ASSERT((has_predecrement<Z>::value)); // { dg-error "instantiated from here" }
|
||||
STATIC_ASSERT((has_postincrement<Z>::value)); // { dg-error "instantiated from here" }
|
||||
STATIC_ASSERT((has_postdecrement<Z>::value)); // { dg-error "instantiated from here" }
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of the comma operator with SFINAE
|
||||
|
||||
// Boilerplate helpers
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
template<typename T> struct type { };
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
#define JOIN( X, Y ) DO_JOIN( X, Y )
|
||||
#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
||||
#define DO_JOIN2( X, Y ) X##Y
|
||||
|
||||
template<typename T, typename U>
|
||||
typename enable_if<(sizeof(create_a<T>(), create_a<U>()) > 0),
|
||||
yes_type>::type
|
||||
check_comma(int);
|
||||
|
||||
template<typename T, typename U> no_type check_comma(...);
|
||||
|
||||
template<typename T, typename U>
|
||||
struct has_comma
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_comma<T, U>(0)) == sizeof(yes_type));
|
||||
};
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
||||
#else
|
||||
# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
||||
#endif
|
||||
|
||||
struct X { };
|
||||
struct Y { };
|
||||
struct Z { };
|
||||
|
||||
bool operator,(X&, Y);
|
||||
bool operator,(X, Z);
|
||||
void operator,(const Y&, const Z&);
|
||||
|
||||
STATIC_ASSERT((has_comma<int, float>::value));
|
||||
STATIC_ASSERT((has_comma<int, X>::value));
|
||||
STATIC_ASSERT((has_comma<X, X>::value));
|
||||
STATIC_ASSERT((has_comma<X, Y>::value));
|
||||
STATIC_ASSERT((has_comma<X&, Y>::value));
|
||||
STATIC_ASSERT((has_comma<X, Z>::value));
|
||||
STATIC_ASSERT((!has_comma<Y, Z>::value));
|
|
@ -0,0 +1,47 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of the ternary operator with SFINAE
|
||||
|
||||
// Boilerplate helpers
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
template<typename T> struct type { };
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
#define JOIN( X, Y ) DO_JOIN( X, Y )
|
||||
#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
||||
#define DO_JOIN2( X, Y ) X##Y
|
||||
|
||||
template<typename T, typename U, typename V>
|
||||
typename enable_if<
|
||||
(sizeof((create_a<T>()? create_a<U>() : create_a<V>()), 0) > 0),
|
||||
yes_type>::type
|
||||
check_ternary(int);
|
||||
|
||||
template<typename T, typename U, typename V> no_type check_ternary(...);
|
||||
|
||||
template<typename T, typename U, typename V>
|
||||
struct has_ternary
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_ternary<T, U, V>(0)) == sizeof(yes_type));
|
||||
};
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
||||
#else
|
||||
# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
||||
#endif
|
||||
|
||||
struct X { };
|
||||
struct Y { operator bool(); };
|
||||
|
||||
STATIC_ASSERT((has_ternary<int, float, double>::value));
|
||||
STATIC_ASSERT((has_ternary<bool, double, double>::value));
|
||||
STATIC_ASSERT((!has_ternary<int, float*, double>::value));
|
||||
STATIC_ASSERT((!has_ternary<X, double, double>::value));
|
||||
STATIC_ASSERT((has_ternary<Y, double, double>::value));
|
|
@ -0,0 +1,86 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of casts with SFINAE
|
||||
|
||||
// Boilerplate helpers
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
template<typename T> struct type { };
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
#define JOIN( X, Y ) DO_JOIN( X, Y )
|
||||
#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
||||
#define DO_JOIN2( X, Y ) X##Y
|
||||
|
||||
#define CHECK_CAST(CastKind) \
|
||||
template<typename T, typename U> \
|
||||
typename enable_if<(sizeof((JOIN(CastKind,_cast)<U>(create_a<T>())), 0) > 0), \
|
||||
yes_type>::type \
|
||||
JOIN(check_,JOIN(CastKind,_cast))(int); \
|
||||
\
|
||||
template<typename T, typename U> \
|
||||
no_type JOIN(check_,JOIN(CastKind,_cast))(...); \
|
||||
\
|
||||
template<typename T, typename U> \
|
||||
struct JOIN(has_,JOIN(CastKind,_cast)) \
|
||||
{ \
|
||||
static const bool value = \
|
||||
(sizeof(JOIN(check_,JOIN(CastKind,_cast))<T, U>(0)) == sizeof(yes_type)); \
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
typename enable_if<(sizeof(((U)create_a<T>()), 0) > 0), yes_type>::type
|
||||
check_c_cast(int);
|
||||
|
||||
template<typename T, typename U> no_type check_c_cast(...);
|
||||
|
||||
template<typename T, typename U>
|
||||
struct has_c_cast
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_c_cast<T, U>(0)) == sizeof(yes_type));
|
||||
};
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
||||
#else
|
||||
# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
||||
#endif
|
||||
|
||||
CHECK_CAST(static);
|
||||
CHECK_CAST(dynamic);
|
||||
CHECK_CAST(const);
|
||||
CHECK_CAST(reinterpret);
|
||||
|
||||
struct X { virtual void f(); };
|
||||
struct Y { operator bool(); };
|
||||
struct Z : public X { };
|
||||
|
||||
STATIC_ASSERT((has_static_cast<int, float>::value));
|
||||
STATIC_ASSERT((!has_static_cast<X, Y>::value));
|
||||
STATIC_ASSERT((has_static_cast<Z, X>::value));
|
||||
|
||||
STATIC_ASSERT(!(has_dynamic_cast<int, float>::value));
|
||||
STATIC_ASSERT(!(has_dynamic_cast<X, Y>::value));
|
||||
STATIC_ASSERT(!(has_dynamic_cast<X, Z>::value));
|
||||
STATIC_ASSERT(!(has_dynamic_cast<Y, Z>::value));
|
||||
STATIC_ASSERT((has_dynamic_cast<X*, Z*>::value));
|
||||
STATIC_ASSERT((has_dynamic_cast<X*, Y*>::value));
|
||||
STATIC_ASSERT(!(has_dynamic_cast<Y*, Z*>::value));
|
||||
|
||||
STATIC_ASSERT(!(has_const_cast<int, float>::value));
|
||||
STATIC_ASSERT((has_const_cast<const int*, int*>::value));
|
||||
STATIC_ASSERT((has_const_cast<int*, const int*>::value));
|
||||
STATIC_ASSERT(!(has_const_cast<const int*, float*>::value));
|
||||
|
||||
STATIC_ASSERT((has_reinterpret_cast<int*, float*>::value));
|
||||
STATIC_ASSERT(!(has_reinterpret_cast<void*, char>::value));
|
||||
STATIC_ASSERT(!(has_reinterpret_cast<const X, X>::value));
|
||||
|
||||
STATIC_ASSERT((has_c_cast<int, float>::value));
|
||||
STATIC_ASSERT(!(has_c_cast<X, Y>::value));
|
||||
STATIC_ASSERT(!(has_c_cast<void*, char>::value));
|
|
@ -0,0 +1,79 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of the new and new[] operators with SFINAE
|
||||
|
||||
// Boilerplate helpers
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
template<typename T> struct type { };
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
#define JOIN( X, Y ) DO_JOIN( X, Y )
|
||||
#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
||||
#define DO_JOIN2( X, Y ) X##Y
|
||||
|
||||
template<typename T>
|
||||
typename enable_if<(sizeof(new T, 0) > 0), yes_type>::type
|
||||
check_new(int);
|
||||
|
||||
template<typename T> no_type check_new(...);
|
||||
|
||||
template<typename T>
|
||||
struct has_new
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_new<T>(0)) == sizeof(yes_type));
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
typename enable_if<(sizeof((new T(create_a<U>())), 0) > 0),
|
||||
yes_type>::type
|
||||
check_new_one_arg(int);
|
||||
|
||||
template<typename T, typename U> no_type check_new_one_arg(...);
|
||||
|
||||
template<typename T, typename U>
|
||||
struct has_new_one_arg
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_new_one_arg<T, U>(0)) == sizeof(yes_type));
|
||||
};
|
||||
|
||||
template<typename T, typename U, U N>
|
||||
typename enable_if<(sizeof(new T[N], 0) > 0), yes_type>::type
|
||||
check_array_new(int);
|
||||
|
||||
template<typename T, typename U, U N> no_type check_array_new(...);
|
||||
|
||||
template<typename T, typename U, U N>
|
||||
struct has_array_new
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_array_new<T, U, N>(0)) == sizeof(yes_type));
|
||||
};
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
||||
#else
|
||||
# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
||||
#endif
|
||||
|
||||
struct X {
|
||||
X(int);
|
||||
};
|
||||
|
||||
struct Y { int foo; };
|
||||
|
||||
STATIC_ASSERT((has_new<Y>::value));
|
||||
STATIC_ASSERT(!(has_new<X>::value));
|
||||
STATIC_ASSERT((has_new_one_arg<Y, Y>::value));
|
||||
STATIC_ASSERT((has_new_one_arg<X, float>::value));
|
||||
STATIC_ASSERT(!(has_new_one_arg<X, int X::*>::value));
|
||||
|
||||
STATIC_ASSERT((has_array_new<Y, int, 5>::value));
|
||||
STATIC_ASSERT(!(has_array_new<X, int Y::*, &Y::foo>::value));
|
||||
STATIC_ASSERT((has_array_new<X, int, 5>::value));
|
|
@ -0,0 +1,35 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of free functions with SFINAE
|
||||
void foo(int) { }
|
||||
template<typename T> void foo(T*) { }
|
||||
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
template<typename T>
|
||||
typename enable_if<(sizeof(foo(create_a<T const&>()), 1) > 0),
|
||||
yes_type>::type
|
||||
check_has_foo(const volatile T&);
|
||||
|
||||
no_type check_has_foo(...);
|
||||
|
||||
template<typename T>
|
||||
struct has_foo
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_has_foo(create_a<T const&>())) == sizeof(yes_type));
|
||||
};
|
||||
|
||||
struct X { };
|
||||
|
||||
int a1[has_foo<int>::value? 1 : -1];
|
||||
int a2[has_foo<long>::value? 1 : -1];
|
||||
int a3[has_foo<int*>::value? 1 : -1];
|
||||
int a4[has_foo<X>::value? -1 : 1];
|
||||
int a5[has_foo<int X::*>::value? -1 : 1];
|
|
@ -0,0 +1,47 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of member functions with SFINAE
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
template<typename T>
|
||||
typename enable_if<(sizeof(create_a<T>().foo(), 1) > 0),
|
||||
yes_type>::type
|
||||
check_has_member_foo(const volatile T&);
|
||||
|
||||
no_type check_has_member_foo(...);
|
||||
|
||||
template<typename T>
|
||||
struct has_foo
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_has_member_foo(create_a<T const&>())) == sizeof(yes_type));
|
||||
};
|
||||
|
||||
struct X { };
|
||||
struct Y {
|
||||
void foo();
|
||||
};
|
||||
struct Z {
|
||||
void foo(int);
|
||||
};
|
||||
|
||||
struct A {
|
||||
int foo;
|
||||
};
|
||||
|
||||
struct B {
|
||||
static int foo();
|
||||
};
|
||||
|
||||
int a1[has_foo<X>::value? -1 : 1];
|
||||
int a2[has_foo<Y>::value? 1 : -1];
|
||||
int a3[has_foo<Z>::value? -1 : 1];
|
||||
int a4[has_foo<int>::value? -1 : 1];
|
||||
int a5[has_foo<A>::value? -1 : 1];
|
||||
int a6[has_foo<B>::value? 1 : -1];
|
|
@ -0,0 +1,83 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of the function call operator with SFINAE
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
|
||||
template<typename T> struct type { };
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
template<typename F, typename T1, typename T2>
|
||||
typename enable_if<sizeof(create_a<F>()(create_a<T1>(), create_a<T2>()), 1),
|
||||
yes_type>::type
|
||||
check_is_callable2(type<F>, type<T1>, type<T2>);
|
||||
|
||||
no_type check_is_callable2(...);
|
||||
|
||||
template<typename F, typename T1, typename T2 = T1>
|
||||
struct is_callable2
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_is_callable2(type<F>(), type<T1>(), type<T2>()))
|
||||
== sizeof(yes_type));
|
||||
};
|
||||
|
||||
#define JOIN( X, Y ) DO_JOIN( X, Y )
|
||||
#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
||||
#define DO_JOIN2( X, Y ) X##Y
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
||||
#else
|
||||
# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
||||
#endif
|
||||
|
||||
|
||||
struct A;
|
||||
struct B;
|
||||
|
||||
struct A {
|
||||
A(B);
|
||||
};
|
||||
|
||||
struct B {
|
||||
B(A);
|
||||
};
|
||||
|
||||
struct F1 { };
|
||||
|
||||
struct F2 {
|
||||
bool operator()(int, float);
|
||||
};
|
||||
|
||||
struct F3 {
|
||||
bool operator()(int);
|
||||
};
|
||||
|
||||
struct F4 {
|
||||
void operator()(A, A);
|
||||
void operator()(B, B);
|
||||
};
|
||||
|
||||
struct F5 {
|
||||
void operator()(A, A);
|
||||
|
||||
private:
|
||||
void operator()(B, B);
|
||||
};
|
||||
|
||||
STATIC_ASSERT((is_callable2<int(*)(int, int), long, int>::value));
|
||||
STATIC_ASSERT((!is_callable2<int(*)(int, int), int*, int>::value));
|
||||
STATIC_ASSERT((!is_callable2<F1, int, int>::value));
|
||||
STATIC_ASSERT((is_callable2<F2, int, int>::value));
|
||||
STATIC_ASSERT((!is_callable2<F2, int*, int>::value));
|
||||
STATIC_ASSERT((!is_callable2<F3, int, int>::value));
|
||||
STATIC_ASSERT((is_callable2<F4, A, A>::value));
|
||||
STATIC_ASSERT((is_callable2<F4, B, B>::value));
|
||||
STATIC_ASSERT((!is_callable2<F4, A, B>::value));
|
||||
STATIC_ASSERT((is_callable2<F5, A, A>::value));
|
||||
STATIC_ASSERT((!is_callable2<F5, A, B>::value));
|
|
@ -0,0 +1,58 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of the function call operator with SFINAE
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
|
||||
template<typename T> struct type { };
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
template<typename F, typename T1, typename T2>
|
||||
typename enable_if<sizeof(create_a<F>()(create_a<T1>(), create_a<T2>()), 1),
|
||||
yes_type>::type
|
||||
check_is_callable2(type<F>, type<T1>, type<T2>);
|
||||
|
||||
no_type check_is_callable2(...);
|
||||
|
||||
template<typename F, typename T1, typename T2 = T1>
|
||||
struct is_callable2
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_is_callable2(type<F>(), type<T1>(), type<T2>()))
|
||||
== sizeof(yes_type)); // { dg-error "within this context" }
|
||||
};
|
||||
|
||||
#define JOIN( X, Y ) DO_JOIN( X, Y )
|
||||
#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
||||
#define DO_JOIN2( X, Y ) X##Y
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
||||
#else
|
||||
# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
||||
#endif
|
||||
|
||||
|
||||
struct A;
|
||||
struct B;
|
||||
|
||||
struct A {
|
||||
A(B);
|
||||
};
|
||||
|
||||
struct B {
|
||||
B(A);
|
||||
};
|
||||
|
||||
struct F {
|
||||
void operator()(A, A);
|
||||
|
||||
private:
|
||||
void operator()(B, B); // { dg-error "is private" }
|
||||
};
|
||||
|
||||
STATIC_ASSERT((is_callable2<F, B, B>::value));
|
|
@ -0,0 +1,199 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of various binary operators with SFINAE
|
||||
|
||||
// Boilerplate helpers
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
template<typename T> struct type { };
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
#define JOIN( X, Y ) DO_JOIN( X, Y )
|
||||
#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
||||
#define DO_JOIN2( X, Y ) X##Y
|
||||
|
||||
#define DEFINE_INFIX_BINARY_TRAIT(Name,Op) \
|
||||
template<typename T, typename U> \
|
||||
typename enable_if<(sizeof(create_a<T>() Op create_a<U>(), 1) > 0), \
|
||||
yes_type>::type \
|
||||
JOIN(check_,Name)(type<T>, type<U>); \
|
||||
\
|
||||
no_type JOIN(check_,Name)(...); \
|
||||
\
|
||||
template<typename T, typename U = T> \
|
||||
struct Name \
|
||||
{ \
|
||||
static const bool value = \
|
||||
(sizeof(JOIN(check_,Name)(type<T>(), type<U>())) == sizeof(yes_type)); \
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
typename enable_if<(sizeof(create_a<T>()[create_a<U>()], 1) > 0),
|
||||
yes_type>::type
|
||||
check_subscript(int);
|
||||
|
||||
template<typename T, typename U>
|
||||
no_type check_subscript(...);
|
||||
|
||||
template<typename T, typename U>
|
||||
struct can_subscript
|
||||
{
|
||||
static const bool value =
|
||||
(sizeof(check_subscript<T, U>(0)) == sizeof(yes_type));
|
||||
};
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
||||
#else
|
||||
# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
||||
#endif
|
||||
|
||||
struct X { };
|
||||
struct Y { int operator[](X); };
|
||||
|
||||
// is_addable
|
||||
DEFINE_INFIX_BINARY_TRAIT(is_addable, +);
|
||||
X operator+(X, X);
|
||||
X operator+(X, Y);
|
||||
STATIC_ASSERT((is_addable<int>::value));
|
||||
STATIC_ASSERT((is_addable<int, long>::value));
|
||||
STATIC_ASSERT((is_addable<X>::value));
|
||||
STATIC_ASSERT((is_addable<int*, int>::value));
|
||||
STATIC_ASSERT((!is_addable<int*>::value));
|
||||
STATIC_ASSERT((is_addable<X, Y>::value));
|
||||
STATIC_ASSERT((!is_addable<Y>::value));
|
||||
|
||||
// is_subtractable
|
||||
DEFINE_INFIX_BINARY_TRAIT(is_subtractable, -);
|
||||
X operator-(X, X);
|
||||
X operator-(X, Y);
|
||||
STATIC_ASSERT((is_subtractable<int>::value));
|
||||
STATIC_ASSERT((is_subtractable<int, long>::value));
|
||||
STATIC_ASSERT((is_subtractable<X>::value));
|
||||
STATIC_ASSERT((is_subtractable<int*, int>::value));
|
||||
STATIC_ASSERT((is_subtractable<int*>::value));
|
||||
STATIC_ASSERT((is_subtractable<X, Y>::value));
|
||||
STATIC_ASSERT((!is_subtractable<Y>::value));
|
||||
STATIC_ASSERT((!is_subtractable<int X::*>::value));
|
||||
|
||||
// is_multiplicable
|
||||
DEFINE_INFIX_BINARY_TRAIT(is_multiplicable, *);
|
||||
X operator*(X, X);
|
||||
X operator*(X, Y);
|
||||
STATIC_ASSERT((is_multiplicable<int>::value));
|
||||
STATIC_ASSERT((is_multiplicable<int, long>::value));
|
||||
STATIC_ASSERT((is_multiplicable<X>::value));
|
||||
STATIC_ASSERT((!is_multiplicable<int*, int>::value));
|
||||
STATIC_ASSERT((!is_multiplicable<int*>::value));
|
||||
STATIC_ASSERT((is_multiplicable<X, Y>::value));
|
||||
STATIC_ASSERT((!is_multiplicable<Y>::value));
|
||||
STATIC_ASSERT((!is_multiplicable<int X::*>::value));
|
||||
|
||||
// is_divisible
|
||||
DEFINE_INFIX_BINARY_TRAIT(is_divisible, /);
|
||||
X operator/(X, X);
|
||||
X operator/(X, Y);
|
||||
STATIC_ASSERT((is_divisible<int>::value));
|
||||
STATIC_ASSERT((is_divisible<int, long>::value));
|
||||
STATIC_ASSERT((is_divisible<X>::value));
|
||||
STATIC_ASSERT((!is_divisible<int*, int>::value));
|
||||
STATIC_ASSERT((!is_divisible<int*>::value));
|
||||
STATIC_ASSERT((is_divisible<X, Y>::value));
|
||||
STATIC_ASSERT((!is_divisible<Y>::value));
|
||||
STATIC_ASSERT((!is_divisible<int X::*>::value));
|
||||
|
||||
// has_remainder
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_remainder, %);
|
||||
X operator%(X, X);
|
||||
X operator%(X, Y);
|
||||
STATIC_ASSERT((has_remainder<int>::value));
|
||||
STATIC_ASSERT((has_remainder<int, long>::value));
|
||||
STATIC_ASSERT((!has_remainder<float>::value));
|
||||
STATIC_ASSERT((has_remainder<X>::value));
|
||||
STATIC_ASSERT((!has_remainder<int*, int>::value));
|
||||
STATIC_ASSERT((!has_remainder<int*>::value));
|
||||
STATIC_ASSERT((has_remainder<X, Y>::value));
|
||||
STATIC_ASSERT((!has_remainder<Y>::value));
|
||||
STATIC_ASSERT((!has_remainder<int X::*>::value));
|
||||
|
||||
// has_xor
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_xor, ^);
|
||||
X operator^(X, X);
|
||||
X operator^(X, Y);
|
||||
STATIC_ASSERT((has_xor<int>::value));
|
||||
STATIC_ASSERT((has_xor<int, long>::value));
|
||||
STATIC_ASSERT((!has_xor<float>::value));
|
||||
STATIC_ASSERT((has_xor<X>::value));
|
||||
STATIC_ASSERT((!has_xor<int*, int>::value));
|
||||
STATIC_ASSERT((!has_xor<int*>::value));
|
||||
STATIC_ASSERT((has_xor<X, Y>::value));
|
||||
STATIC_ASSERT((!has_xor<Y>::value));
|
||||
STATIC_ASSERT((!has_xor<int X::*>::value));
|
||||
|
||||
// has_bitand
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_bitand, &);
|
||||
X operator&(X, X);
|
||||
X operator&(X, Y);
|
||||
STATIC_ASSERT((has_bitand<int>::value));
|
||||
STATIC_ASSERT((has_bitand<int, long>::value));
|
||||
STATIC_ASSERT((!has_bitand<float>::value));
|
||||
STATIC_ASSERT((has_bitand<X>::value));
|
||||
STATIC_ASSERT((!has_bitand<int*, int>::value));
|
||||
STATIC_ASSERT((!has_bitand<int*>::value));
|
||||
STATIC_ASSERT((has_bitand<X, Y>::value));
|
||||
STATIC_ASSERT((!has_bitand<Y>::value));
|
||||
STATIC_ASSERT((!has_bitand<int X::*>::value));
|
||||
|
||||
// has_bitor
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_bitor, |);
|
||||
X operator|(X, X);
|
||||
X operator|(X, Y);
|
||||
STATIC_ASSERT((has_bitor<int>::value));
|
||||
STATIC_ASSERT((has_bitor<int, long>::value));
|
||||
STATIC_ASSERT((!has_bitor<float>::value));
|
||||
STATIC_ASSERT((has_bitor<X>::value));
|
||||
STATIC_ASSERT((!has_bitor<int*, int>::value));
|
||||
STATIC_ASSERT((!has_bitor<int*>::value));
|
||||
STATIC_ASSERT((has_bitor<X, Y>::value));
|
||||
STATIC_ASSERT((!has_bitor<Y>::value));
|
||||
STATIC_ASSERT((!has_bitor<int X::*>::value));
|
||||
|
||||
// has_left_shift
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_left_shift, <<);
|
||||
X operator<<(X, X);
|
||||
X operator<<(X, Y);
|
||||
STATIC_ASSERT((has_left_shift<int>::value));
|
||||
STATIC_ASSERT((has_left_shift<int, long>::value));
|
||||
STATIC_ASSERT((!has_left_shift<float>::value));
|
||||
STATIC_ASSERT((has_left_shift<X>::value));
|
||||
STATIC_ASSERT((!has_left_shift<int*, int>::value));
|
||||
STATIC_ASSERT((!has_left_shift<int*>::value));
|
||||
STATIC_ASSERT((has_left_shift<X, Y>::value));
|
||||
STATIC_ASSERT((!has_left_shift<Y>::value));
|
||||
STATIC_ASSERT((!has_left_shift<int X::*>::value));
|
||||
|
||||
// has_right_shift
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_right_shift, >>);
|
||||
X operator>>(X, X);
|
||||
X operator>>(X, Y);
|
||||
STATIC_ASSERT((has_right_shift<int>::value));
|
||||
STATIC_ASSERT((has_right_shift<int, long>::value));
|
||||
STATIC_ASSERT((!has_right_shift<float>::value));
|
||||
STATIC_ASSERT((has_right_shift<X>::value));
|
||||
STATIC_ASSERT((!has_right_shift<int*, int>::value));
|
||||
STATIC_ASSERT((!has_right_shift<int*>::value));
|
||||
STATIC_ASSERT((has_right_shift<X, Y>::value));
|
||||
STATIC_ASSERT((!has_right_shift<Y>::value));
|
||||
STATIC_ASSERT((!has_right_shift<int X::*>::value));
|
||||
|
||||
// can_subscript
|
||||
STATIC_ASSERT((can_subscript<int*, int>::value));
|
||||
STATIC_ASSERT((can_subscript<int, int*>::value));
|
||||
STATIC_ASSERT((can_subscript<int(&)[7], int>::value));
|
||||
STATIC_ASSERT((can_subscript<int, int(&)[7]>::value));
|
||||
STATIC_ASSERT((!can_subscript<X, Y>::value));
|
||||
STATIC_ASSERT((can_subscript<Y, X>::value));
|
|
@ -0,0 +1,182 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of various boolean binary operators with SFINAE
|
||||
|
||||
// Boilerplate helpers
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
template<typename T> struct type { };
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
#define JOIN( X, Y ) DO_JOIN( X, Y )
|
||||
#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
||||
#define DO_JOIN2( X, Y ) X##Y
|
||||
|
||||
bool accepts_bool(bool);
|
||||
|
||||
#define DEFINE_BINARY_PREDICATE_TRAIT(Name,Op) \
|
||||
template<typename T, typename U> \
|
||||
typename enable_if<sizeof(accepts_bool(create_a<T>() Op create_a<U>())), \
|
||||
yes_type>::type \
|
||||
JOIN(check_,Name)(type<T>, type<U>); \
|
||||
\
|
||||
no_type JOIN(check_,Name)(...); \
|
||||
\
|
||||
template<typename T, typename U = T> \
|
||||
struct Name \
|
||||
{ \
|
||||
static const bool value = \
|
||||
(sizeof(JOIN(check_,Name)(type<T>(), type<U>())) == sizeof(yes_type)); \
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
||||
#else
|
||||
# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
||||
#endif
|
||||
|
||||
struct X { };
|
||||
struct Y { };
|
||||
|
||||
struct convertible_to_bool {
|
||||
operator int convertible_to_bool::* ();
|
||||
};
|
||||
|
||||
struct not_convertible_to_bool { };
|
||||
|
||||
// is_less_than_comparable
|
||||
DEFINE_BINARY_PREDICATE_TRAIT(is_less_than_comparable,<);
|
||||
bool operator<(X, X);
|
||||
convertible_to_bool operator<(X, Y);
|
||||
not_convertible_to_bool operator<(Y, X);
|
||||
|
||||
STATIC_ASSERT((is_less_than_comparable<int>::value));
|
||||
STATIC_ASSERT((is_less_than_comparable<int, long>::value));
|
||||
STATIC_ASSERT((is_less_than_comparable<int*>::value));
|
||||
STATIC_ASSERT((is_less_than_comparable<X>::value));
|
||||
STATIC_ASSERT((is_less_than_comparable<X, Y>::value));
|
||||
STATIC_ASSERT((!is_less_than_comparable<Y, X>::value));
|
||||
STATIC_ASSERT((!is_less_than_comparable<Y>::value));
|
||||
|
||||
// is_less_equal_comparable
|
||||
DEFINE_BINARY_PREDICATE_TRAIT(is_less_equal_comparable,<=);
|
||||
bool operator<=(X, X);
|
||||
convertible_to_bool operator<=(X, Y);
|
||||
not_convertible_to_bool operator<=(Y, X);
|
||||
|
||||
STATIC_ASSERT((is_less_equal_comparable<int>::value));
|
||||
STATIC_ASSERT((is_less_equal_comparable<int, long>::value));
|
||||
STATIC_ASSERT((is_less_equal_comparable<int*>::value));
|
||||
STATIC_ASSERT((is_less_equal_comparable<X>::value));
|
||||
STATIC_ASSERT((is_less_equal_comparable<X, Y>::value));
|
||||
STATIC_ASSERT((!is_less_equal_comparable<Y, X>::value));
|
||||
STATIC_ASSERT((!is_less_equal_comparable<Y>::value));
|
||||
|
||||
// is_greater_than_comparable
|
||||
DEFINE_BINARY_PREDICATE_TRAIT(is_greater_than_comparable,>);
|
||||
bool operator>(X, X);
|
||||
convertible_to_bool operator>(X, Y);
|
||||
not_convertible_to_bool operator>(Y, X);
|
||||
|
||||
STATIC_ASSERT((is_greater_than_comparable<int>::value));
|
||||
STATIC_ASSERT((is_greater_than_comparable<int, long>::value));
|
||||
STATIC_ASSERT((is_greater_than_comparable<int*>::value));
|
||||
STATIC_ASSERT((is_greater_than_comparable<X>::value));
|
||||
STATIC_ASSERT((is_greater_than_comparable<X, Y>::value));
|
||||
STATIC_ASSERT((!is_greater_than_comparable<Y, X>::value));
|
||||
STATIC_ASSERT((!is_greater_than_comparable<Y>::value));
|
||||
|
||||
// is_greater_equal_comparable
|
||||
DEFINE_BINARY_PREDICATE_TRAIT(is_greater_equal_comparable,>=);
|
||||
bool operator>=(X, X);
|
||||
convertible_to_bool operator>=(X, Y);
|
||||
not_convertible_to_bool operator>=(Y, X);
|
||||
|
||||
STATIC_ASSERT((is_greater_equal_comparable<int>::value));
|
||||
STATIC_ASSERT((is_greater_equal_comparable<int, long>::value));
|
||||
STATIC_ASSERT((is_greater_equal_comparable<int*>::value));
|
||||
STATIC_ASSERT((is_greater_equal_comparable<X>::value));
|
||||
STATIC_ASSERT((is_greater_equal_comparable<X, Y>::value));
|
||||
STATIC_ASSERT((!is_greater_equal_comparable<Y, X>::value));
|
||||
STATIC_ASSERT((!is_greater_equal_comparable<Y>::value));
|
||||
|
||||
// is_equality_comparable
|
||||
struct Z : X { };
|
||||
DEFINE_BINARY_PREDICATE_TRAIT(is_equality_comparable,==);
|
||||
bool operator==(X, X);
|
||||
convertible_to_bool operator==(X, Y);
|
||||
not_convertible_to_bool operator==(Y, X);
|
||||
|
||||
STATIC_ASSERT((is_equality_comparable<int>::value));
|
||||
STATIC_ASSERT((is_equality_comparable<int, long>::value));
|
||||
STATIC_ASSERT((is_equality_comparable<int*>::value));
|
||||
STATIC_ASSERT((is_equality_comparable<X>::value));
|
||||
STATIC_ASSERT((is_equality_comparable<X, Y>::value));
|
||||
STATIC_ASSERT((!is_equality_comparable<Y, X>::value));
|
||||
STATIC_ASSERT((!is_equality_comparable<Y>::value));
|
||||
STATIC_ASSERT((is_equality_comparable<int X::*>::value));
|
||||
STATIC_ASSERT((!is_equality_comparable<int X::*, int Y::*>::value));
|
||||
STATIC_ASSERT((is_equality_comparable<int*, float*>::value));
|
||||
STATIC_ASSERT((is_equality_comparable<X*, Z*>::value));
|
||||
STATIC_ASSERT((!is_equality_comparable<X*, Y*>::value));
|
||||
|
||||
// is_not_equal_comparable
|
||||
DEFINE_BINARY_PREDICATE_TRAIT(is_not_equal_comparable,!=);
|
||||
bool operator!=(X, X);
|
||||
convertible_to_bool operator!=(X, Y);
|
||||
not_convertible_to_bool operator!=(Y, X);
|
||||
|
||||
STATIC_ASSERT((is_not_equal_comparable<int>::value));
|
||||
STATIC_ASSERT((is_not_equal_comparable<int, long>::value));
|
||||
STATIC_ASSERT((is_not_equal_comparable<int*>::value));
|
||||
STATIC_ASSERT((is_not_equal_comparable<X>::value));
|
||||
STATIC_ASSERT((is_not_equal_comparable<X, Y>::value));
|
||||
STATIC_ASSERT((!is_not_equal_comparable<Y, X>::value));
|
||||
STATIC_ASSERT((!is_not_equal_comparable<Y>::value));
|
||||
STATIC_ASSERT((is_not_equal_comparable<int X::*>::value));
|
||||
STATIC_ASSERT((!is_not_equal_comparable<int X::*, int Y::*>::value));
|
||||
STATIC_ASSERT((is_not_equal_comparable<int*, float*>::value));
|
||||
STATIC_ASSERT((is_not_equal_comparable<X*, Z*>::value));
|
||||
STATIC_ASSERT((!is_not_equal_comparable<X*, Y*>::value));
|
||||
|
||||
// has_logical_and
|
||||
DEFINE_BINARY_PREDICATE_TRAIT(has_logical_and,&&);
|
||||
bool operator&&(X, X);
|
||||
convertible_to_bool operator&&(X, Y);
|
||||
not_convertible_to_bool operator&&(Y, X);
|
||||
|
||||
STATIC_ASSERT((has_logical_and<int>::value));
|
||||
STATIC_ASSERT((has_logical_and<int, long>::value));
|
||||
STATIC_ASSERT((has_logical_and<int*>::value));
|
||||
STATIC_ASSERT((has_logical_and<X>::value));
|
||||
STATIC_ASSERT((has_logical_and<X, Y>::value));
|
||||
STATIC_ASSERT((!has_logical_and<Y, X>::value));
|
||||
STATIC_ASSERT((!has_logical_and<Y>::value));
|
||||
STATIC_ASSERT((has_logical_and<int X::*>::value));
|
||||
STATIC_ASSERT((has_logical_and<int X::*, int Y::*>::value));
|
||||
STATIC_ASSERT((has_logical_and<int*, float*>::value));
|
||||
STATIC_ASSERT((has_logical_and<X*, Z*>::value));
|
||||
STATIC_ASSERT((has_logical_and<X*, Y*>::value));
|
||||
|
||||
// has_logical_or
|
||||
DEFINE_BINARY_PREDICATE_TRAIT(has_logical_or,||);
|
||||
bool operator||(X, X);
|
||||
convertible_to_bool operator||(X, Y);
|
||||
not_convertible_to_bool operator||(Y, X);
|
||||
|
||||
STATIC_ASSERT((has_logical_or<int>::value));
|
||||
STATIC_ASSERT((has_logical_or<int, long>::value));
|
||||
STATIC_ASSERT((has_logical_or<int*>::value));
|
||||
STATIC_ASSERT((has_logical_or<X>::value));
|
||||
STATIC_ASSERT((has_logical_or<X, Y>::value));
|
||||
STATIC_ASSERT((!has_logical_or<Y, X>::value));
|
||||
STATIC_ASSERT((!has_logical_or<Y>::value));
|
||||
STATIC_ASSERT((has_logical_or<int X::*>::value));
|
||||
STATIC_ASSERT((has_logical_or<int X::*, int Y::*>::value));
|
||||
STATIC_ASSERT((has_logical_or<int*, float*>::value));
|
||||
STATIC_ASSERT((has_logical_or<X*, Z*>::value));
|
||||
STATIC_ASSERT((has_logical_or<X*, Y*>::value));
|
|
@ -0,0 +1,207 @@
|
|||
// DR 339
|
||||
//
|
||||
// Test of the use of various assignment operators with SFINAE
|
||||
|
||||
// Boilerplate helpers
|
||||
typedef char yes_type;
|
||||
struct no_type { char data[2]; };
|
||||
|
||||
template<typename T> T create_a();
|
||||
template<typename T> struct type { };
|
||||
|
||||
template<bool, typename T = void> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> { };
|
||||
|
||||
#define JOIN( X, Y ) DO_JOIN( X, Y )
|
||||
#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
||||
#define DO_JOIN2( X, Y ) X##Y
|
||||
|
||||
#define DEFINE_INFIX_BINARY_TRAIT(Name,Op) \
|
||||
template<typename T, typename U> \
|
||||
typename enable_if<(sizeof(create_a<T>() Op create_a<U>(), 1) > 0), \
|
||||
yes_type>::type \
|
||||
JOIN(check_,Name)(type<T>, type<U>); \
|
||||
\
|
||||
no_type JOIN(check_,Name)(...); \
|
||||
\
|
||||
template<typename T, typename U = T> \
|
||||
struct Name \
|
||||
{ \
|
||||
static const bool value = \
|
||||
(sizeof(JOIN(check_,Name)(type<T&>(), type<U>())) == sizeof(yes_type)); \
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
||||
#else
|
||||
# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
||||
#endif
|
||||
|
||||
struct Y {
|
||||
Y& operator=(Y&);
|
||||
};
|
||||
|
||||
struct X {
|
||||
X& operator=(Y);
|
||||
X& operator+=(X);
|
||||
X& operator-=(X);
|
||||
X& operator*=(X);
|
||||
X& operator/=(X);
|
||||
X& operator%=(X);
|
||||
X& operator^=(X);
|
||||
X& operator&=(X);
|
||||
X& operator|=(X);
|
||||
X& operator<<=(X);
|
||||
X& operator>>=(X);
|
||||
};
|
||||
struct Z { };
|
||||
|
||||
// is_assignable
|
||||
DEFINE_INFIX_BINARY_TRAIT(is_assignable, =);
|
||||
STATIC_ASSERT((is_assignable<int>::value));
|
||||
STATIC_ASSERT((is_assignable<int, long>::value));
|
||||
STATIC_ASSERT((is_assignable<X>::value));
|
||||
STATIC_ASSERT((!is_assignable<int*, int>::value));
|
||||
STATIC_ASSERT((is_assignable<int*>::value));
|
||||
STATIC_ASSERT((is_assignable<X, Y>::value));
|
||||
STATIC_ASSERT((!is_assignable<X, Z>::value));
|
||||
STATIC_ASSERT((!is_assignable<Y>::value));
|
||||
STATIC_ASSERT((!is_assignable<const int, long>::value));
|
||||
|
||||
// has_plus_assign
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_plus_assign, +=);
|
||||
X& operator+=(X&, Y);
|
||||
STATIC_ASSERT((has_plus_assign<int>::value));
|
||||
STATIC_ASSERT((has_plus_assign<int, long>::value));
|
||||
STATIC_ASSERT((has_plus_assign<X>::value));
|
||||
STATIC_ASSERT((has_plus_assign<int*, int>::value));
|
||||
STATIC_ASSERT((!has_plus_assign<int*>::value));
|
||||
STATIC_ASSERT((has_plus_assign<X, Y>::value));
|
||||
STATIC_ASSERT((!has_plus_assign<X, Z>::value));
|
||||
STATIC_ASSERT((!has_plus_assign<Y>::value));
|
||||
STATIC_ASSERT((!has_plus_assign<const int, long>::value));
|
||||
|
||||
// has_minus_assign
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_minus_assign, -=);
|
||||
X& operator-=(X&, Y);
|
||||
STATIC_ASSERT((has_minus_assign<int>::value));
|
||||
STATIC_ASSERT((has_minus_assign<int, long>::value));
|
||||
STATIC_ASSERT((has_minus_assign<X>::value));
|
||||
STATIC_ASSERT((has_minus_assign<int*, int>::value));
|
||||
STATIC_ASSERT((!has_minus_assign<int*>::value));
|
||||
STATIC_ASSERT((has_minus_assign<X, Y>::value));
|
||||
STATIC_ASSERT((!has_minus_assign<X, Z>::value));
|
||||
STATIC_ASSERT((!has_minus_assign<Y>::value));
|
||||
STATIC_ASSERT((!has_minus_assign<int X::*>::value));
|
||||
STATIC_ASSERT((!has_minus_assign<const int, long>::value));
|
||||
|
||||
// has_multiply_assign
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_multiply_assign, *=);
|
||||
X& operator*=(X&, Y);
|
||||
STATIC_ASSERT((has_multiply_assign<int>::value));
|
||||
STATIC_ASSERT((has_multiply_assign<int, long>::value));
|
||||
STATIC_ASSERT((has_multiply_assign<X>::value));
|
||||
STATIC_ASSERT((!has_multiply_assign<int*, int>::value));
|
||||
STATIC_ASSERT((!has_multiply_assign<int*>::value));
|
||||
STATIC_ASSERT((has_multiply_assign<X, Y>::value));
|
||||
STATIC_ASSERT((!has_multiply_assign<X, Z>::value));
|
||||
STATIC_ASSERT((!has_multiply_assign<Y>::value));
|
||||
STATIC_ASSERT((!has_multiply_assign<int X::*>::value));
|
||||
STATIC_ASSERT((!has_multiply_assign<const int, long>::value));
|
||||
|
||||
// has_divide_assign
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_divide_assign, /=);
|
||||
X& operator/=(X&, Y);
|
||||
STATIC_ASSERT((has_divide_assign<int>::value));
|
||||
STATIC_ASSERT((has_divide_assign<int, long>::value));
|
||||
STATIC_ASSERT((has_divide_assign<X>::value));
|
||||
STATIC_ASSERT((!has_divide_assign<int*, int>::value));
|
||||
STATIC_ASSERT((!has_divide_assign<int*>::value));
|
||||
STATIC_ASSERT((has_divide_assign<X, Y>::value));
|
||||
STATIC_ASSERT((!has_divide_assign<X, Z>::value));
|
||||
STATIC_ASSERT((!has_divide_assign<Y>::value));
|
||||
STATIC_ASSERT((!has_divide_assign<int X::*>::value));
|
||||
|
||||
// has_remainder_assign
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_remainder_assign, %=);
|
||||
X& operator%=(X&, Y);
|
||||
STATIC_ASSERT((has_remainder_assign<int>::value));
|
||||
STATIC_ASSERT((has_remainder_assign<int, long>::value));
|
||||
STATIC_ASSERT((!has_remainder_assign<float>::value));
|
||||
STATIC_ASSERT((has_remainder_assign<X>::value));
|
||||
STATIC_ASSERT((!has_remainder_assign<int*, int>::value));
|
||||
STATIC_ASSERT((!has_remainder_assign<int*>::value));
|
||||
STATIC_ASSERT((has_remainder_assign<X, Y>::value));
|
||||
STATIC_ASSERT((!has_remainder_assign<X, Z>::value));
|
||||
STATIC_ASSERT((!has_remainder_assign<Y>::value));
|
||||
STATIC_ASSERT((!has_remainder_assign<int X::*>::value));
|
||||
|
||||
// has_xor_assign
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_xor_assign, ^=);
|
||||
X& operator^=(X&, Y);
|
||||
STATIC_ASSERT((has_xor_assign<int>::value));
|
||||
STATIC_ASSERT((has_xor_assign<int, long>::value));
|
||||
STATIC_ASSERT((!has_xor_assign<float>::value));
|
||||
STATIC_ASSERT((has_xor_assign<X>::value));
|
||||
STATIC_ASSERT((!has_xor_assign<int*, int>::value));
|
||||
STATIC_ASSERT((!has_xor_assign<int*>::value));
|
||||
STATIC_ASSERT((has_xor_assign<X, Y>::value));
|
||||
STATIC_ASSERT((!has_xor_assign<X, Z>::value));
|
||||
STATIC_ASSERT((!has_xor_assign<Y>::value));
|
||||
STATIC_ASSERT((!has_xor_assign<int X::*>::value));
|
||||
|
||||
// has_bitand_assign
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_bitand_assign, &=);
|
||||
X& operator&=(X&, Y);
|
||||
STATIC_ASSERT((has_bitand_assign<int>::value));
|
||||
STATIC_ASSERT((has_bitand_assign<int, long>::value));
|
||||
STATIC_ASSERT((!has_bitand_assign<float>::value));
|
||||
STATIC_ASSERT((has_bitand_assign<X>::value));
|
||||
STATIC_ASSERT((!has_bitand_assign<int*, int>::value));
|
||||
STATIC_ASSERT((!has_bitand_assign<int*>::value));
|
||||
STATIC_ASSERT((has_bitand_assign<X, Y>::value));
|
||||
STATIC_ASSERT((!has_bitand_assign<X, Z>::value));
|
||||
STATIC_ASSERT((!has_bitand_assign<Y>::value));
|
||||
STATIC_ASSERT((!has_bitand_assign<int X::*>::value));
|
||||
|
||||
// has_bitor_assign
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_bitor_assign, |=);
|
||||
X& operator|=(X&, Y);
|
||||
STATIC_ASSERT((has_bitor_assign<int>::value));
|
||||
STATIC_ASSERT((has_bitor_assign<int, long>::value));
|
||||
STATIC_ASSERT((!has_bitor_assign<float>::value));
|
||||
STATIC_ASSERT((has_bitor_assign<X>::value));
|
||||
STATIC_ASSERT((!has_bitor_assign<int*, int>::value));
|
||||
STATIC_ASSERT((!has_bitor_assign<int*>::value));
|
||||
STATIC_ASSERT((has_bitor_assign<X, Y>::value));
|
||||
STATIC_ASSERT((!has_bitor_assign<X, Z>::value));
|
||||
STATIC_ASSERT((!has_bitor_assign<Y>::value));
|
||||
STATIC_ASSERT((!has_bitor_assign<int X::*>::value));
|
||||
|
||||
// has_left_shift_assign
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_left_shift_assign, <<=);
|
||||
X& operator<<=(X&, Y);
|
||||
STATIC_ASSERT((has_left_shift_assign<int>::value));
|
||||
STATIC_ASSERT((has_left_shift_assign<int, long>::value));
|
||||
STATIC_ASSERT((!has_left_shift_assign<float>::value));
|
||||
STATIC_ASSERT((has_left_shift_assign<X>::value));
|
||||
STATIC_ASSERT((!has_left_shift_assign<int*, int>::value));
|
||||
STATIC_ASSERT((!has_left_shift_assign<int*>::value));
|
||||
STATIC_ASSERT((has_left_shift_assign<X, Y>::value));
|
||||
STATIC_ASSERT((!has_left_shift_assign<X, Z>::value));
|
||||
STATIC_ASSERT((!has_left_shift_assign<Y>::value));
|
||||
STATIC_ASSERT((!has_left_shift_assign<int X::*>::value));
|
||||
|
||||
// has_right_shift_assign
|
||||
DEFINE_INFIX_BINARY_TRAIT(has_right_shift_assign, >>=);
|
||||
X& operator>>=(X&, Y);
|
||||
STATIC_ASSERT((has_right_shift_assign<int>::value));
|
||||
STATIC_ASSERT((has_right_shift_assign<int, long>::value));
|
||||
STATIC_ASSERT((!has_right_shift_assign<float>::value));
|
||||
STATIC_ASSERT((has_right_shift_assign<X>::value));
|
||||
STATIC_ASSERT((!has_right_shift_assign<int*, int>::value));
|
||||
STATIC_ASSERT((!has_right_shift_assign<int*>::value));
|
||||
STATIC_ASSERT((has_right_shift_assign<X, Y>::value));
|
||||
STATIC_ASSERT((!has_right_shift_assign<X, Z>::value));
|
||||
STATIC_ASSERT((!has_right_shift_assign<Y>::value));
|
||||
STATIC_ASSERT((!has_right_shift_assign<int X::*>::value));
|
Loading…
Reference in New Issue