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:
Douglas Gregor 2008-03-25 13:53:58 +00:00 committed by Doug Gregor
parent de6adfa2f4
commit 5ade1ed2c0
32 changed files with 2876 additions and 808 deletions

View File

@ -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.

View File

@ -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))

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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");
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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);
}

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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.

View File

@ -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" }

View File

@ -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));

View File

@ -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));

View File

@ -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));

View File

@ -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));

View File

@ -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];

View File

@ -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];

View File

@ -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));

View File

@ -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));

View File

@ -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));

View File

@ -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));

View File

@ -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));