diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2012-06-06 23:01:45 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2012-06-06 23:01:45 +0000 |
commit | 4b978f96910158a9a2fab2ff6b6c4113ff97204d (patch) | |
tree | f33c10cac813a9df3728ad7933a633ef664460ab /gcc | |
parent | 6f07a821c41399a6b87094816a7d0f7beefa5faa (diff) | |
download | gcc-4b978f96910158a9a2fab2ff6b6c4113ff97204d.zip gcc-4b978f96910158a9a2fab2ff6b6c4113ff97204d.tar.gz gcc-4b978f96910158a9a2fab2ff6b6c4113ff97204d.tar.bz2 |
re PR c++/53567 ("ICE: Error reporting routines re-entered" on missing enum entry)
/cp
2012-06-06 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/53567
* typeck.c (cp_perform_integral_promotions): New, like
perform_integral_promotions but also takes a tsubst_flags_t parameter.
(pointer_diff): Add tsubst_flags_t parameter.
(decay_conversion, cp_default_conversion, cp_build_array_ref,
cp_build_binary_op, cp_build_unary_op, build_static_cast_1,
build_reinterpret_cast_1, cp_build_modify_expr,
convert_for_assignment): Adjust.
* optimize.c (build_delete_destructor_body): Adjust.
* init.c (expand_virtual_init, expand_default_init, build_new_1,
build_new, build_vec_delete_1, build_vec_init, build_delete): Adjust.
(construct_virtual_base): Adjust LOOKUP_COMPLAIN -> 0.
* class.c (build_base_path): Adjust.
* decl.c (compute_array_index_type, finish_destructor_body): Likewise.
* method.c (synthesized_method_walk): Adjust flag and complain.
* rtti.c (ifnonnull): Add tsubst_flags_t parameter.
(build_typeid, build_dynamic_cast_1): Adjust.
* except.c (initialize_handler_parm): Likewise.
* typeck2.c (process_init_constructor_record): Likewise.
* pt.c (tsubst_friend_class): Don't change flags.
* semantics.c (finish_goto_stmt, handle_omp_for_class_iterator,
finish_static_assert): Likewise.
* parser.c (cp_parser_lookup_name): Just pass 0 as flags to
lookup_name_real.
* call.c (build_op_delete_call): Add tsubst_flags_t parameter.
(convert_like_real, convert_arg_to_ellipsis, convert_for_arg_passing):
Adjust.
(standard_conversion): Adjust LOOKUP_COMPLAIN -> 0.
(implicit_conversion): Mask out tf_error with a FIXME.
(build_user_type_conversion_1, build_new_op_1, build_over_call): Use
complain & tf_error instead of flags & LOOKUP_COMPLAIN.
* cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
build_up_reference, convert_to_reference, cp_convert,
cp_convert_and_check, ocp_convert, convert_force): Add tsubst_flags_t
parameter.
(convert_to_reference, ocp_convert): Use complain & tf_error instead
of flags & LOOKUP_COMPLAIN.
(convert_force): Adjust LOOKUP_COMPLAIN -> 0.
* name-lookup.c (identifier_type_value_1, lookup_qualified_name,
lookup_name_real, lookup_function_nonclass, lookup_name,
lookup_name_prefer_type): Adjust LOOKUP_COMPLAIN -> 0.
* cp-tree.h: Adjust prototypes; remove LOOKUP_COMPLAIN.
/testsuite
2012-06-06 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/53567
* g++.dg/cpp0x/alias-decl-19.C: New.
From-SVN: r188283
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 45 | ||||
-rw-r--r-- | gcc/cp/call.c | 62 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 39 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 197 | ||||
-rw-r--r-- | gcc/cp/decl.c | 18 | ||||
-rw-r--r-- | gcc/cp/except.c | 6 | ||||
-rw-r--r-- | gcc/cp/init.c | 36 | ||||
-rw-r--r-- | gcc/cp/method.c | 13 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 13 | ||||
-rw-r--r-- | gcc/cp/optimize.c | 3 | ||||
-rw-r--r-- | gcc/cp/parser.c | 8 | ||||
-rw-r--r-- | gcc/cp/pt.c | 3 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 22 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 10 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 116 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C | 31 |
19 files changed, 389 insertions, 242 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 49e1dfe..e8a11f3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,48 @@ +2012-06-06 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/53567 + * typeck.c (cp_perform_integral_promotions): New, like + perform_integral_promotions but also takes a tsubst_flags_t parameter. + (pointer_diff): Add tsubst_flags_t parameter. + (decay_conversion, cp_default_conversion, cp_build_array_ref, + cp_build_binary_op, cp_build_unary_op, build_static_cast_1, + build_reinterpret_cast_1, cp_build_modify_expr, + convert_for_assignment): Adjust. + * optimize.c (build_delete_destructor_body): Adjust. + * init.c (expand_virtual_init, expand_default_init, build_new_1, + build_new, build_vec_delete_1, build_vec_init, build_delete): Adjust. + (construct_virtual_base): Adjust LOOKUP_COMPLAIN -> 0. + * class.c (build_base_path): Adjust. + * decl.c (compute_array_index_type, finish_destructor_body): Likewise. + * method.c (synthesized_method_walk): Adjust flag and complain. + * rtti.c (ifnonnull): Add tsubst_flags_t parameter. + (build_typeid, build_dynamic_cast_1): Adjust. + * except.c (initialize_handler_parm): Likewise. + * typeck2.c (process_init_constructor_record): Likewise. + * pt.c (tsubst_friend_class): Don't change flags. + * semantics.c (finish_goto_stmt, handle_omp_for_class_iterator, + finish_static_assert): Likewise. + * parser.c (cp_parser_lookup_name): Just pass 0 as flags to + lookup_name_real. + * call.c (build_op_delete_call): Add tsubst_flags_t parameter. + (convert_like_real, convert_arg_to_ellipsis, convert_for_arg_passing): + Adjust. + (standard_conversion): Adjust LOOKUP_COMPLAIN -> 0. + (implicit_conversion): Mask out tf_error with a FIXME. + (build_user_type_conversion_1, build_new_op_1, build_over_call): Use + complain & tf_error instead of flags & LOOKUP_COMPLAIN. + * cvt.c (cp_convert_to_pointer, convert_to_pointer_force, + build_up_reference, convert_to_reference, cp_convert, + cp_convert_and_check, ocp_convert, convert_force): Add tsubst_flags_t + parameter. + (convert_to_reference, ocp_convert): Use complain & tf_error instead + of flags & LOOKUP_COMPLAIN. + (convert_force): Adjust LOOKUP_COMPLAIN -> 0. + * name-lookup.c (identifier_type_value_1, lookup_qualified_name, + lookup_name_real, lookup_function_nonclass, lookup_name, + lookup_name_prefer_type): Adjust LOOKUP_COMPLAIN -> 0. + * cp-tree.h: Adjust prototypes; remove LOOKUP_COMPLAIN. + 2012-06-06 Steven Bosscher <steven@gcc.gnu.org> * decl.c: Do not include output.h. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index ad31f6a..09965b3 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1695,6 +1695,13 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, |LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE |LOOKUP_NO_NARROWING|LOOKUP_PROTECT); + /* FIXME: actually we don't want warnings either, but we can't just + have 'complain &= ~(tf_warning|tf_error)' because it would cause + the regression of, eg, g++.old-deja/g++.benjamin/16077.C. + We really ought not to issue that warning until we've committed + to that conversion. */ + complain &= ~tf_error; + if (TREE_CODE (to) == REFERENCE_TYPE) conv = reference_binding (to, from, expr, c_cast_p, flags, complain); else @@ -3607,8 +3614,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags, cand = tourney (candidates, complain); if (cand == 0) { - if ((flags & LOOKUP_COMPLAIN) - && (complain & tf_error)) + if (complain & tf_error) { error ("conversion from %qT to %qT is ambiguous", fromtype, totype); @@ -5098,7 +5104,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1, distinguish between prefix and postfix ++ and operator++() was used for both, so we allow this with -fpermissive. */ - if (flags & LOOKUP_COMPLAIN) + else { const char *msg = (flag_permissive) ? G_("no %<%D(int)%> declared for postfix %qs," @@ -5127,7 +5133,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1, break; default: - if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error)) + if (complain & tf_error) { /* If one of the arguments of the operator represents an invalid use of member function pointer, try to report @@ -5153,7 +5159,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1, cand = tourney (candidates, complain); if (cand == 0) { - if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error)) + if (complain & tf_error) { op_error (loc, code, code2, arg1, arg2, arg3, TRUE); print_z_candidates (loc, candidates); @@ -5379,7 +5385,7 @@ non_placement_deallocation_fn_p (tree t) tree build_op_delete_call (enum tree_code code, tree addr, tree size, bool global_p, tree placement, - tree alloc_fn) + tree alloc_fn, tsubst_flags_t complain) { tree fn = NULL_TREE; tree fns, fnname, type, t; @@ -5413,7 +5419,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, fns = lookup_name_nonclass (fnname); /* Strip const and volatile from addr. */ - addr = cp_convert (ptr_type_node, addr); + addr = cp_convert (ptr_type_node, addr, complain); if (placement) { @@ -5452,8 +5458,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, && FUNCTION_ARG_CHAIN (elt) == void_list_node) goto ok; } - permerror (0, "non-placement deallocation function %q+D", fn); - permerror (input_location, "selected for placement delete"); + if (complain & tf_error) + { + permerror (0, "non-placement deallocation function %q+D", fn); + permerror (input_location, "selected for placement delete"); + } + else + return error_mark_node; ok:; } } @@ -5518,7 +5529,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, VEC_quick_push (tree, args, addr); if (FUNCTION_ARG_CHAIN (fn) != void_list_node) VEC_quick_push (tree, args, size); - ret = cp_build_function_call_vec (fn, &args, tf_warning_or_error); + ret = cp_build_function_call_vec (fn, &args, complain); VEC_free (tree, gc, args); return ret; } @@ -5531,14 +5542,16 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, be freed. */ if (alloc_fn) { - if (!placement) + if ((complain & tf_warning) + && !placement) warning (0, "no corresponding deallocation function for %qD", alloc_fn); return NULL_TREE; } - error ("no suitable %<operator %s%> for %qT", - operator_name_info[(int)code].name, type); + if (complain & tf_error) + error ("no suitable %<operator %s%> for %qT", + operator_name_info[(int)code].name, type); return error_mark_node; } @@ -5685,9 +5698,10 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, complain); if (convs->kind == ck_ref_bind) return convert_to_reference (totype, expr, CONV_IMPLICIT, - LOOKUP_NORMAL, NULL_TREE); + LOOKUP_NORMAL, NULL_TREE, + complain); else - return cp_convert (totype, expr); + return cp_convert (totype, expr, complain); } else if (t->kind == ck_user || !t->bad_p) { @@ -5712,7 +5726,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, permerror (DECL_SOURCE_LOCATION (fn), " initializing argument %P of %qD", argnum, fn); - return cp_convert (totype, expr); + return cp_convert (totype, expr, complain); } if (issue_conversion_warnings && (complain & tf_warning)) @@ -5851,7 +5865,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, /* Take the address explicitly rather than via decay_conversion to avoid the error about taking the address of a temporary. */ array = cp_build_addr_expr (array, complain); - array = cp_convert (build_pointer_type (elttype), array); + array = cp_convert (build_pointer_type (elttype), array, complain); /* Build up the initializer_list object. */ totype = complete_type (totype); @@ -6017,7 +6031,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, reference. This will adjust the pointer if a derived to base conversion is being performed. */ expr = cp_convert (build_pointer_type (TREE_TYPE (ref_type)), - expr); + expr, complain); /* Convert the pointer to the desired reference type. */ return build_nop (ref_type, expr); } @@ -6099,9 +6113,9 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain) if (complain & tf_warning) warning_at (loc, OPT_Wabi, "scoped enum %qT will not promote to an " "integral type in a future version of GCC", arg_type); - arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg); + arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg, complain); } - arg = perform_integral_promotions (arg); + arg = cp_perform_integral_promotions (arg, complain); } arg = require_complete_type (arg); @@ -6336,7 +6350,7 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain) && COMPLETE_TYPE_P (type) && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) - val = perform_integral_promotions (val); + val = cp_perform_integral_promotions (val, complain); if ((complain & tf_warning) && warn_suggest_attribute_format) { @@ -6487,7 +6501,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (flags & LOOKUP_SPECULATIVE) { if (!speculative_access_check (cand->access_path, access_fn, fn, - !!(flags & LOOKUP_COMPLAIN))) + complain & tf_error)) return error_mark_node; } else @@ -6500,13 +6514,13 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) { if (DECL_DELETED_FN (fn)) { - if (flags & LOOKUP_COMPLAIN) + if (complain & tf_error) mark_used (fn); return error_mark_node; } if (cand->viable == 1) return fn; - else if (!(flags & LOOKUP_COMPLAIN)) + else if (!(complain & tf_error)) /* Reject bad conversions now. */ return error_mark_node; /* else continue to get conversion error. */ diff --git a/gcc/cp/class.c b/gcc/cp/class.c index c30054d..e85aac9 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -366,7 +366,7 @@ build_base_path (enum tree_code code, /* Now that we've saved expr, build the real null test. */ if (null_test) { - tree zero = cp_convert (TREE_TYPE (expr), nullptr_node); + tree zero = cp_convert (TREE_TYPE (expr), nullptr_node, complain); null_test = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, expr, zero); } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7c901be..22012e2 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4371,16 +4371,13 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; behaviors relevant to them. */ /* Check for access violations. */ #define LOOKUP_PROTECT (1 << 0) -/* Complain if no suitable member function matching the arguments is - found. */ -#define LOOKUP_COMPLAIN (1 << 1) -#define LOOKUP_NORMAL (LOOKUP_PROTECT | LOOKUP_COMPLAIN) +#define LOOKUP_NORMAL (LOOKUP_PROTECT) /* Even if the function found by lookup is a virtual function, it should be called directly. */ -#define LOOKUP_NONVIRTUAL (1 << 2) +#define LOOKUP_NONVIRTUAL (1 << 1) /* Non-converting (i.e., "explicit") constructors are not tried. This flag indicates that we are not performing direct-initialization. */ -#define LOOKUP_ONLYCONVERTING (1 << 3) +#define LOOKUP_ONLYCONVERTING (1 << 2) #define LOOKUP_IMPLICIT (LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING) /* If a temporary is created, it should be created so that it lives as long as the current variable bindings; otherwise it only lives @@ -4388,20 +4385,20 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; direct-initialization in cases where other parts of the compiler have already generated a temporary, such as reference initialization and the catch parameter. */ -#define DIRECT_BIND (1 << 4) +#define DIRECT_BIND (1 << 3) /* We're performing a user-defined conversion, so more user-defined conversions are not permitted (only built-in conversions). */ -#define LOOKUP_NO_CONVERSION (1 << 5) +#define LOOKUP_NO_CONVERSION (1 << 4) /* The user has explicitly called a destructor. (Therefore, we do not need to check that the object is non-NULL before calling the destructor.) */ -#define LOOKUP_DESTRUCTOR (1 << 6) +#define LOOKUP_DESTRUCTOR (1 << 5) /* Do not permit references to bind to temporaries. */ -#define LOOKUP_NO_TEMP_BIND (1 << 7) +#define LOOKUP_NO_TEMP_BIND (1 << 6) /* Do not accept objects, and possibly namespaces. */ -#define LOOKUP_PREFER_TYPES (1 << 8) +#define LOOKUP_PREFER_TYPES (1 << 7) /* Do not accept objects, and possibly types. */ -#define LOOKUP_PREFER_NAMESPACES (1 << 9) +#define LOOKUP_PREFER_NAMESPACES (1 << 8) /* Accept types or namespaces. */ #define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES) /* Return friend declarations and un-declared builtin functions. @@ -4894,7 +4891,9 @@ extern tree build_new_op (location_t, enum tree_code, tsubst_flags_t); extern tree build_op_call (tree, VEC(tree,gc) **, tsubst_flags_t); -extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree, tree); +extern tree build_op_delete_call (enum tree_code, tree, tree, + bool, tree, tree, + tsubst_flags_t); extern bool can_convert (tree, tree, tsubst_flags_t); extern bool can_convert_arg (tree, tree, tree, int, tsubst_flags_t); @@ -5001,16 +5000,19 @@ extern void adjust_clone_args (tree); extern void deduce_noexcept_on_destructor (tree); /* in cvt.c */ -extern tree convert_to_reference (tree, tree, int, int, tree); +extern tree convert_to_reference (tree, tree, int, int, tree, + tsubst_flags_t); extern tree convert_from_reference (tree); extern tree force_rvalue (tree, tsubst_flags_t); -extern tree ocp_convert (tree, tree, int, int); -extern tree cp_convert (tree, tree); -extern tree cp_convert_and_check (tree, tree); +extern tree ocp_convert (tree, tree, int, int, + tsubst_flags_t); +extern tree cp_convert (tree, tree, tsubst_flags_t); +extern tree cp_convert_and_check (tree, tree, tsubst_flags_t); extern tree cp_fold_convert (tree, tree); extern tree convert_to_void (tree, impl_conv_void, tsubst_flags_t); -extern tree convert_force (tree, tree, int); +extern tree convert_force (tree, tree, int, + tsubst_flags_t); extern tree build_expr_type_conversion (int, tree, bool); extern tree type_promotes_to (tree); extern tree perform_qualification_conversions (tree, tree); @@ -5901,6 +5903,7 @@ extern void check_template_keyword (tree); extern bool check_raw_literal_operator (const_tree decl); extern bool check_literal_operator_args (const_tree, bool *, bool *); extern void maybe_warn_about_useless_cast (tree, tree, tsubst_flags_t); +extern tree cp_perform_integral_promotions (tree, tsubst_flags_t); /* in typeck2.c */ extern void require_complete_eh_spec_types (tree, tree); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index ebd7505..998d4eb 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -38,10 +38,10 @@ along with GCC; see the file COPYING3. If not see #include "decl.h" #include "target.h" -static tree cp_convert_to_pointer (tree, tree); -static tree convert_to_pointer_force (tree, tree); +static tree cp_convert_to_pointer (tree, tree, tsubst_flags_t); +static tree convert_to_pointer_force (tree, tree, tsubst_flags_t); static tree build_type_conversion (tree, tree); -static tree build_up_reference (tree, tree, int, tree); +static tree build_up_reference (tree, tree, int, tree, tsubst_flags_t); static void warn_ref_binding (location_t, tree, tree, tree); /* Change of width--truncation and extension of integers or reals-- @@ -74,7 +74,7 @@ static void warn_ref_binding (location_t, tree, tree, tree); else try C-style pointer conversion. */ static tree -cp_convert_to_pointer (tree type, tree expr) +cp_convert_to_pointer (tree type, tree expr, tsubst_flags_t complain) { tree intype = TREE_TYPE (expr); enum tree_code form; @@ -89,15 +89,17 @@ cp_convert_to_pointer (tree type, tree expr) intype = complete_type (intype); if (!COMPLETE_TYPE_P (intype)) { - error_at (loc, "can%'t convert from incomplete type %qT to %qT", - intype, type); + if (complain & tf_error) + error_at (loc, "can%'t convert from incomplete type %qT to %qT", + intype, type); return error_mark_node; } rval = build_type_conversion (type, expr); if (rval) { - if (rval == error_mark_node) + if ((complain & tf_error) + && rval == error_mark_node) error_at (loc, "conversion of %qE from %qT to %qT is ambiguous", expr, intype, type); return rval; @@ -111,7 +113,7 @@ cp_convert_to_pointer (tree type, tree expr) { if (TYPE_PTRMEMFUNC_P (intype) || TREE_CODE (intype) == METHOD_TYPE) - return convert_member_func_to_ptr (type, expr, tf_warning_or_error); + return convert_member_func_to_ptr (type, expr, complain); if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE) return build_nop (type, expr); intype = TREE_TYPE (expr); @@ -159,8 +161,7 @@ cp_convert_to_pointer (tree type, tree expr) if (binfo || same_p) { if (binfo) - expr = build_base_path (code, expr, binfo, 0, - tf_warning_or_error); + expr = build_base_path (code, expr, binfo, 0, complain); /* Add any qualifier conversions. */ return build_nop (type, expr); } @@ -168,8 +169,9 @@ cp_convert_to_pointer (tree type, tree expr) if (TYPE_PTRMEMFUNC_P (type)) { - error_at (loc, "cannot convert %qE from type %qT to type %qT", - expr, intype, type); + if (complain & tf_error) + error_at (loc, "cannot convert %qE from type %qT to type %qT", + expr, intype, type); return error_mark_node; } @@ -178,20 +180,20 @@ cp_convert_to_pointer (tree type, tree expr) else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype)) || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))) return convert_ptrmem (type, expr, /*allow_inverse_p=*/false, - /*c_cast_p=*/false, tf_warning_or_error); + /*c_cast_p=*/false, complain); else if (TYPE_PTRMEMFUNC_P (intype)) { if (!warn_pmf2ptr) { if (TREE_CODE (expr) == PTRMEM_CST) - return cp_convert_to_pointer (type, - PTRMEM_CST_MEMBER (expr)); + return cp_convert_to_pointer (type, PTRMEM_CST_MEMBER (expr), + complain); else if (TREE_CODE (expr) == OFFSET_REF) { tree object = TREE_OPERAND (expr, 0); return get_member_function_from_ptrfunc (&object, TREE_OPERAND (expr, 1), - tf_warning_or_error); + complain); } } error_at (loc, "cannot convert %qE from type %qT to type %qT", @@ -201,14 +203,15 @@ cp_convert_to_pointer (tree type, tree expr) if (null_ptr_cst_p (expr)) { - if (c_inhibit_evaluation_warnings == 0 + if ((complain & tf_warning) + && c_inhibit_evaluation_warnings == 0 && !NULLPTR_TYPE_P (TREE_TYPE (expr))) warning_at (loc, OPT_Wzero_as_null_pointer_constant, "zero as null pointer constant"); if (TYPE_PTRMEMFUNC_P (type)) return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0, - /*c_cast_p=*/false, tf_warning_or_error); + /*c_cast_p=*/false, complain); if (TYPE_PTRDATAMEM_P (type)) { @@ -223,7 +226,8 @@ cp_convert_to_pointer (tree type, tree expr) } else if (TYPE_PTRMEM_P (type) && INTEGRAL_CODE_P (form)) { - error_at (loc, "invalid conversion from %qT to %qT", intype, type); + if (complain & tf_error) + error_at (loc, "invalid conversion from %qT to %qT", intype, type); return error_mark_node; } @@ -231,7 +235,8 @@ cp_convert_to_pointer (tree type, tree expr) { if (TYPE_PRECISION (intype) == POINTER_SIZE) return build1 (CONVERT_EXPR, type, expr); - expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr); + expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr, + complain); /* Modes may be different but sizes should be the same. There is supposed to be some integral type that is the same width as a pointer. */ @@ -242,10 +247,11 @@ cp_convert_to_pointer (tree type, tree expr) } if (type_unknown_p (expr)) - return instantiate_type (type, expr, tf_warning_or_error); + return instantiate_type (type, expr, complain); - error_at (loc, "cannot convert %qE from type %qT to type %qT", - expr, intype, type); + if (complain & tf_error) + error_at (loc, "cannot convert %qE from type %qT to type %qT", + expr, intype, type); return error_mark_node; } @@ -254,7 +260,7 @@ cp_convert_to_pointer (tree type, tree expr) (such as conversion from sub-type to private super-type). */ static tree -convert_to_pointer_force (tree type, tree expr) +convert_to_pointer_force (tree type, tree expr, tsubst_flags_t complain) { tree intype = TREE_TYPE (expr); enum tree_code form = TREE_CODE (intype); @@ -284,8 +290,7 @@ convert_to_pointer_force (tree type, tree expr) return error_mark_node; if (binfo) { - expr = build_base_path (code, expr, binfo, 0, - tf_warning_or_error); + expr = build_base_path (code, expr, binfo, 0, complain); if (expr == error_mark_node) return error_mark_node; /* Add any qualifier conversions. */ @@ -297,7 +302,7 @@ convert_to_pointer_force (tree type, tree expr) } } - return cp_convert_to_pointer (type, expr); + return cp_convert_to_pointer (type, expr, complain); } /* We are passing something to a function which requires a reference. @@ -309,7 +314,8 @@ convert_to_pointer_force (tree type, tree expr) If DIRECT_BIND is set, DECL is the reference we're binding to. */ static tree -build_up_reference (tree type, tree arg, int flags, tree decl) +build_up_reference (tree type, tree arg, int flags, tree decl, + tsubst_flags_t complain) { tree rval; tree argtype = TREE_TYPE (arg); @@ -351,12 +357,12 @@ build_up_reference (tree type, tree arg, int flags, tree decl) return error_mark_node; if (binfo == NULL_TREE) return error_not_base_type (target_type, argtype); - rval = build_base_path (PLUS_EXPR, rval, binfo, 1, - tf_warning_or_error); + rval = build_base_path (PLUS_EXPR, rval, binfo, 1, complain); } else rval - = convert_to_pointer_force (build_pointer_type (target_type), rval); + = convert_to_pointer_force (build_pointer_type (target_type), + rval, complain); return build_nop (type, rval); } @@ -403,15 +409,13 @@ warn_ref_binding (location_t loc, tree reftype, tree intype, tree decl) tree convert_to_reference (tree reftype, tree expr, int convtype, - int flags, tree decl) + int flags, tree decl, tsubst_flags_t complain) { tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype)); tree intype; tree rval = NULL_TREE; tree rval_as_conversion = NULL_TREE; bool can_convert_intype_to_type; - tsubst_flags_t complain = ((flags & LOOKUP_COMPLAIN) - ? tf_warning_or_error : tf_none); location_t loc = EXPR_LOC_OR_HERE (expr); if (TREE_CODE (type) == FUNCTION_TYPE @@ -452,21 +456,26 @@ convert_to_reference (tree reftype, tree expr, int convtype, if (((convtype & CONV_STATIC) && can_convert (intype, type, complain)) || ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type)) { - if (flags & LOOKUP_COMPLAIN) - { - tree ttl = TREE_TYPE (reftype); - tree ttr = lvalue_type (expr); + { + tree ttl = TREE_TYPE (reftype); + tree ttr = lvalue_type (expr); - if (! real_lvalue_p (expr)) - warn_ref_binding (loc, reftype, intype, decl); + if ((complain & tf_warning) + && ! real_lvalue_p (expr)) + warn_ref_binding (loc, reftype, intype, decl); - if (! (convtype & CONV_CONST) - && !at_least_as_qualified_p (ttl, ttr)) - permerror (loc, "conversion from %qT to %qT discards qualifiers", - ttr, reftype); - } + if (! (convtype & CONV_CONST) + && !at_least_as_qualified_p (ttl, ttr)) + { + if (complain & tf_error) + permerror (loc, "conversion from %qT to %qT discards qualifiers", + ttr, reftype); + else + return error_mark_node; + } + } - return build_up_reference (reftype, expr, flags, decl); + return build_up_reference (reftype, expr, flags, decl, complain); } else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr)) { @@ -477,28 +486,29 @@ convert_to_reference (tree reftype, tree expr, int convtype, /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they meant. */ - if (TREE_CODE (intype) == POINTER_TYPE + if ((complain & tf_warning) + && TREE_CODE (intype) == POINTER_TYPE && (comptypes (TREE_TYPE (intype), type, COMPARE_BASE | COMPARE_DERIVED))) warning_at (loc, 0, "casting %qT to %qT does not dereference pointer", intype, reftype); - rval = cp_build_addr_expr (expr, tf_warning_or_error); + rval = cp_build_addr_expr (expr, complain); if (rval != error_mark_node) rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), - rval, 0); + rval, 0, complain); if (rval != error_mark_node) rval = build1 (NOP_EXPR, reftype, rval); } else { rval = convert_for_initialization (NULL_TREE, type, expr, flags, - ICR_CONVERTING, 0, 0, - tf_warning_or_error); + ICR_CONVERTING, 0, 0, complain); if (rval == NULL_TREE || rval == error_mark_node) return rval; - warn_ref_binding (loc, reftype, intype, decl); - rval = build_up_reference (reftype, rval, flags, decl); + if (complain & tf_warning) + warn_ref_binding (loc, reftype, intype, decl); + rval = build_up_reference (reftype, rval, flags, decl, complain); } if (rval) @@ -507,7 +517,7 @@ convert_to_reference (tree reftype, tree expr, int convtype, return rval; } - if (flags & LOOKUP_COMPLAIN) + if (complain & tf_error) error_at (loc, "cannot convert type %qT to type %qT", intype, reftype); return error_mark_node; @@ -595,9 +605,9 @@ cp_fold_convert (tree type, tree expr) /* C++ conversions, preference to static cast conversions. */ tree -cp_convert (tree type, tree expr) +cp_convert (tree type, tree expr, tsubst_flags_t complain) { - return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL); + return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL, complain); } /* C++ equivalent of convert_and_check but using cp_convert as the @@ -608,16 +618,17 @@ cp_convert (tree type, tree expr) i.e. because of language rules and not because of an explicit cast. */ tree -cp_convert_and_check (tree type, tree expr) +cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain) { tree result; if (TREE_TYPE (expr) == type) return expr; - result = cp_convert (type, expr); + result = cp_convert (type, expr, complain); - if (c_inhibit_evaluation_warnings == 0 + if ((complain & tf_warning) + && c_inhibit_evaluation_warnings == 0 && !TREE_OVERFLOW_P (expr) && result != error_mark_node) warnings_for_convert_and_check (type, expr, result); @@ -630,7 +641,8 @@ cp_convert_and_check (tree type, tree expr) FLAGS indicates how we should behave. */ tree -ocp_convert (tree type, tree expr, int convtype, int flags) +ocp_convert (tree type, tree expr, int convtype, int flags, + tsubst_flags_t complain) { tree e = expr; enum tree_code code = TREE_CODE (type); @@ -647,7 +659,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags) if ((invalid_conv_diag = targetm.invalid_conversion (TREE_TYPE (expr), type))) { - error (invalid_conv_diag); + if (complain & tf_error) + error (invalid_conv_diag); return error_mark_node; } @@ -696,7 +709,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) if (code == VOID_TYPE && (convtype & CONV_STATIC)) { - e = convert_to_void (e, ICV_CAST, tf_warning_or_error); + e = convert_to_void (e, ICV_CAST, complain); return e; } @@ -714,9 +727,9 @@ ocp_convert (tree type, tree expr, int convtype, int flags) && ! (convtype & CONV_STATIC)) || TREE_CODE (intype) == POINTER_TYPE) { - if (flags & LOOKUP_COMPLAIN) + if (complain & tf_error) permerror (loc, "conversion from %q#T to %q#T", intype, type); - if (!flag_permissive) + else return error_mark_node; } @@ -727,7 +740,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags) the original value is within the range of the enumeration values. Otherwise, the resulting enumeration value is unspecified. */ - if (TREE_CODE (expr) == INTEGER_CST + if ((complain & tf_warning) + && TREE_CODE (expr) == INTEGER_CST && !int_fits_type_p (expr, ENUM_UNDERLYING_TYPE (type))) warning_at (loc, OPT_Wconversion, "the result of the conversion is unspecified because " @@ -740,7 +754,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) rval = build_type_conversion (type, e); if (rval) return rval; - if (flags & LOOKUP_COMPLAIN) + if (complain & tf_error) error_at (loc, "%q#T used where a %qT was expected", intype, type); return error_mark_node; } @@ -748,8 +762,10 @@ ocp_convert (tree type, tree expr, int convtype, int flags) { if (TREE_CODE (intype) == VOID_TYPE) { - error_at (loc, "could not convert %qE from %<void%> to %<bool%>", - expr); + if (complain & tf_error) + error_at (loc, + "could not convert %qE from %<void%> to %<bool%>", + expr); return error_mark_node; } @@ -768,7 +784,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) if (NULLPTR_TYPE_P (type) && e && null_ptr_cst_p (e)) return nullptr_node; if (POINTER_TYPE_P (type) || TYPE_PTRMEM_P (type)) - return fold_if_not_in_template (cp_convert_to_pointer (type, e)); + return fold_if_not_in_template (cp_convert_to_pointer (type, e, complain)); if (code == VECTOR_TYPE) { tree in_vtype = TREE_TYPE (e); @@ -778,8 +794,9 @@ ocp_convert (tree type, tree expr, int convtype, int flags) ret_val = build_type_conversion (type, e); if (ret_val) return ret_val; - if (flags & LOOKUP_COMPLAIN) - error_at (loc, "%q#T used where a %qT was expected", in_vtype, type); + if (complain & tf_error) + error_at (loc, "%q#T used where a %qT was expected", + in_vtype, type); return error_mark_node; } return fold_if_not_in_template (convert_to_vector (type, e)); @@ -792,10 +809,10 @@ ocp_convert (tree type, tree expr, int convtype, int flags) rval = build_type_conversion (type, e); if (rval) return rval; - else - if (flags & LOOKUP_COMPLAIN) - error_at (loc, "%q#T used where a floating point value was expected", - TREE_TYPE (e)); + else if (complain & tf_error) + error_at (loc, + "%q#T used where a floating point value was expected", + TREE_TYPE (e)); } if (code == REAL_TYPE) return fold_if_not_in_template (convert_to_real (type, e)); @@ -826,33 +843,31 @@ ocp_convert (tree type, tree expr, int convtype, int flags) return error_mark_node; if (BRACE_ENCLOSED_INITIALIZER_P (ctor)) - ctor = perform_implicit_conversion (type, ctor, tf_warning_or_error); + ctor = perform_implicit_conversion (type, ctor, complain); else if ((flags & LOOKUP_ONLYCONVERTING) && ! (CLASS_TYPE_P (dtype) && DERIVED_FROM_P (type, dtype))) /* For copy-initialization, first we create a temp of the proper type with a user-defined conversion sequence, then we direct-initialize the target with the temp (see [dcl.init]). */ - ctor = build_user_type_conversion (type, ctor, flags, - tf_warning_or_error); + ctor = build_user_type_conversion (type, ctor, flags, complain); else { VEC(tree,gc) *ctor_vec = make_tree_vector_single (ctor); ctor = build_special_member_call (NULL_TREE, complete_ctor_identifier, &ctor_vec, - type, flags, - tf_warning_or_error); + type, flags, complain); release_tree_vector (ctor_vec); } if (ctor) - return build_cplus_new (type, ctor, tf_warning_or_error); + return build_cplus_new (type, ctor, complain); } - if (flags & LOOKUP_COMPLAIN) + if (complain & tf_error) { /* If the conversion failed and expr was an invalid use of pointer to member function, try to report a meaningful error. */ - if (invalid_nonstatic_memfn_p (expr, tf_warning_or_error)) + if (invalid_nonstatic_memfn_p (expr, complain)) /* We displayed the error message. */; else error_at (loc, "conversion from %qT to non-scalar type %qT requested", @@ -1416,7 +1431,8 @@ convert (tree type, tree expr) return fold_if_not_in_template (build_nop (type, expr)); return ocp_convert (type, expr, CONV_OLD_CONVERT, - LOOKUP_NORMAL|LOOKUP_NO_CONVERSION); + LOOKUP_NORMAL|LOOKUP_NO_CONVERSION, + tf_warning_or_error); } /* Like cp_convert, except permit conversions to take place which @@ -1424,18 +1440,19 @@ convert (tree type, tree expr) (such as conversion from sub-type to private super-type). */ tree -convert_force (tree type, tree expr, int convtype) +convert_force (tree type, tree expr, int convtype, tsubst_flags_t complain) { tree e = expr; enum tree_code code = TREE_CODE (type); if (code == REFERENCE_TYPE) return (fold_if_not_in_template - (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN, - NULL_TREE))); + (convert_to_reference (type, e, CONV_C_CAST, 0, + NULL_TREE, complain))); if (code == POINTER_TYPE) - return fold_if_not_in_template (convert_to_pointer_force (type, e)); + return fold_if_not_in_template (convert_to_pointer_force (type, e, + complain)); /* From typeck.c convert_for_assignment */ if (((TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE && TREE_CODE (e) == ADDR_EXPR @@ -1446,9 +1463,9 @@ convert_force (tree type, tree expr, int convtype) && TYPE_PTRMEMFUNC_P (type)) /* compatible pointer to member functions. */ return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1, - /*c_cast_p=*/1, tf_warning_or_error); + /*c_cast_p=*/1, complain); - return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL); + return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL, complain); } /* Convert an aggregate EXPR to type XTYPE. If a conversion diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index aa98f8b..b0f62a3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8091,9 +8091,10 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) processing_template_decl = 0; itype = cp_build_binary_op (input_location, MINUS_EXPR, - cp_convert (ssizetype, size), - cp_convert (ssizetype, integer_one_node), - tf_warning_or_error); + cp_convert (ssizetype, size, complain), + cp_convert (ssizetype, integer_one_node, + complain), + complain); itype = fold (itype); processing_template_decl = saved_processing_template_decl; @@ -13277,11 +13278,12 @@ finish_destructor_body (void) an implicit definition), non-placement operator delete shall be looked up in the scope of the destructor's class and if found shall be accessible and unambiguous. */ - exprstmt = build_op_delete_call(DELETE_EXPR, current_class_ptr, - virtual_size, - /*global_p=*/false, - /*placement=*/NULL_TREE, - /*alloc_fn=*/NULL_TREE); + exprstmt = build_op_delete_call (DELETE_EXPR, current_class_ptr, + virtual_size, + /*global_p=*/false, + /*placement=*/NULL_TREE, + /*alloc_fn=*/NULL_TREE, + tf_warning_or_error); if_stmt = begin_if_stmt (); finish_if_stmt_cond (build2 (BIT_AND_EXPR, integer_type_node, diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 6fe3cce..2339b9c 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -424,7 +424,8 @@ initialize_handler_parm (tree decl, tree exp) && TYPE_PTR_P (TREE_TYPE (init_type))) exp = cp_build_addr_expr (exp, tf_warning_or_error); - exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0); + exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0, + tf_warning_or_error); init = convert_from_reference (exp); @@ -435,7 +436,8 @@ initialize_handler_parm (tree decl, tree exp) /* Generate the copy constructor call directly so we can wrap it. See also expand_default_init. */ init = ocp_convert (TREE_TYPE (decl), init, - CONV_IMPLICIT|CONV_FORCE_TEMP, 0); + CONV_IMPLICIT|CONV_FORCE_TEMP, 0, + tf_warning_or_error); /* Force cleanups now to avoid nesting problems with the MUST_NOT_THROW_EXPR. */ init = fold_build_cleanup_point_expr (TREE_TYPE (init), init); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 5bd46cb..419c13f 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1180,7 +1180,7 @@ expand_virtual_init (tree binfo, tree decl) gcc_assert (vtbl_ptr != error_mark_node); /* Assign the vtable to the vptr. */ - vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0); + vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0, tf_warning_or_error); finish_expr_stmt (cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl, tf_warning_or_error)); } @@ -1250,7 +1250,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, tf_warning_or_error); + 0, tf_warning_or_error); finish_then_clause (inner_if_stmt); finish_if_stmt (inner_if_stmt); @@ -1598,7 +1598,8 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags, have already built up the constructor call so we could wrap it in an exception region. */; else - init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); + init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, + flags, complain); if (TREE_CODE (init) == MUST_NOT_THROW_EXPR) /* We need to protect the initialization of a catch parm with a @@ -2656,7 +2657,8 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, size, globally_qualified_p, placement_allocation_fn_p ? alloc_call : NULL_TREE, - alloc_fn)); + alloc_fn, + complain)); if (!cleanup) /* We're done. */; @@ -2815,7 +2817,7 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts, return error_mark_node; } nelts = mark_rvalue_use (nelts); - nelts = cp_save_expr (cp_convert (sizetype, nelts)); + nelts = cp_save_expr (cp_convert (sizetype, nelts, complain)); } /* ``A reference cannot be created by the new operator. A reference @@ -3012,12 +3014,12 @@ build_vec_delete_1 (tree base, tree maxindex, tree type, base_tbd = cp_build_binary_op (input_location, MINUS_EXPR, cp_convert (string_type_node, - base), + base, complain), cookie_size, complain); if (base_tbd == error_mark_node) return error_mark_node; - base_tbd = cp_convert (ptype, base_tbd); + base_tbd = cp_convert (ptype, base_tbd, complain); /* True size with header. */ virtual_size = size_binop (PLUS_EXPR, virtual_size, cookie_size); } @@ -3026,7 +3028,8 @@ build_vec_delete_1 (tree base, tree maxindex, tree type, base_tbd, virtual_size, use_global_delete & 1, /*placement=*/NULL_TREE, - /*alloc_fn=*/NULL_TREE); + /*alloc_fn=*/NULL_TREE, + complain); } body = loop; @@ -3189,14 +3192,14 @@ build_vec_init (tree base, tree maxindex, tree init, return stmt_expr; } - maxindex = cp_convert (ptrdiff_type_node, maxindex); + maxindex = cp_convert (ptrdiff_type_node, maxindex, complain); if (TREE_CODE (atype) == ARRAY_TYPE) { ptype = build_pointer_type (type); base = decay_conversion (base, complain); if (base == error_mark_node) return error_mark_node; - base = cp_convert (ptype, base); + base = cp_convert (ptype, base, complain); } else ptype = atype; @@ -3665,7 +3668,7 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, addr = save_expr (addr); /* Throw away const and volatile on target type of addr. */ - addr = convert_force (build_pointer_type (type), addr, 0); + addr = convert_force (build_pointer_type (type), addr, 0, complain); } else if (TREE_CODE (type) == ARRAY_TYPE) { @@ -3691,7 +3694,7 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, if (TREE_SIDE_EFFECTS (addr)) addr = save_expr (addr); - addr = convert_force (build_pointer_type (type), addr, 0); + addr = convert_force (build_pointer_type (type), addr, 0, complain); } gcc_assert (MAYBE_CLASS_TYPE_P (type)); @@ -3705,7 +3708,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, cxx_sizeof_nowarn (type), use_global_delete, /*placement=*/NULL_TREE, - /*alloc_fn=*/NULL_TREE); + /*alloc_fn=*/NULL_TREE, + complain); } else { @@ -3744,7 +3748,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, cxx_sizeof_nowarn (type), /*global_p=*/false, /*placement=*/NULL_TREE, - /*alloc_fn=*/NULL_TREE); + /*alloc_fn=*/NULL_TREE, + complain); /* Call the complete object destructor. */ auto_delete = sfk_complete_destructor; } @@ -3756,7 +3761,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type), /*global_p=*/false, /*placement=*/NULL_TREE, - /*alloc_fn=*/NULL_TREE); + /*alloc_fn=*/NULL_TREE, + complain); } expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL, complain), diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 6e29521..0237456 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1228,16 +1228,9 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, scope = push_scope (ctype); - if (diag) - { - flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED; - complain = tf_warning_or_error; - } - else - { - flags = LOOKUP_PROTECT|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED; - complain = tf_none; - } + flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED; + + complain = diag ? tf_warning_or_error : tf_none; if (const_p) quals = TYPE_QUAL_CONST; diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 642f39f..9cc6d39 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1854,7 +1854,7 @@ identifier_type_value_1 (tree id) return REAL_IDENTIFIER_TYPE_VALUE (id); /* Have to search for it. It must be on the global level, now. Ask lookup_name not to return non-types. */ - id = lookup_name_real (id, 2, 1, /*block_p=*/true, 0, LOOKUP_COMPLAIN); + id = lookup_name_real (id, 2, 1, /*block_p=*/true, 0, 0); if (id) return TREE_TYPE (id); return NULL_TREE; @@ -4345,7 +4345,6 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain) { struct scope_binding binding = EMPTY_SCOPE_BINDING; - flags |= LOOKUP_COMPLAIN; if (is_type_p) flags |= LOOKUP_PREFER_TYPES; if (qualified_lookup_using_namespace (name, scope, &binding, flags)) @@ -4772,7 +4771,7 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, tree lookup_name_nonclass (tree name) { - return lookup_name_real (name, 0, 1, /*block_p=*/true, 0, LOOKUP_COMPLAIN); + return lookup_name_real (name, 0, 1, /*block_p=*/true, 0, 0); } tree @@ -4780,22 +4779,20 @@ lookup_function_nonclass (tree name, VEC(tree,gc) *args, bool block_p) { return lookup_arg_dependent (name, - lookup_name_real (name, 0, 1, block_p, 0, - LOOKUP_COMPLAIN), + lookup_name_real (name, 0, 1, block_p, 0, 0), args, false); } tree lookup_name (tree name) { - return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, LOOKUP_COMPLAIN); + return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, 0); } tree lookup_name_prefer_type (tree name, int prefer_type) { - return lookup_name_real (name, prefer_type, 0, /*block_p=*/true, - 0, LOOKUP_COMPLAIN); + return lookup_name_real (name, prefer_type, 0, /*block_p=*/true, 0, 0); } /* Look up NAME for type used in elaborated name specifier in diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index 5698c97..8f0b3c0 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -138,7 +138,8 @@ build_delete_destructor_body (tree delete_dtor, tree complete_dtor) virtual_size, /*global_p=*/false, /*placement=*/NULL_TREE, - /*alloc_fn=*/NULL_TREE); + /*alloc_fn=*/NULL_TREE, + tf_warning_or_error); add_stmt (call_delete); /* Return the address of the object. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 5256d01..85e0322 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -20320,13 +20320,9 @@ cp_parser_lookup_name (cp_parser *parser, tree name, tree *ambiguous_decls, location_t name_location) { - int flags = 0; tree decl; tree object_type = parser->context->object_type; - if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) - flags |= LOOKUP_COMPLAIN; - /* Assume that the lookup will be unambiguous. */ if (ambiguous_decls) *ambiguous_decls = NULL_TREE; @@ -20498,7 +20494,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, /* Look it up in the enclosing context, too. */ decl = lookup_name_real (name, tag_type != none_type, /*nonclass=*/0, - /*block_p=*/true, is_namespace, flags); + /*block_p=*/true, is_namespace, 0); parser->object_scope = object_type; parser->qualifying_scope = NULL_TREE; if (object_decl) @@ -20508,7 +20504,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, { decl = lookup_name_real (name, tag_type != none_type, /*nonclass=*/0, - /*block_p=*/true, is_namespace, flags); + /*block_p=*/true, is_namespace, 0); parser->qualifying_scope = NULL_TREE; parser->object_scope = NULL_TREE; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4d4e8ad..df80159 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8474,8 +8474,7 @@ tsubst_friend_class (tree friend_tmpl, tree args) both F templates are the same. */ tmpl = lookup_name_real (DECL_NAME (friend_tmpl), 0, 0, - /*block_p=*/true, 0, - LOOKUP_COMPLAIN | LOOKUP_HIDDEN); + /*block_p=*/true, 0, LOOKUP_HIDDEN); /* But, if we don't find one, it might be because we're in a situation like this: diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index e79b02e..a19a893 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -99,7 +99,7 @@ VEC(tree,gc) *unemitted_tinfo_decls; and are generated as needed. */ static GTY (()) VEC(tinfo_s,gc) *tinfo_descs; -static tree ifnonnull (tree, tree); +static tree ifnonnull (tree, tree, tsubst_flags_t); static tree tinfo_name (tree, bool); static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t); static tree throw_bad_cast (void); @@ -336,7 +336,8 @@ build_typeid (tree exp) This is an lvalue use of expr then. */ exp = mark_lvalue_use (exp); exp = stabilize_reference (exp); - cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0)); + cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0), + tf_warning_or_error); } exp = get_tinfo_decl_dynamic (exp); @@ -498,12 +499,13 @@ get_typeid (tree type) RESULT, it must have previously had a save_expr applied to it. */ static tree -ifnonnull (tree test, tree result) +ifnonnull (tree test, tree result, tsubst_flags_t complain) { return build3 (COND_EXPR, TREE_TYPE (result), build2 (EQ_EXPR, boolean_type_node, test, - cp_convert (TREE_TYPE (test), nullptr_node)), - cp_convert (TREE_TYPE (result), nullptr_node), + cp_convert (TREE_TYPE (test), nullptr_node, + complain)), + cp_convert (TREE_TYPE (result), nullptr_node, complain), result); } @@ -596,7 +598,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) /* Apply trivial conversion T -> T& for dereferenced ptrs. */ expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT, - LOOKUP_NORMAL, NULL_TREE); + LOOKUP_NORMAL, NULL_TREE, complain); } /* The dynamic_cast operator shall not cast away constness. */ @@ -644,7 +646,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) expr1 = build_headof (expr); if (TREE_TYPE (expr1) != type) expr1 = build1 (NOP_EXPR, type, expr1); - return ifnonnull (expr, expr1); + return ifnonnull (expr, expr1, complain); } else { @@ -752,12 +754,12 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) neq = cp_truthvalue_conversion (result); return cp_convert (type, build3 (COND_EXPR, TREE_TYPE (result), - neq, result, bad)); + neq, result, bad), complain); } /* Now back to the type we want from a void*. */ - result = cp_convert (type, result); - return ifnonnull (expr, result); + result = cp_convert (type, result, complain); + return ifnonnull (expr, result, complain); } } else diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 4334d4c..7769bba 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -564,7 +564,8 @@ finish_goto_stmt (tree destination) destination = mark_rvalue_use (destination); if (!processing_template_decl) { - destination = cp_convert (ptr_type_node, destination); + destination = cp_convert (ptr_type_node, destination, + tf_warning_or_error); if (error_operand_p (destination)) return NULL_TREE; } @@ -4526,7 +4527,8 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv, if (error_operand_p (iter_incr)) return true; incr = TREE_OPERAND (rhs, 1); - incr = cp_convert (TREE_TYPE (diff), incr); + incr = cp_convert (TREE_TYPE (diff), incr, + tf_warning_or_error); if (TREE_CODE (rhs) == MINUS_EXPR) { incr = build1 (NEGATE_EXPR, TREE_TYPE (diff), incr); @@ -4581,7 +4583,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv, return true; } - incr = cp_convert (TREE_TYPE (diff), incr); + incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error); for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE && OMP_CLAUSE_DECL (c) == iter) @@ -5130,7 +5132,7 @@ finish_static_assert (tree condition, tree message, location_t location, /* Fold the expression and convert it to a boolean value. */ condition = fold_non_dependent_expr (condition); - condition = cp_convert (boolean_type_node, condition); + condition = cp_convert (boolean_type_node, condition, tf_warning_or_error); condition = maybe_constant_value (condition); if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition)) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index bca676b..945266b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -52,7 +52,7 @@ static tree rationalize_conditional_expr (enum tree_code, tree, static int comp_ptr_ttypes_real (tree, tree, int); static bool comp_except_types (tree, tree, bool); static bool comp_array_types (const_tree, const_tree, bool); -static tree pointer_diff (tree, tree, tree); +static tree pointer_diff (tree, tree, tree, tsubst_flags_t); static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t); static void casts_away_constness_r (tree *, tree *, tsubst_flags_t); static bool casts_away_constness (tree, tree, tsubst_flags_t); @@ -1906,7 +1906,7 @@ decay_conversion (tree exp, tsubst_flags_t complain) /* This way is better for a COMPONENT_REF since it can simplify the offset for a component. */ adr = cp_build_addr_expr (exp, complain); - return cp_convert (ptrtype, adr); + return cp_convert (ptrtype, adr, complain); } /* If a bitfield is used in a context where integral promotion @@ -1950,12 +1950,12 @@ cp_default_conversion (tree exp, tsubst_flags_t complain) /* Check for target-specific promotions. */ tree promoted_type = targetm.promoted_type (TREE_TYPE (exp)); if (promoted_type) - exp = cp_convert (promoted_type, exp); + exp = cp_convert (promoted_type, exp, complain); /* Perform the integral promotions first so that bitfield expressions (which may promote to "int", even if the bitfield is declared "unsigned") are promoted correctly. */ else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp))) - exp = perform_integral_promotions (exp); + exp = cp_perform_integral_promotions (exp, complain); /* Perform the other conversions. */ exp = decay_conversion (exp, complain); @@ -1975,7 +1975,7 @@ default_conversion (tree exp) converted value. */ tree -perform_integral_promotions (tree expr) +cp_perform_integral_promotions (tree expr, tsubst_flags_t complain) { tree type; tree promoted_type; @@ -1995,10 +1995,18 @@ perform_integral_promotions (tree expr) return expr; promoted_type = type_promotes_to (type); if (type != promoted_type) - expr = cp_convert (promoted_type, expr); + expr = cp_convert (promoted_type, expr, complain); return expr; } +/* C version. */ + +tree +perform_integral_promotions (tree expr) +{ + return cp_perform_integral_promotions (expr, tf_warning_or_error); +} + /* Returns nonzero iff exp is a STRING_CST or the result of applying decay_conversion to one. */ @@ -2945,7 +2953,7 @@ cp_build_array_ref (location_t loc, tree array, tree idx, does not say that we should. In fact, the natural thing would seem to be to convert IDX to ptrdiff_t; we're performing pointer arithmetic.) */ - idx = perform_integral_promotions (idx); + idx = cp_perform_integral_promotions (idx, complain); /* An array that is indexed by a non-constant cannot be stored in a register; we must be able to do @@ -3867,7 +3875,8 @@ cp_build_binary_op (location_t location, if (code0 == POINTER_TYPE && code1 == POINTER_TYPE && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0), TREE_TYPE (type1))) - return pointer_diff (op0, op1, common_pointer_type (type0, type1)); + return pointer_diff (op0, op1, common_pointer_type (type0, type1), + complain); /* In all other cases except pointer - int, the usual arithmetic rules apply. */ else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE)) @@ -4003,7 +4012,7 @@ cp_build_binary_op (location_t location, /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1); + op1 = cp_convert (integer_type_node, op1, complain); /* Avoid converting op1 to result_type later. */ converted = 1; } @@ -4031,7 +4040,7 @@ cp_build_binary_op (location_t location, /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1); + op1 = cp_convert (integer_type_node, op1, complain); /* Avoid converting op1 to result_type later. */ converted = 1; } @@ -4062,7 +4071,7 @@ cp_build_binary_op (location_t location, /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1); + op1 = cp_convert (integer_type_node, op1, complain); } break; @@ -4162,12 +4171,12 @@ cp_build_binary_op (location_t location, op0 = cp_build_binary_op (location, TRUTH_ANDIF_EXPR, e1, e2, complain); - op1 = cp_convert (TREE_TYPE (op0), integer_one_node); + op1 = cp_convert (TREE_TYPE (op0), integer_one_node, complain); } else { op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier); - op1 = cp_convert (TREE_TYPE (op0), op1); + op1 = cp_convert (TREE_TYPE (op0), op1, complain); } result_type = TREE_TYPE (op0); } @@ -4190,9 +4199,9 @@ cp_build_binary_op (location_t location, CPO_COMPARISON, complain); if (!same_type_p (TREE_TYPE (op0), type)) - op0 = cp_convert_and_check (type, op0); + op0 = cp_convert_and_check (type, op0, complain); if (!same_type_p (TREE_TYPE (op1), type)) - op1 = cp_convert_and_check (type, op1); + op1 = cp_convert_and_check (type, op1, complain); if (op0 == error_mark_node || op1 == error_mark_node) return error_mark_node; @@ -4456,16 +4465,16 @@ cp_build_binary_op (location_t location, if (first_complex) { if (TREE_TYPE (op0) != result_type) - op0 = cp_convert_and_check (result_type, op0); + op0 = cp_convert_and_check (result_type, op0, complain); if (TREE_TYPE (op1) != real_type) - op1 = cp_convert_and_check (real_type, op1); + op1 = cp_convert_and_check (real_type, op1, complain); } else { if (TREE_TYPE (op0) != real_type) - op0 = cp_convert_and_check (real_type, op0); + op0 = cp_convert_and_check (real_type, op0, complain); if (TREE_TYPE (op1) != result_type) - op1 = cp_convert_and_check (result_type, op1); + op1 = cp_convert_and_check (result_type, op1, complain); } if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK) return error_mark_node; @@ -4550,7 +4559,7 @@ cp_build_binary_op (location_t location, tree val = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); if (val != 0) - return cp_convert (boolean_type_node, val); + return cp_convert (boolean_type_node, val, complain); op0 = xop0, op1 = xop1; converted = 1; resultcode = xresultcode; @@ -4580,9 +4589,9 @@ cp_build_binary_op (location_t location, if (! converted) { if (TREE_TYPE (op0) != result_type) - op0 = cp_convert_and_check (result_type, op0); + op0 = cp_convert_and_check (result_type, op0, complain); if (TREE_TYPE (op1) != result_type) - op1 = cp_convert_and_check (result_type, op1); + op1 = cp_convert_and_check (result_type, op1, complain); if (op0 == error_mark_node || op1 == error_mark_node) return error_mark_node; @@ -4594,7 +4603,7 @@ cp_build_binary_op (location_t location, result = build2 (resultcode, build_type, op0, op1); result = fold_if_not_in_template (result); if (final_type != 0) - result = cp_convert (final_type, result); + result = cp_convert (final_type, result, complain); if (TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (op0) @@ -4627,7 +4636,7 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop) The resulting tree has type int. */ static tree -pointer_diff (tree op0, tree op1, tree ptrtype) +pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain) { tree result; tree restype = ptrdiff_type_node; @@ -4637,24 +4646,48 @@ pointer_diff (tree op0, tree op1, tree ptrtype) return error_mark_node; if (TREE_CODE (target_type) == VOID_TYPE) - permerror (input_location, "ISO C++ forbids using pointer of type %<void *%> in subtraction"); + { + if (complain & tf_error) + permerror (input_location, "ISO C++ forbids using pointer of " + "type %<void *%> in subtraction"); + else + return error_mark_node; + } if (TREE_CODE (target_type) == FUNCTION_TYPE) - permerror (input_location, "ISO C++ forbids using pointer to a function in subtraction"); + { + if (complain & tf_error) + permerror (input_location, "ISO C++ forbids using pointer to " + "a function in subtraction"); + else + return error_mark_node; + } if (TREE_CODE (target_type) == METHOD_TYPE) - permerror (input_location, "ISO C++ forbids using pointer to a method in subtraction"); + { + if (complain & tf_error) + permerror (input_location, "ISO C++ forbids using pointer to " + "a method in subtraction"); + else + return error_mark_node; + } /* First do the subtraction as integers; then drop through to build the divide operator. */ op0 = cp_build_binary_op (input_location, MINUS_EXPR, - cp_convert (restype, op0), - cp_convert (restype, op1), - tf_warning_or_error); + cp_convert (restype, op0, complain), + cp_convert (restype, op1, complain), + complain); /* This generates an error if op1 is a pointer to an incomplete type. */ if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1)))) - error ("invalid use of a pointer to an incomplete type in pointer arithmetic"); + { + if (complain & tf_error) + error ("invalid use of a pointer to an incomplete type in " + "pointer arithmetic"); + else + return error_mark_node; + } op1 = (TYPE_PTROB_P (ptrtype) ? size_in_bytes (target_type) @@ -4662,7 +4695,8 @@ pointer_diff (tree op0, tree op1, tree ptrtype) /* Do the division. */ - result = build2 (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1)); + result = build2 (EXACT_DIV_EXPR, restype, op0, + cp_convert (restype, op1, complain)); return fold_if_not_in_template (result); } @@ -5175,7 +5209,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, else { if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg))) - arg = perform_integral_promotions (arg); + arg = cp_perform_integral_promotions (arg, complain); /* Make sure the result is not an lvalue: a unary plus or minus expression is always a rvalue. */ @@ -5200,7 +5234,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, arg, true))) errstring = _("wrong type argument to bit-complement"); else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg))) - arg = perform_integral_promotions (arg); + arg = cp_perform_integral_promotions (arg, complain); break; case ABS_EXPR: @@ -5358,7 +5392,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, else inc = integer_one_node; - inc = cp_convert (argtype, inc); + inc = cp_convert (argtype, inc, complain); /* If 'arg' is an Objective-C PROPERTY_REF expression, then we need to ask Objective-C to build the increment or decrement @@ -6074,7 +6108,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, || SCALAR_FLOAT_TYPE_P (type)) && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype) || SCALAR_FLOAT_TYPE_P (intype))) - return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL); + return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain); if (TYPE_PTR_P (type) && TYPE_PTR_P (intype) && CLASS_TYPE_P (TREE_TYPE (type)) @@ -6417,7 +6451,7 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, return error_mark_node; } - return cp_convert (type, expr); + return cp_convert (type, expr, complain); } tree @@ -7078,7 +7112,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, NULL_TREE, 0, complain, LOOKUP_IMPLICIT); if (!same_type_p (lhstype, olhstype)) - newrhs = cp_convert_and_check (lhstype, newrhs); + newrhs = cp_convert_and_check (lhstype, newrhs, complain); if (modifycode != INIT_EXPR) { @@ -7599,7 +7633,7 @@ convert_for_assignment (tree type, tree rhs, if (!warn_pmf2ptr && TYPE_PTR_P (type) && TYPE_PTRMEMFUNC_P (rhstype)) - rhs = cp_convert (strip_top_quals (type), rhs); + rhs = cp_convert (strip_top_quals (type), rhs, complain); else { if (complain & tf_error) @@ -7723,9 +7757,7 @@ convert_for_assignment (tree type, tree rhs, latter (X(X&)). If using constructor make sure no conversion operator exists, if one does - exist, an ambiguity exists. - - If flags doesn't include LOOKUP_COMPLAIN, don't complain about anything. */ + exist, an ambiguity exists. */ tree convert_for_initialization (tree exp, tree type, tree rhs, int flags, diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 688dabc..326f602 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1264,7 +1264,7 @@ process_init_constructor_record (tree type, tree init, /* If this is a bitfield, now convert to the lowered type. */ if (type != TREE_TYPE (field)) - next = cp_convert_and_check (TREE_TYPE (field), next); + next = cp_convert_and_check (TREE_TYPE (field), next, complain); flags |= picflag_from_initializer (next); CONSTRUCTOR_APPEND_ELT (v, field, next); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 01d759d..2711820 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-06-06 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/53567 + * g++.dg/cpp0x/alias-decl-19.C: New. + 2012-06-06 Steven Bosscher <steven@gcc.gnu.org> * g++.old-deja/g++.brendan/array1.C: Remove dg-options. diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C new file mode 100644 index 0000000..b101cb3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C @@ -0,0 +1,31 @@ +// PR c++/53567 +// { dg-do compile { target c++11 } } + +template <unsigned int, bool> struct IntegerType { typedef unsigned type; }; + +template <class EnumT> +using UnderlyingEnumType = typename IntegerType<sizeof(EnumT), (EnumT(-1) > EnumT(0))>::type; + +template <class EnumT, class UnderlyingT = UnderlyingEnumType<EnumT>> +struct EnumMask +{ + constexpr EnumMask(EnumT val) : m_val(val) {} + operator EnumT() { return m_val; } + + EnumT m_val; +}; + +enum class A : unsigned { x }; + +template <class EnumT> +EnumMask<EnumT> operator ~(EnumT lhs) +{ + return EnumT(~unsigned(lhs) & unsigned(EnumT::maskAll)); // { dg-error "not a member" } + +} + +int main() +{ + ~A::x; + return 0; +} |