Mercurial > hg > CbC > CbC_gcc
diff gcc/cp/cvt.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
line wrap: on
line diff
--- a/gcc/cp/cvt.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/cp/cvt.c Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* Language-level data type conversion for GNU C++. - Copyright (C) 1987-2018 Free Software Foundation, Inc. + Copyright (C) 1987-2020 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -35,6 +35,7 @@ #include "convert.h" #include "stringpool.h" #include "attribs.h" +#include "escaped_string.h" static tree convert_to_pointer_force (tree, tree, tsubst_flags_t); static tree build_type_conversion (tree, tree); @@ -77,7 +78,7 @@ tree intype = TREE_TYPE (expr); enum tree_code form; tree rval; - location_t loc = cp_expr_loc_or_loc (expr, input_location); + location_t loc = cp_expr_loc_or_input_loc (expr); if (intype == error_mark_node) return error_mark_node; @@ -88,7 +89,7 @@ if (!COMPLETE_TYPE_P (intype)) { if (complain & tf_error) - error_at (loc, "can%'t convert from incomplete type %qH to %qI", + error_at (loc, "cannot convert from incomplete type %qH to %qI", intype, type); return error_mark_node; } @@ -419,7 +420,7 @@ tree rval = NULL_TREE; tree rval_as_conversion = NULL_TREE; bool can_convert_intype_to_type; - location_t loc = cp_expr_loc_or_loc (expr, input_location); + location_t loc = cp_expr_loc_or_input_loc (expr); if (TREE_CODE (type) == FUNCTION_TYPE && TREE_TYPE (expr) == unknown_type_node) @@ -562,10 +563,9 @@ tree type = TREE_TYPE (expr); if (MAYBE_CLASS_TYPE_P (type) && TREE_CODE (expr) != TARGET_EXPR) { - vec<tree, va_gc> *args = make_tree_vector_single (expr); + releasing_vec args (make_tree_vector_single (expr)); expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, &args, type, LOOKUP_NORMAL, complain); - release_tree_vector (args); expr = build_cplus_new (type, expr, complain); } else @@ -582,15 +582,20 @@ static tree ignore_overflows (tree expr, tree orig) { - if (TREE_CODE (expr) == INTEGER_CST - && TREE_CODE (orig) == INTEGER_CST - && TREE_OVERFLOW (expr) != TREE_OVERFLOW (orig)) + tree stripped_expr = tree_strip_any_location_wrapper (expr); + tree stripped_orig = tree_strip_any_location_wrapper (orig); + + if (TREE_CODE (stripped_expr) == INTEGER_CST + && TREE_CODE (stripped_orig) == INTEGER_CST + && TREE_OVERFLOW (stripped_expr) != TREE_OVERFLOW (stripped_orig)) { - gcc_assert (!TREE_OVERFLOW (orig)); + gcc_assert (!TREE_OVERFLOW (stripped_orig)); /* Ensure constant sharing. */ - expr = wide_int_to_tree (TREE_TYPE (expr), wi::to_wide (expr)); + stripped_expr = wide_int_to_tree (TREE_TYPE (stripped_expr), + wi::to_wide (stripped_expr)); } - return expr; + + return preserve_any_location_wrapper (stripped_expr, expr); } /* Fold away simple conversions, but make sure TREE_OVERFLOW is set @@ -667,7 +672,7 @@ folded_result = fold_simple (folded_result); if (!TREE_OVERFLOW_P (folded) && folded_result != error_mark_node) - warnings_for_convert_and_check (cp_expr_loc_or_loc (expr, input_location), + warnings_for_convert_and_check (cp_expr_loc_or_input_loc (expr), type, folded, folded_result); } @@ -686,7 +691,7 @@ enum tree_code code = TREE_CODE (type); const char *invalid_conv_diag; tree e1; - location_t loc = cp_expr_loc_or_loc (expr, input_location); + location_t loc = cp_expr_loc_or_input_loc (expr); bool dofold = (convtype & CONV_FOLD); if (error_operand_p (e) || type == error_mark_node) @@ -725,7 +730,8 @@ /* We need a new temporary; don't take this shortcut. */; else if (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (e))) { - if (same_type_p (type, TREE_TYPE (e))) + tree etype = TREE_TYPE (e); + if (same_type_p (type, etype)) /* The call to fold will not always remove the NOP_EXPR as might be expected, since if one of the types is a typedef; the comparison in fold is just equality of pointers, not a @@ -738,14 +744,21 @@ else if (TREE_CODE (type) == COMPLEX_TYPE) return convert_to_complex_maybe_fold (type, e, dofold); else if (VECTOR_TYPE_P (type)) - return convert_to_vector (type, e); + return convert_to_vector (type, rvalue (e)); else if (TREE_CODE (e) == TARGET_EXPR) { /* Don't build a NOP_EXPR of class type. Instead, change the type of the temporary. */ + gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype)); TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type; return e; } + else if (TREE_CODE (e) == CONSTRUCTOR) + { + gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype)); + TREE_TYPE (e) = type; + return e; + } else { /* We shouldn't be treating objects of ADDRESSABLE type as @@ -792,10 +805,11 @@ the original value is within the range of the enumeration values. Otherwise, the resulting enumeration value is unspecified. */ + tree val = fold_for_warn (e); if ((complain & tf_warning) - && TREE_CODE (e) == INTEGER_CST + && TREE_CODE (val) == INTEGER_CST && ENUM_UNDERLYING_TYPE (type) - && !int_fits_type_p (e, ENUM_UNDERLYING_TYPE (type))) + && !int_fits_type_p (val, ENUM_UNDERLYING_TYPE (type))) warning_at (loc, OPT_Wconversion, "the result of the conversion is unspecified because " "%qE is outside the range of type %qT", @@ -822,18 +836,27 @@ return error_mark_node; } + if (VECTOR_TYPE_P (intype) && !gnu_vector_type_p (intype)) + { + if (complain & tf_error) + error_at (loc, "could not convert %qE from %qH to %qI", expr, + TREE_TYPE (expr), type); + return error_mark_node; + } + /* We can't implicitly convert a scoped enum to bool, so convert to the underlying type first. */ if (SCOPED_ENUM_P (intype) && (convtype & CONV_STATIC)) e = build_nop (ENUM_UNDERLYING_TYPE (intype), e); if (complain & tf_warning) - return cp_truthvalue_conversion (e); + return cp_truthvalue_conversion (e, complain); else { /* Prevent bogus -Wint-in-bool-context warnings coming from c_common_truthvalue_conversion down the line. */ warning_sentinel w (warn_int_in_bool_context); - return cp_truthvalue_conversion (e); + warning_sentinel c (warn_sign_compare); + return cp_truthvalue_conversion (e, complain); } } @@ -858,7 +881,7 @@ in_vtype, type); return error_mark_node; } - return convert_to_vector (type, e); + return convert_to_vector (type, rvalue (e)); } if (code == REAL_TYPE || code == COMPLEX_TYPE) { @@ -870,7 +893,7 @@ return rval; else if (complain & tf_error) error_at (loc, - "%q#T used where a floating point value was expected", + "%q#T used where a floating-point value was expected", TREE_TYPE (e)); } if (code == REAL_TYPE) @@ -911,12 +934,11 @@ ctor = build_user_type_conversion (type, ctor, flags, complain); else { - vec<tree, va_gc> *ctor_vec = make_tree_vector_single (ctor); + releasing_vec ctor_vec (make_tree_vector_single (ctor)); ctor = build_special_member_call (NULL_TREE, complete_ctor_identifier, &ctor_vec, type, flags, complain); - release_tree_vector (ctor_vec); } if (ctor) return build_cplus_new (type, ctor, complain); @@ -1001,7 +1023,7 @@ tree call = expr; if (TREE_CODE (expr) == TARGET_EXPR) call = TARGET_EXPR_INITIAL (expr); - location_t loc = cp_expr_loc_or_loc (call, input_location); + location_t loc = cp_expr_loc_or_input_loc (call); tree callee = cp_get_callee (call); if (!callee) return; @@ -1014,22 +1036,41 @@ tree rettype = TREE_TYPE (type); tree fn = cp_get_fndecl_from_callee (callee); + tree attr; if (implicit != ICV_CAST && fn - && lookup_attribute ("nodiscard", DECL_ATTRIBUTES (fn))) + && (attr = lookup_attribute ("nodiscard", DECL_ATTRIBUTES (fn)))) { + escaped_string msg; + tree args = TREE_VALUE (attr); + if (args) + msg.escape (TREE_STRING_POINTER (TREE_VALUE (args))); + const char *format + = (msg + ? G_("ignoring return value of %qD, " + "declared with attribute %<nodiscard%>: %<%s%>") + : G_("ignoring return value of %qD, " + "declared with attribute %<nodiscard%>%s")); + const char *raw_msg = msg ? (const char *) msg : ""; auto_diagnostic_group d; - if (warning_at (loc, OPT_Wunused_result, - "ignoring return value of %qD, " - "declared with attribute nodiscard", fn)) + if (warning_at (loc, OPT_Wunused_result, format, fn, raw_msg)) inform (DECL_SOURCE_LOCATION (fn), "declared here"); } else if (implicit != ICV_CAST - && lookup_attribute ("nodiscard", TYPE_ATTRIBUTES (rettype))) + && (attr = lookup_attribute ("nodiscard", TYPE_ATTRIBUTES (rettype)))) { + escaped_string msg; + tree args = TREE_VALUE (attr); + if (args) + msg.escape (TREE_STRING_POINTER (TREE_VALUE (args))); + const char *format + = (msg + ? G_("ignoring returned value of type %qT, " + "declared with attribute %<nodiscard%>: %<%s%>") + : G_("ignoring returned value of type %qT, " + "declared with attribute %<nodiscard%>%s")); + const char *raw_msg = msg ? (const char *) msg : ""; auto_diagnostic_group d; - if (warning_at (loc, OPT_Wunused_result, - "ignoring returned value of type %qT, " - "declared with attribute nodiscard", rettype)) + if (warning_at (loc, OPT_Wunused_result, format, rettype, raw_msg)) { if (fn) inform (DECL_SOURCE_LOCATION (fn), @@ -1048,14 +1089,14 @@ auto_diagnostic_group d; if (warning_at (loc, OPT_Wunused_result, "ignoring return value of %qD, " - "declared with attribute warn_unused_result", + "declared with attribute %<warn_unused_result%>", fn)) inform (DECL_SOURCE_LOCATION (fn), "declared here"); } else warning_at (loc, OPT_Wunused_result, "ignoring return value of function " - "declared with attribute warn_unused_result"); + "declared with attribute %<warn_unused_result%>"); } } @@ -1081,7 +1122,7 @@ tree convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) { - location_t loc = cp_expr_loc_or_loc (expr, input_location); + location_t loc = cp_expr_loc_or_input_loc (expr); if (expr == error_mark_node || TREE_TYPE (expr) == error_mark_node) @@ -1104,6 +1145,12 @@ error_at (loc, "pseudo-destructor is not called"); return error_mark_node; } + + /* Explicitly evaluate void-converted concept checks since their + satisfaction may produce ill-formed programs. */ + if (concept_check_p (expr)) + expr = evaluate_concept_check (expr, tf_warning_or_error); + if (VOID_TYPE_P (TREE_TYPE (expr))) return expr; switch (TREE_CODE (expr)) @@ -1161,7 +1208,18 @@ break; case CALL_EXPR: /* We have a special meaning for volatile void fn(). */ - maybe_warn_nodiscard (expr, implicit); + /* cdtors may return this or void, depending on + targetm.cxx.cdtor_returns_this, but this shouldn't affect our + decisions here: neither nodiscard warnings (nodiscard cdtors + are nonsensical), nor should any constexpr or template + instantiations be affected by an ABI property that is, or at + least ought to be transparent to the language. */ + if (tree fn = cp_get_callee_fndecl_nofold (expr)) + if (DECL_DESTRUCTOR_P (fn)) + return expr; + + if (complain & tf_warning) + maybe_warn_nodiscard (expr, implicit); break; case INDIRECT_REF: @@ -1317,7 +1375,8 @@ && !is_reference) warning_at (loc, OPT_Wunused_value, "value computed is not used"); expr = TREE_OPERAND (expr, 0); - if (TREE_CODE (expr) == CALL_EXPR) + if (TREE_CODE (expr) == CALL_EXPR + && (complain & tf_warning)) maybe_warn_nodiscard (expr, implicit); } @@ -1395,7 +1454,8 @@ AGGR_INIT_EXPR_ARGP (init)); } } - maybe_warn_nodiscard (expr, implicit); + if (complain & tf_warning) + maybe_warn_nodiscard (expr, implicit); break; default:; @@ -1496,7 +1556,8 @@ if (implicit != ICV_CAST && warn_unused_value && !TREE_NO_WARNING (expr) - && !processing_template_decl) + && !processing_template_decl + && !cp_unevaluated_operand) { /* The middle end does not warn about expressions that have been explicitly cast to void, so we must do so here. */ @@ -1679,7 +1740,7 @@ && (desires & WANT_INT) && !(desires & WANT_NULL)) { - source_location loc = + location_t loc = expansion_point_location_if_in_system_header (input_location); warning_at (loc, OPT_Wconversion_null, @@ -1712,8 +1773,11 @@ tf_warning_or_error) : NULL_TREE; + case VECTOR_TYPE: + if (!gnu_vector_type_p (basetype)) + return NULL_TREE; + /* FALLTHROUGH */ case COMPLEX_TYPE: - case VECTOR_TYPE: if ((desires & WANT_VECTOR_OR_COMPLEX) == 0) return NULL_TREE; switch (TREE_CODE (TREE_TYPE (basetype))) @@ -1798,7 +1862,7 @@ if (TREE_CODE (cand) == TEMPLATE_DECL) { if (complain) - error ("default type conversion can't deduce template" + error ("default type conversion cannot deduce template" " argument for %qD", cand); return error_mark_node; } @@ -1863,6 +1927,7 @@ wider. Scoped enums don't promote, but pretend they do for backward ABI bug compatibility wrt varargs. */ else if (TREE_CODE (type) == ENUMERAL_TYPE + || type == char8_type_node || type == char16_type_node || type == char32_type_node || type == wchar_type_node) @@ -1897,8 +1962,8 @@ { if (abi_version_crosses (6) && TYPE_MODE (prom) != TYPE_MODE (type)) - warning (OPT_Wabi, "scoped enum %qT passed through ... as " - "%qT before -fabi-version=6, %qT after", + warning (OPT_Wabi, "scoped enum %qT passed through %<...%> as " + "%qT before %<-fabi-version=6%>, %qT after", type, prom, ENUM_UNDERLYING_TYPE (type)); if (!abi_version_at_least (6)) type = prom; @@ -1971,8 +2036,7 @@ bool tx_safe_fn_type_p (tree t) { - if (TREE_CODE (t) != FUNCTION_TYPE - && TREE_CODE (t) != METHOD_TYPE) + if (!FUNC_OR_METHOD_TYPE_P (t)) return false; return !!lookup_attribute ("transaction_safe", TYPE_ATTRIBUTES (t)); }