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
This commit is contained in:
parent
6f07a821c4
commit
4b978f9691
19 changed files with 389 additions and 242 deletions
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
197
gcc/cp/cvt.c
197
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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
116
gcc/cp/typeck.c
116
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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
31
gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C
Normal file
31
gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue