X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Ftypeck.c;h=a23e27491d8c8056290d6504bf3b78d605b51ce9;hb=2b6ed700ac98f9851deaa6abac003d469920a334;hp=019c51eed856dd4f4e1cdc2baeb71560e85b31d9;hpb=1f3a51d65eff45f64b58800db5fe253d68771664;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 019c51eed85..a23e27491d8 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1,6 +1,6 @@ /* Build expressions with type checking for C++ compiler. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) @@ -34,12 +34,12 @@ along with GCC; see the file COPYING3. If not see #include "cp-tree.h" #include "flags.h" #include "output.h" -#include "toplev.h" #include "diagnostic.h" #include "intl.h" #include "target.h" #include "convert.h" #include "c-family/c-common.h" +#include "c-family/c-objc.h" #include "params.h" static tree pfn_from_ptrmemfunc (tree); @@ -64,11 +64,11 @@ static int convert_arguments (tree, VEC(tree,gc) **, tree, int, /* Do `exp = require_complete_type (exp);' to make sure exp does not have an incomplete type. (That includes void types.) - Returns the error_mark_node if the VALUE does not have + Returns error_mark_node if the VALUE does not have complete type when this function returns. */ tree -require_complete_type (tree value) +require_complete_type_sfinae (tree value, tsubst_flags_t complain) { tree type; @@ -87,12 +87,18 @@ require_complete_type (tree value) if (COMPLETE_TYPE_P (type)) return value; - if (complete_type_or_else (type, value)) + if (complete_type_or_maybe_complain (type, value, complain)) return value; else return error_mark_node; } +tree +require_complete_type (tree value) +{ + return require_complete_type_sfinae (value, tf_warning_or_error); +} + /* Try to complete TYPE, if it is incomplete. For example, if TYPE is a template instantiation, do the instantiation. Returns TYPE, whether or not it could be completed, unless something goes @@ -437,6 +443,35 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2) return cp_common_type (t1, t2); } +static void +composite_pointer_error (diagnostic_t kind, tree t1, tree t2, + composite_pointer_operation operation) +{ + switch (operation) + { + case CPO_COMPARISON: + emit_diagnostic (kind, input_location, 0, + "comparison between " + "distinct pointer types %qT and %qT lacks a cast", + t1, t2); + break; + case CPO_CONVERSION: + emit_diagnostic (kind, input_location, 0, + "conversion between " + "distinct pointer types %qT and %qT lacks a cast", + t1, t2); + break; + case CPO_CONDITIONAL_EXPR: + emit_diagnostic (kind, input_location, 0, + "conditional expression between " + "distinct pointer types %qT and %qT lacks a cast", + t1, t2); + break; + default: + gcc_unreachable (); + } +} + /* Subroutine of composite_pointer_type to implement the recursive case. See that function for documentation of the parameters. */ @@ -475,33 +510,18 @@ composite_pointer_type_r (tree t1, tree t2, && TREE_CODE (pointee2) == POINTER_TYPE) || (TYPE_PTR_TO_MEMBER_P (pointee1) && TYPE_PTR_TO_MEMBER_P (pointee2))) - result_type = composite_pointer_type_r (pointee1, pointee2, operation, - complain); + { + result_type = composite_pointer_type_r (pointee1, pointee2, operation, + complain); + if (result_type == error_mark_node) + return error_mark_node; + } else { if (complain & tf_error) - { - switch (operation) - { - case CPO_COMPARISON: - permerror (input_location, "comparison between " - "distinct pointer types %qT and %qT lacks a cast", - t1, t2); - break; - case CPO_CONVERSION: - permerror (input_location, "conversion between " - "distinct pointer types %qT and %qT lacks a cast", - t1, t2); - break; - case CPO_CONDITIONAL_EXPR: - permerror (input_location, "conditional expression between " - "distinct pointer types %qT and %qT lacks a cast", - t1, t2); - break; - default: - gcc_unreachable (); - } - } + composite_pointer_error (DK_PERMERROR, t1, t2, operation); + else + return error_mark_node; result_type = void_type_node; } result_type = cp_build_qualified_type (result_type, @@ -512,30 +532,13 @@ composite_pointer_type_r (tree t1, tree t2, if (TYPE_PTR_TO_MEMBER_P (t1)) { if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1), - TYPE_PTRMEM_CLASS_TYPE (t2)) - && (complain & tf_error)) - { - switch (operation) - { - case CPO_COMPARISON: - permerror (input_location, "comparison between " - "distinct pointer types %qT and %qT lacks a cast", - t1, t2); - break; - case CPO_CONVERSION: - permerror (input_location, "conversion between " - "distinct pointer types %qT and %qT lacks a cast", - t1, t2); - break; - case CPO_CONDITIONAL_EXPR: - permerror (input_location, "conditional expression between " - "distinct pointer types %qT and %qT lacks a cast", - t1, t2); - break; - default: - gcc_unreachable (); - } - } + TYPE_PTRMEM_CLASS_TYPE (t2))) + { + if (complain & tf_error) + composite_pointer_error (DK_PERMERROR, t1, t2, operation); + else + return error_mark_node; + } result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1), result_type); } @@ -632,8 +635,8 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2, if (c_dialect_objc () && TREE_CODE (t1) == POINTER_TYPE && TREE_CODE (t2) == POINTER_TYPE) { - if (objc_compare_types (t1, t2, -3, NULL_TREE)) - return t1; + if (objc_have_common_type (t1, t2, -3, NULL_TREE)) + return objc_common_type (t1, t2); } /* [expr.eq] permits the application of a pointer conversion to @@ -656,23 +659,7 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2, else { if (complain & tf_error) - switch (operation) - { - case CPO_COMPARISON: - error ("comparison between distinct " - "pointer types %qT and %qT lacks a cast", t1, t2); - break; - case CPO_CONVERSION: - error ("conversion between distinct " - "pointer types %qT and %qT lacks a cast", t1, t2); - break; - case CPO_CONDITIONAL_EXPR: - error ("conditional expression between distinct " - "pointer types %qT and %qT lacks a cast", t1, t2); - break; - default: - gcc_unreachable (); - } + composite_pointer_error (DK_ERROR, t1, t2, operation); return error_mark_node; } } @@ -847,7 +834,8 @@ merge_types (tree t1, tree t2) gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2)); rval = apply_memfn_quals (rval, type_memfn_quals (t1)); raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1), - TYPE_RAISES_EXCEPTIONS (t2)); + TYPE_RAISES_EXCEPTIONS (t2), + NULL_TREE); t1 = build_exception_variant (rval, raises); break; } @@ -856,9 +844,10 @@ merge_types (tree t1, tree t2) { /* Get this value the long way, since TYPE_METHOD_BASETYPE is just the main variant of this. */ - tree basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2))); + tree basetype = class_of_this_parm (t2); tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1), - TYPE_RAISES_EXCEPTIONS (t2)); + TYPE_RAISES_EXCEPTIONS (t2), + NULL_TREE); tree t3; /* If this was a member function type, get back to the @@ -1008,14 +997,14 @@ comp_except_specs (const_tree t1, const_tree t2, int exact) /* First handle noexcept. */ if (exact < ce_exact) { - /* noexcept(false) is compatible with any throwing dynamic-exc-spec + /* noexcept(false) is compatible with no exception-specification, and stricter than any spec. */ if (t1 == noexcept_false_spec) - return !nothrow_spec_p (t2) || exact == ce_derived; - /* Even a derived noexcept(false) is compatible with a throwing - dynamic spec. */ + return t2 == NULL_TREE || exact == ce_derived; + /* Even a derived noexcept(false) is compatible with no + exception-specification. */ if (t2 == noexcept_false_spec) - return !nothrow_spec_p (t1); + return t1 == NULL_TREE; /* Otherwise, if we aren't looking for an exact match, noexcept is equivalent to throw(). */ @@ -1137,120 +1126,30 @@ comp_array_types (const_tree t1, const_tree t2, bool allow_redeclaration) static bool comp_template_parms_position (tree t1, tree t2) { + tree index1, index2; gcc_assert (t1 && t2 && TREE_CODE (t1) == TREE_CODE (t2) && (TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (t1) == TEMPLATE_TYPE_PARM)); - if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2) - || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2) - || (TEMPLATE_TYPE_PARAMETER_PACK (t1) - != TEMPLATE_TYPE_PARAMETER_PACK (t2))) - return false; - - return true; -} - -/* Subroutine of incompatible_dependent_types_p. - Return the template parameter of the dependent type T. - If T is a typedef, return the template parameters of - the _decl_ of the typedef. T must be a dependent type. */ - -static tree -get_template_parms_of_dependent_type (tree t) -{ - tree tinfo = NULL_TREE, tparms = NULL_TREE; - - /* First, try the obvious case of getting the - template info from T itself. */ - if ((tinfo = get_template_info (t))) - ; - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) - return TEMPLATE_TYPE_PARM_SIBLING_PARMS (t); - else if (typedef_variant_p (t) - && !NAMESPACE_SCOPE_P (TYPE_NAME (t))) - tinfo = get_template_info (DECL_CONTEXT (TYPE_NAME (t))); - /* If T is a TYPENAME_TYPE which context is a template type - parameter, get the template parameters from that context. */ - else if (TYPE_CONTEXT (t) - && TREE_CODE (TYPE_CONTEXT (t)) == TEMPLATE_TYPE_PARM) - return TEMPLATE_TYPE_PARM_SIBLING_PARMS (TYPE_CONTEXT (t)); - else if (TYPE_CONTEXT (t) - && !NAMESPACE_SCOPE_P (t)) - tinfo = get_template_info (TYPE_CONTEXT (t)); - - if (tinfo) - tparms = DECL_TEMPLATE_PARMS (TI_TEMPLATE (tinfo)); - - return tparms; -} - -/* Subroutine of structural_comptypes. - Compare the dependent types T1 and T2. - Return TRUE if we are sure they can't be equal, FALSE otherwise. - The whole point of this function is to support cases where either T1 or - T2 is a typedef. In those cases, we need to compare the template parameters - of the _decl_ of the typedef. If those don't match then we know T1 - and T2 cannot be equal. */ + index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1)); + index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2)); -static bool -incompatible_dependent_types_p (tree t1, tree t2) -{ - tree tparms1 = NULL_TREE, tparms2 = NULL_TREE; - bool t1_typedef_variant_p, t2_typedef_variant_p; - - if (!uses_template_parms (t1) || !uses_template_parms (t2)) + /* If T1 and T2 belong to template parm lists of different size, + let's assume they are different. */ + if (TEMPLATE_PARM_NUM_SIBLINGS (index1) + != TEMPLATE_PARM_NUM_SIBLINGS (index2)) return false; - if (TREE_CODE (t1) == TEMPLATE_TYPE_PARM) - { - /* If T1 and T2 don't have the same relative position in their - template parameters set, they can't be equal. */ - if (!comp_template_parms_position (t1, t2)) - return true; - } - - t1_typedef_variant_p = typedef_variant_p (t1); - t2_typedef_variant_p = typedef_variant_p (t2); - - /* Either T1 or T2 must be a typedef. */ - if (!t1_typedef_variant_p && !t2_typedef_variant_p) - return false; - - if (!t1_typedef_variant_p || !t2_typedef_variant_p) - /* Either T1 or T2 is not a typedef so we cannot compare the - template parms of the typedefs of T1 and T2. - At this point, if the main variant type of T1 and T2 are equal - it means the two types can't be incompatible, from the perspective - of this function. */ - if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) - return false; - - /* So if we reach this point, it means either T1 or T2 is a typedef variant. - Let's compare their template parameters. */ - - tparms1 = get_template_parms_of_dependent_type (t1); - tparms2 = get_template_parms_of_dependent_type (t2); - - /* If T2 is a template type parm and if we could not get the template - parms it belongs to, that means we have not finished parsing the - full set of template parameters of the template declaration it - belongs to yet. If we could get the template parms T1 belongs to, - that mostly means T1 and T2 belongs to templates that are - different and incompatible. */ - if (TREE_CODE (t1) == TEMPLATE_TYPE_PARM - && (tparms1 == NULL_TREE || tparms2 == NULL_TREE) - && tparms1 != tparms2) - return true; - - if (tparms1 == NULL_TREE - || tparms2 == NULL_TREE - || tparms1 == tparms2) + /* Then compare their relative position. */ + if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2) + || TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2) + || (TEMPLATE_PARM_PARAMETER_PACK (index1) + != TEMPLATE_PARM_PARAMETER_PACK (index2))) return false; - /* And now compare the mighty template parms! */ - return !comp_template_parms (tparms1, tparms2); + return true; } /* Subroutine in comptypes. */ @@ -1295,12 +1194,6 @@ structural_comptypes (tree t1, tree t2, int strict) if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2)) return false; - /* If T1 and T2 are dependent typedefs then check upfront that - the template parameters of their typedef DECLs match before - going down checking their subtypes. */ - if (incompatible_dependent_types_p (t1, t2)) - return false; - /* Allow for two different type nodes which have essentially the same definition. Note that we already checked for equality of the type qualifiers (just above). */ @@ -1401,15 +1294,19 @@ structural_comptypes (tree t1, tree t2, int strict) break; case TEMPLATE_TYPE_PARM: - /* If incompatible_dependent_types_p called earlier didn't decide - T1 and T2 were different, they might be equal. */ + /* If T1 and T2 don't have the same relative position in their + template parameters set, they can't be equal. */ + if (!comp_template_parms_position (t1, t2)) + return false; break; case TYPENAME_TYPE: if (!cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1), TYPENAME_TYPE_FULLNAME (t2))) return false; - if (!same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2))) + /* Qualifiers don't matter on scopes. */ + if (!same_type_ignoring_top_level_qualifiers_p (TYPE_CONTEXT (t1), + TYPE_CONTEXT (t2))) return false; break; @@ -1432,21 +1329,27 @@ structural_comptypes (tree t1, tree t2, int strict) break; case TYPE_PACK_EXPANSION: - return same_type_p (PACK_EXPANSION_PATTERN (t1), - PACK_EXPANSION_PATTERN (t2)); + return (same_type_p (PACK_EXPANSION_PATTERN (t1), + PACK_EXPANSION_PATTERN (t2)) + && comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1), + PACK_EXPANSION_EXTRA_ARGS (t2))); case DECLTYPE_TYPE: if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t1) != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2) || (DECLTYPE_FOR_LAMBDA_CAPTURE (t1) != DECLTYPE_FOR_LAMBDA_CAPTURE (t2)) - || (DECLTYPE_FOR_LAMBDA_RETURN (t1) - != DECLTYPE_FOR_LAMBDA_RETURN (t2)) + || (DECLTYPE_FOR_LAMBDA_PROXY (t1) + != DECLTYPE_FOR_LAMBDA_PROXY (t2)) || !cp_tree_equal (DECLTYPE_TYPE_EXPR (t1), DECLTYPE_TYPE_EXPR (t2))) return false; break; + case UNDERLYING_TYPE: + return same_type_p (UNDERLYING_TYPE_TYPE (t1), + UNDERLYING_TYPE_TYPE (t2)); + default: return false; } @@ -1454,7 +1357,7 @@ structural_comptypes (tree t1, tree t2, int strict) /* If we get here, we know that from a target independent POV the types are the same. Make sure the target attributes are also the same. */ - return targetm.comp_type_attributes (t1, t2); + return comp_type_attributes (t1, t2); } /* Return true if T1 and T2 are related as allowed by STRICT. STRICT @@ -1884,10 +1787,13 @@ tree unlowered_expr_type (const_tree exp) { tree type; + tree etype = TREE_TYPE (exp); type = is_bitfield_expr_with_lowered_type (exp); - if (!type) - type = TREE_TYPE (exp); + if (type) + type = cp_build_qualified_type (type, cp_type_quals (etype)); + else + type = etype; return type; } @@ -1924,7 +1830,10 @@ decay_conversion (tree exp) return error_mark_node; } - exp = decl_constant_value (exp); + /* FIXME remove? at least need to remember that this isn't really a + constant expression if EXP isn't decl_constant_var_p, like with + C_MAYBE_CONST_EXPR. */ + exp = decl_constant_value_safe (exp); if (error_operand_p (exp)) return error_mark_node; @@ -1942,7 +1851,7 @@ decay_conversion (tree exp) if (invalid_nonstatic_memfn_p (exp, tf_warning_or_error)) return error_mark_node; if (code == FUNCTION_TYPE || is_overloaded_fn (exp)) - return cp_build_unary_op (ADDR_EXPR, exp, 0, tf_warning_or_error); + return cp_build_addr_expr (exp, tf_warning_or_error); if (code == ARRAY_TYPE) { tree adr; @@ -1977,7 +1886,7 @@ decay_conversion (tree exp) } /* This way is better for a COMPONENT_REF since it can simplify the offset for a component. */ - adr = cp_build_unary_op (ADDR_EXPR, exp, 1, tf_warning_or_error); + adr = cp_build_addr_expr (exp, tf_warning_or_error); return cp_convert (ptrtype, adr); } @@ -2054,6 +1963,9 @@ perform_integral_promotions (tree expr) if (!type || TREE_CODE (type) != ENUMERAL_TYPE) type = TREE_TYPE (expr); gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type)); + /* Scoped enums don't promote. */ + if (SCOPED_ENUM_P (type)) + return expr; promoted_type = type_promotes_to (type); if (type != promoted_type) expr = cp_convert (promoted_type, expr); @@ -2133,7 +2045,7 @@ rationalize_conditional_expr (enum tree_code code, tree t, ? LE_EXPR : GE_EXPR), op0, TREE_CODE (op0), op1, TREE_CODE (op1), - /*overloaded_p=*/NULL, + /*overload=*/NULL, complain), cp_build_unary_op (code, op0, 0, complain), cp_build_unary_op (code, op1, 0, complain), @@ -2205,6 +2117,7 @@ build_class_member_access_expr (tree object, tree member, tree object_type; tree member_scope; tree result = NULL_TREE; + tree using_decl = NULL_TREE; if (error_operand_p (object) || error_operand_p (member)) return error_mark_node; @@ -2222,8 +2135,16 @@ build_class_member_access_expr (tree object, tree member, if (!CLASS_TYPE_P (object_type)) { if (complain & tf_error) - error ("request for member %qD in %qE, which is of non-class type %qT", - member, object, object_type); + { + if (POINTER_TYPE_P (object_type) + && CLASS_TYPE_P (TREE_TYPE (object_type))) + error ("request for member %qD in %qE, which is of pointer " + "type %qT (maybe you meant to use %<->%> ?)", + member, object, object_type); + else + error ("request for member %qD in %qE, which is of non-class " + "type %qT", member, object, object_type); + } return error_mark_node; } @@ -2317,7 +2238,7 @@ build_class_member_access_expr (tree object, tree member, /* Convert to the base. */ object = build_base_path (PLUS_EXPR, object, binfo, - /*nonnull=*/1); + /*nonnull=*/1, complain); /* If we found the base successfully then we should be able to convert to it successfully. */ gcc_assert (object != error_mark_node); @@ -2425,6 +2346,11 @@ build_class_member_access_expr (tree object, tree member, result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result); } + else if ((using_decl = strip_using_decl (member)) != member) + result = build_class_member_access_expr (object, + using_decl, + access_path, preserve_reference, + complain); else { if (complain & tf_error) @@ -2479,7 +2405,8 @@ lookup_destructor (tree object, tree scope, tree dtor_name) return error_mark_node; } expr = lookup_member (dtor_type, complete_dtor_identifier, - /*protect=*/1, /*want_type=*/false); + /*protect=*/1, /*want_type=*/false, + tf_warning_or_error); expr = (adjust_result_of_qualified_name_lookup (expr, dtor_type, object_type)); return expr; @@ -2587,7 +2514,11 @@ finish_class_member_access_expr (tree object, tree name, bool template_p, return build_min_nt (COMPONENT_REF, object, name, NULL_TREE); object = build_non_dependent_expr (object); } - + else if (c_dialect_objc () + && TREE_CODE (name) == IDENTIFIER_NODE + && (expr = objc_maybe_build_component_ref (object, name))) + return expr; + /* [expr.ref] The type of the first expression shall be "class object" (of a @@ -2598,8 +2529,16 @@ finish_class_member_access_expr (tree object, tree name, bool template_p, if (!CLASS_TYPE_P (object_type)) { if (complain & tf_error) - error ("request for member %qD in %qE, which is of non-class type %qT", - name, object, object_type); + { + if (POINTER_TYPE_P (object_type) + && CLASS_TYPE_P (TREE_TYPE (object_type))) + error ("request for member %qD in %qE, which is of pointer " + "type %qT (maybe you meant to use %<->%> ?)", + name, object, object_type); + else + error ("request for member %qD in %qE, which is of non-class " + "type %qT", name, object, object_type); + } return error_mark_node; } @@ -2677,11 +2616,13 @@ finish_class_member_access_expr (tree object, tree name, bool template_p, { /* Look up the member. */ member = lookup_member (access_path, name, /*protect=*/1, - /*want_type=*/false); + /*want_type=*/false, complain); if (member == NULL_TREE) { if (complain & tf_error) - error ("%qD has no member named %qE", object_type, name); + error ("%qD has no member named %qE", + TREE_CODE (access_path) == TREE_BINFO + ? TREE_TYPE (access_path) : object_type, name); return error_mark_node; } if (member == error_mark_node) @@ -2749,7 +2690,7 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name) ptrmem_type = TREE_TYPE (ptrmem); gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type)); member = lookup_member (ptrmem_type, member_name, /*protect=*/0, - /*want_type=*/false); + /*want_type=*/false, tf_warning_or_error); member_type = cp_build_qualified_type (TREE_TYPE (member), cp_type_quals (ptrmem_type)); return fold_build3_loc (input_location, @@ -2773,8 +2714,7 @@ build_x_indirect_ref (tree expr, ref_operator errorstring, if (processing_template_decl) { - /* Retain the type if we know the operand is a pointer so that - describable_type doesn't make auto deduction break. */ + /* Retain the type if we know the operand is a pointer. */ if (TREE_TYPE (expr) && POINTER_TYPE_P (TREE_TYPE (expr))) return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr); if (type_dependent_expression_p (expr)) @@ -2783,7 +2723,7 @@ build_x_indirect_ref (tree expr, ref_operator errorstring, } rval = build_new_op (INDIRECT_REF, LOOKUP_NORMAL, expr, NULL_TREE, - NULL_TREE, /*overloaded_p=*/NULL, complain); + NULL_TREE, /*overload=*/NULL, complain); if (!rval) rval = cp_build_indirect_ref (expr, errorstring, complain); @@ -2795,7 +2735,7 @@ build_x_indirect_ref (tree expr, ref_operator errorstring, /* Helper function called from c-common. */ tree -build_indirect_ref (location_t loc __attribute__ ((__unused__)), +build_indirect_ref (location_t loc ATTRIBUTE_UNUSED, tree ptr, ref_operator errorstring) { return cp_build_indirect_ref (ptr, errorstring, tf_warning_or_error); @@ -2885,23 +2825,8 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring, gcc_unreachable (); } else if (pointer != error_mark_node) - switch (errorstring) - { - case RO_NULL: - error ("invalid type argument"); - break; - case RO_ARRAY_INDEXING: - error ("invalid type argument of array indexing"); - break; - case RO_UNARY_STAR: - error ("invalid type argument of unary %<*%>"); - break; - case RO_IMPLICIT_CONVERSION: - error ("invalid type argument of implicit conversion"); - break; - default: - gcc_unreachable (); - } + invalid_indirection_error (input_location, type, errorstring); + return error_mark_node; } @@ -3039,7 +2964,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx, |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array)); TREE_THIS_VOLATILE (rval) |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array)); - ret = require_complete_type (fold_if_not_in_template (rval)); + ret = require_complete_type_sfinae (fold_if_not_in_template (rval), + complain); protected_set_expr_location (ret, loc); return ret; } @@ -3180,13 +3106,12 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)), basetype, ba_check, NULL); instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, - 1); + 1, tf_warning_or_error); if (instance_ptr == error_mark_node) return error_mark_node; } /* ...and then the delta in the PMF. */ - instance_ptr = build2 (POINTER_PLUS_EXPR, TREE_TYPE (instance_ptr), - instance_ptr, fold_convert (sizetype, delta)); + instance_ptr = fold_build_pointer_plus (instance_ptr, delta); /* Hand back the adjusted 'this' argument to our caller. */ *instance_ptrptr = instance_ptr; @@ -3201,9 +3126,7 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) TREE_NO_WARNING (vtbl) = 1; /* Finally, extract the function pointer from the vtable. */ - e2 = fold_build2_loc (input_location, - POINTER_PLUS_EXPR, TREE_TYPE (vtbl), vtbl, - fold_convert (sizetype, idx)); + e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx); e2 = cp_build_indirect_ref (e2, RO_NULL, tf_warning_or_error); TREE_CONSTANT (e2) = 1; @@ -3211,8 +3134,7 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) vtable entry is treated as a function pointer. */ if (TARGET_VTABLE_USES_DESCRIPTORS) e2 = build1 (NOP_EXPR, TREE_TYPE (e2), - cp_build_unary_op (ADDR_EXPR, e2, /*noconvert=*/1, - tf_warning_or_error)); + cp_build_addr_expr (e2, tf_warning_or_error)); e2 = fold_convert (TREE_TYPE (e3), e2); e1 = build_conditional_expr (e1, e2, e3, tf_warning_or_error); @@ -3383,8 +3305,7 @@ cp_build_function_call_vec (tree function, VEC(tree,gc) **params, /* Check for errors in format strings and inappropriately null parameters. */ - check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray, - parm_types); + check_function_arguments (fntype, nargs, argarray); ret = build_cxx_call (function, nargs, argarray); @@ -3543,7 +3464,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl, /* Don't do ellipsis conversion for __built_in_constant_p as this will result in spurious errors for non-trivial types. */ - val = require_complete_type (val); + val = require_complete_type_sfinae (val, complain); else val = convert_arg_to_ellipsis (val); @@ -3607,7 +3528,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl, tree build_x_binary_op (enum tree_code code, tree arg1, enum tree_code arg1_code, - tree arg2, enum tree_code arg2_code, bool *overloaded_p, + tree arg2, enum tree_code arg2_code, tree *overload, tsubst_flags_t complain) { tree orig_arg1; @@ -3630,7 +3551,7 @@ build_x_binary_op (enum tree_code code, tree arg1, enum tree_code arg1_code, expr = build_m_component_ref (arg1, arg2); else expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE, - overloaded_p, complain); + overload, complain); /* Check for cases such as x+y<", + base, name); + else + permerror (input_location, "ISO C++ forbids taking the address of a bound member" + " function to form a pointer to member function." + " Say %<&%T::%D%>", + base, name); + } + arg = build_offset_ref (base, fn, /*address_p=*/true); + } + + /* Uninstantiated types are all functions. Taking the + address of a function is a no-op, so just return the + argument. */ + if (type_unknown_p (arg)) + return build1 (ADDR_EXPR, unknown_type_node, arg); + + if (TREE_CODE (arg) == OFFSET_REF) + /* We want a pointer to member; bypass all the code for actually taking + the address of something. */ + goto offset_ref; + + /* Anything not already handled and not a true memory reference + is an error. */ + if (TREE_CODE (argtype) != FUNCTION_TYPE + && TREE_CODE (argtype) != METHOD_TYPE) + { + cp_lvalue_kind kind = lvalue_kind (arg); + if (kind == clk_none) + { + if (complain & tf_error) + lvalue_error (input_location, lv_addressof); + return error_mark_node; + } + if (strict_lvalue && (kind & (clk_rvalueref|clk_class))) + { + if (!(complain & tf_error)) + return error_mark_node; + if (kind & clk_class) + /* Make this a permerror because we used to accept it. */ + permerror (input_location, "taking address of temporary"); + else + error ("taking address of xvalue (rvalue reference)"); + } + } + + if (TREE_CODE (argtype) == REFERENCE_TYPE) + { + tree type = build_pointer_type (TREE_TYPE (argtype)); + arg = build1 (CONVERT_EXPR, type, arg); + return arg; + } + else if (pedantic && DECL_MAIN_P (arg)) + { + /* ARM $3.4 */ + /* Apparently a lot of autoconf scripts for C++ packages do this, + so only complain if -pedantic. */ + if (complain & (flag_pedantic_errors ? tf_error : tf_warning)) + pedwarn (input_location, OPT_pedantic, + "ISO C++ forbids taking address of function %<::main%>"); + else if (flag_pedantic_errors) + return error_mark_node; + } + + /* Let &* cancel out to simplify resulting code. */ + if (TREE_CODE (arg) == INDIRECT_REF) + { + /* We don't need to have `current_class_ptr' wrapped in a + NON_LVALUE_EXPR node. */ + if (arg == current_class_ref) + return current_class_ptr; + + arg = TREE_OPERAND (arg, 0); + if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE) + { + tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg))); + arg = build1 (CONVERT_EXPR, type, arg); + } + else + /* Don't let this be an lvalue. */ + arg = rvalue (arg); + return arg; + } + + /* ??? Cope with user tricks that amount to offsetof. */ + if (TREE_CODE (argtype) != FUNCTION_TYPE + && TREE_CODE (argtype) != METHOD_TYPE + && argtype != unknown_type_node + && (val = get_base_address (arg)) + && COMPLETE_TYPE_P (TREE_TYPE (val)) + && TREE_CODE (val) == INDIRECT_REF + && TREE_CONSTANT (TREE_OPERAND (val, 0))) + { + tree type = build_pointer_type (argtype); + return fold_convert (type, fold_offsetof_1 (arg)); + } + + /* Handle complex lvalues (when permitted) + by reduction to simpler cases. */ + val = unary_complex_lvalue (ADDR_EXPR, arg); + if (val != 0) + return val; + + switch (TREE_CODE (arg)) + { + CASE_CONVERT: + case FLOAT_EXPR: + case FIX_TRUNC_EXPR: + /* Even if we're not being pedantic, we cannot allow this + extension when we're instantiating in a SFINAE + context. */ + if (! lvalue_p (arg) && complain == tf_none) + { + if (complain & tf_error) + permerror (input_location, "ISO C++ forbids taking the address of a cast to a non-lvalue expression"); + else + return error_mark_node; + } + break; + + case BASELINK: + arg = BASELINK_FUNCTIONS (arg); + /* Fall through. */ + + case OVERLOAD: + arg = OVL_CURRENT (arg); + break; + + case OFFSET_REF: + offset_ref: + /* Turn a reference to a non-static data member into a + pointer-to-member. */ + { + tree type; + tree t; + + gcc_assert (PTRMEM_OK_P (arg)); + + t = TREE_OPERAND (arg, 1); + if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE) + { + if (complain & tf_error) + error ("cannot create pointer to reference member %qD", t); + return error_mark_node; + } + + type = build_ptrmem_type (context_for_name_lookup (t), + TREE_TYPE (t)); + t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1)); + return t; + } + + default: + break; + } + + if (argtype != error_mark_node) + argtype = build_pointer_type (argtype); + + /* In a template, we are processing a non-dependent expression + so we can just form an ADDR_EXPR with the correct type. */ + if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF) + { + val = build_address (arg); + if (TREE_CODE (arg) == OFFSET_REF) + PTRMEM_OK_P (val) = PTRMEM_OK_P (arg); + } + else if (BASELINK_P (TREE_OPERAND (arg, 1))) + { + tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1)); + + /* We can only get here with a single static member + function. */ + gcc_assert (TREE_CODE (fn) == FUNCTION_DECL + && DECL_STATIC_FUNCTION_P (fn)); + mark_used (fn); + val = build_address (fn); + if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0))) + /* Do not lose object's side effects. */ + val = build2 (COMPOUND_EXPR, TREE_TYPE (val), + TREE_OPERAND (arg, 0), val); + } + else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1))) + { + if (complain & tf_error) + error ("attempt to take address of bit-field structure member %qD", + TREE_OPERAND (arg, 1)); + return error_mark_node; + } + else + { + tree object = TREE_OPERAND (arg, 0); + tree field = TREE_OPERAND (arg, 1); + gcc_assert (same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (object), decl_type_context (field))); + val = build_address (arg); + } + + if (TREE_CODE (argtype) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE) + { + build_ptrmemfunc_type (argtype); + val = build_ptrmemfunc (argtype, val, 0, + /*c_cast_p=*/false, + tf_warning_or_error); + } + + return val; +} + +/* Take the address of ARG if it has one, even if it's an rvalue. */ + +tree +cp_build_addr_expr (tree arg, tsubst_flags_t complain) +{ + return cp_build_addr_expr_1 (arg, 0, complain); +} + +/* Take the address of ARG, but only if it's an lvalue. */ + +tree +cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain) +{ + return cp_build_addr_expr_1 (arg, 1, complain); +} + /* C++: Must handle pointers to members. Perhaps type instantiation should be extended to handle conversion @@ -4902,26 +5124,12 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, break; case REALPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_REALPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - { - arg = build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg); - return fold_if_not_in_template (arg); - } - else - return arg; - case IMAGPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_IMAGPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - { - arg = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg); - return fold_if_not_in_template (arg); - } + arg = build_real_imag_expr (input_location, code, arg); + if (arg == error_mark_node) + return arg; else - return cp_convert (TREE_TYPE (arg), integer_zero_node); + return fold_if_not_in_template (arg); case PREINCREMENT_EXPR: case POSTINCREMENT_EXPR: @@ -4976,9 +5184,9 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, || TREE_READONLY (arg)) { if (complain & tf_error) - readonly_error (arg, ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? REK_INCREMENT : REK_DECREMENT)); + cxx_readonly_error (arg, ((code == PREINCREMENT_EXPR + || code == POSTINCREMENT_EXPR) + ? lv_increment : lv_decrement)); else return error_mark_node; } @@ -5037,6 +5245,13 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, inc = cp_convert (argtype, inc); + /* If 'arg' is an Objective-C PROPERTY_REF expression, then we + need to ask Objective-C to build the increment or decrement + expression for it. */ + if (objc_is_property_ref (arg)) + return objc_build_incr_expr_for_property_ref (input_location, code, + arg, inc); + /* Complain about anything else that is not a true lvalue. */ if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) @@ -5056,6 +5271,9 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, } val = boolean_increment (code, arg); } + else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) + /* An rvalue has no cv-qualifiers. */ + val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc); else val = build2 (code, TREE_TYPE (arg), arg, inc); @@ -5066,238 +5284,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, case ADDR_EXPR: /* Note that this operation never does default_conversion regardless of NOCONVERT. */ - - argtype = lvalue_type (arg); - - arg = mark_lvalue_use (arg); - - if (TREE_CODE (arg) == OFFSET_REF) - goto offset_ref; - - if (TREE_CODE (argtype) == REFERENCE_TYPE) - { - tree type = build_pointer_type (TREE_TYPE (argtype)); - arg = build1 (CONVERT_EXPR, type, arg); - return arg; - } - else if (pedantic && DECL_MAIN_P (arg)) - { - /* ARM $3.4 */ - /* Apparently a lot of autoconf scripts for C++ packages do this, - so only complain if -pedantic. */ - if (complain & (flag_pedantic_errors ? tf_error : tf_warning)) - pedwarn (input_location, OPT_pedantic, - "ISO C++ forbids taking address of function %<::main%>"); - else if (flag_pedantic_errors) - return error_mark_node; - } - - /* Let &* cancel out to simplify resulting code. */ - if (TREE_CODE (arg) == INDIRECT_REF) - { - /* We don't need to have `current_class_ptr' wrapped in a - NON_LVALUE_EXPR node. */ - if (arg == current_class_ref) - return current_class_ptr; - - arg = TREE_OPERAND (arg, 0); - if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE) - { - tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg))); - arg = build1 (CONVERT_EXPR, type, arg); - } - else - /* Don't let this be an lvalue. */ - arg = rvalue (arg); - return arg; - } - - /* ??? Cope with user tricks that amount to offsetof. */ - if (TREE_CODE (argtype) != FUNCTION_TYPE - && TREE_CODE (argtype) != METHOD_TYPE - && argtype != unknown_type_node - && (val = get_base_address (arg)) - && TREE_CODE (val) == INDIRECT_REF - && TREE_CONSTANT (TREE_OPERAND (val, 0))) - { - tree type = build_pointer_type (argtype); - tree op0 = fold_convert (type, TREE_OPERAND (val, 0)); - tree op1 = fold_convert (sizetype, fold_offsetof (arg, val)); - return fold_build2 (POINTER_PLUS_EXPR, type, op0, op1); - } - - /* Uninstantiated types are all functions. Taking the - address of a function is a no-op, so just return the - argument. */ - - gcc_assert (TREE_CODE (arg) != IDENTIFIER_NODE - || !IDENTIFIER_OPNAME_P (arg)); - - if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg) - && !really_overloaded_fn (TREE_OPERAND (arg, 1))) - { - /* They're trying to take the address of a unique non-static - member function. This is ill-formed (except in MS-land), - but let's try to DTRT. - Note: We only handle unique functions here because we don't - want to complain if there's a static overload; non-unique - cases will be handled by instantiate_type. But we need to - handle this case here to allow casts on the resulting PMF. - We could defer this in non-MS mode, but it's easier to give - a useful error here. */ - - /* Inside constant member functions, the `this' pointer - contains an extra const qualifier. TYPE_MAIN_VARIANT - is used here to remove this const from the diagnostics - and the created OFFSET_REF. */ - tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0))); - tree fn = get_first_fn (TREE_OPERAND (arg, 1)); - mark_used (fn); - - if (! flag_ms_extensions) - { - tree name = DECL_NAME (fn); - if (!(complain & tf_error)) - return error_mark_node; - else if (current_class_type - && TREE_OPERAND (arg, 0) == current_class_ref) - /* An expression like &memfn. */ - permerror (input_location, "ISO C++ forbids taking the address of an unqualified" - " or parenthesized non-static member function to form" - " a pointer to member function. Say %<&%T::%D%>", - base, name); - else - permerror (input_location, "ISO C++ forbids taking the address of a bound member" - " function to form a pointer to member function." - " Say %<&%T::%D%>", - base, name); - } - arg = build_offset_ref (base, fn, /*address_p=*/true); - } - - offset_ref: - if (type_unknown_p (arg)) - return build1 (ADDR_EXPR, unknown_type_node, arg); - - /* Handle complex lvalues (when permitted) - by reduction to simpler cases. */ - val = unary_complex_lvalue (code, arg); - if (val != 0) - return val; - - switch (TREE_CODE (arg)) - { - CASE_CONVERT: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - /* Even if we're not being pedantic, we cannot allow this - extension when we're instantiating in a SFINAE - context. */ - if (! lvalue_p (arg) && complain == tf_none) - { - if (complain & tf_error) - permerror (input_location, "ISO C++ forbids taking the address of a cast to a non-lvalue expression"); - else - return error_mark_node; - } - break; - - case BASELINK: - arg = BASELINK_FUNCTIONS (arg); - /* Fall through. */ - - case OVERLOAD: - arg = OVL_CURRENT (arg); - break; - - case OFFSET_REF: - /* Turn a reference to a non-static data member into a - pointer-to-member. */ - { - tree type; - tree t; - - if (!PTRMEM_OK_P (arg)) - return cp_build_unary_op (code, arg, 0, complain); - - t = TREE_OPERAND (arg, 1); - if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE) - { - if (complain & tf_error) - error ("cannot create pointer to reference member %qD", t); - return error_mark_node; - } - - type = build_ptrmem_type (context_for_name_lookup (t), - TREE_TYPE (t)); - t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1)); - return t; - } - - default: - break; - } - - /* Anything not already handled and not a true memory reference - is an error. */ - if (TREE_CODE (argtype) != FUNCTION_TYPE - && TREE_CODE (argtype) != METHOD_TYPE - && TREE_CODE (arg) != OFFSET_REF - && !lvalue_or_else (arg, lv_addressof, complain)) - return error_mark_node; - - if (argtype != error_mark_node) - argtype = build_pointer_type (argtype); - - /* In a template, we are processing a non-dependent expression - so we can just form an ADDR_EXPR with the correct type. */ - if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF) - { - val = build_address (arg); - if (TREE_CODE (arg) == OFFSET_REF) - PTRMEM_OK_P (val) = PTRMEM_OK_P (arg); - } - else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK) - { - tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1)); - - /* We can only get here with a single static member - function. */ - gcc_assert (TREE_CODE (fn) == FUNCTION_DECL - && DECL_STATIC_FUNCTION_P (fn)); - mark_used (fn); - val = build_address (fn); - if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0))) - /* Do not lose object's side effects. */ - val = build2 (COMPOUND_EXPR, TREE_TYPE (val), - TREE_OPERAND (arg, 0), val); - } - else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1))) - { - if (complain & tf_error) - error ("attempt to take address of bit-field structure member %qD", - TREE_OPERAND (arg, 1)); - return error_mark_node; - } - else - { - tree object = TREE_OPERAND (arg, 0); - tree field = TREE_OPERAND (arg, 1); - gcc_assert (same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (object), decl_type_context (field))); - val = build_address (arg); - } - - if (TREE_CODE (argtype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE) - { - build_ptrmemfunc_type (argtype); - val = build_ptrmemfunc (argtype, val, 0, - /*c_cast_p=*/false, - tf_warning_or_error); - } - - return val; + return cp_build_addr_expr (arg, complain); default: break; @@ -5402,7 +5389,7 @@ unary_complex_lvalue (enum tree_code code, tree arg) if (TREE_CODE (arg) == SAVE_EXPR) targ = arg; else - targ = build_cplus_new (TREE_TYPE (arg), arg); + targ = build_cplus_new (TREE_TYPE (arg), arg, tf_warning_or_error); return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ); } @@ -5455,7 +5442,6 @@ cxx_mark_addressable (tree exp) || DECL_EXTERNAL (x)); /* Fall through. */ - case CONST_DECL: case RESULT_DECL: if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x) && !DECL_ARTIFICIAL (x)) @@ -5473,6 +5459,7 @@ cxx_mark_addressable (tree exp) TREE_ADDRESSABLE (x) = 1; return true; + case CONST_DECL: case FUNCTION_DECL: TREE_ADDRESSABLE (x) = 1; return true; @@ -5520,8 +5507,16 @@ build_x_conditional_expr (tree ifexp, tree op1, tree op2, expr = build_conditional_expr (ifexp, op1, op2, complain); if (processing_template_decl && expr != error_mark_node) - return build_min_non_dep (COND_EXPR, expr, - orig_ifexp, orig_op1, orig_op2); + { + tree min = build_min_non_dep (COND_EXPR, expr, + orig_ifexp, orig_op1, orig_op2); + /* Remember that the result is an lvalue or xvalue. */ + if (lvalue_or_rvalue_with_address_p (expr) + && !lvalue_or_rvalue_with_address_p (min)) + TREE_TYPE (min) = cp_build_reference_type (TREE_TYPE (min), + !real_lvalue_p (expr)); + expr = convert_from_reference (min); + } return expr; } @@ -5534,6 +5529,16 @@ build_x_compound_expr_from_list (tree list, expr_list_kind exp, { tree expr = TREE_VALUE (list); + if (BRACE_ENCLOSED_INITIALIZER_P (expr) + && !CONSTRUCTOR_IS_DIRECT_INIT (expr)) + { + if (complain & tf_error) + pedwarn (EXPR_LOC_OR_HERE (expr), 0, "list-initializer for " + "non-class type must not be parenthesized"); + else + return error_mark_node; + } + if (TREE_CHAIN (list)) { if (complain & tf_error) @@ -5554,6 +5559,8 @@ build_x_compound_expr_from_list (tree list, expr_list_kind exp, default: gcc_unreachable (); } + else + return error_mark_node; for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list)) expr = build_x_compound_expr (expr, TREE_VALUE (list), @@ -5610,7 +5617,7 @@ build_x_compound_expr (tree op1, tree op2, tsubst_flags_t complain) } result = build_new_op (COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE, - /*overloaded_p=*/NULL, complain); + /*overload=*/NULL, complain); if (!result) result = cp_build_compound_expr (op1, op2, complain); @@ -5661,42 +5668,47 @@ cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain) } /* Issue a diagnostic message if casting from SRC_TYPE to DEST_TYPE - casts away constness. CAST gives the type of cast. + casts away constness. CAST gives the type of cast. Returns true + if the cast is ill-formed, false if it is well-formed. ??? This function warns for casting away any qualifier not just const. We would like to specify exactly what qualifiers are casted away. */ -static void +static bool check_for_casting_away_constness (tree src_type, tree dest_type, - enum tree_code cast) + enum tree_code cast, tsubst_flags_t complain) { /* C-style casts are allowed to cast away constness. With WARN_CAST_QUAL, we still want to issue a warning. */ if (cast == CAST_EXPR && !warn_cast_qual) - return; + return false; if (!casts_away_constness (src_type, dest_type)) - return; + return false; switch (cast) { case CAST_EXPR: - warning (OPT_Wcast_qual, - "cast from type %qT to type %qT casts away qualifiers", - src_type, dest_type); - return; + if (complain & tf_warning) + warning (OPT_Wcast_qual, + "cast from type %qT to type %qT casts away qualifiers", + src_type, dest_type); + return false; case STATIC_CAST_EXPR: - error ("static_cast from type %qT to type %qT casts away qualifiers", - src_type, dest_type); - return; + if (complain & tf_error) + error ("static_cast from type %qT to type %qT casts away qualifiers", + src_type, dest_type); + return true; case REINTERPRET_CAST_EXPR: - error ("reinterpret_cast from type %qT to type %qT casts away qualifiers", - src_type, dest_type); - return; + if (complain & tf_error) + error ("reinterpret_cast from type %qT to type %qT casts away qualifiers", + src_type, dest_type); + return true; + default: gcc_unreachable(); } @@ -5752,33 +5764,6 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p, allow_inverse_p, c_cast_p, complain); } -/* If EXPR is an INTEGER_CST and ORIG is an arithmetic constant, return - a version of EXPR that has TREE_OVERFLOW set if it is set in ORIG. - Otherwise, return EXPR unchanged. */ - -static tree -ignore_overflows (tree expr, tree orig) -{ - if (TREE_CODE (expr) == INTEGER_CST - && CONSTANT_CLASS_P (orig) - && TREE_CODE (orig) != STRING_CST - && TREE_OVERFLOW (expr) != TREE_OVERFLOW (orig)) - { - if (!TREE_OVERFLOW (orig)) - /* Ensure constant sharing. */ - expr = build_int_cst_wide (TREE_TYPE (expr), - TREE_INT_CST_LOW (expr), - TREE_INT_CST_HIGH (expr)); - else - { - /* Avoid clobbering a shared constant. */ - expr = copy_node (expr); - TREE_OVERFLOW (expr) = TREE_OVERFLOW (orig); - } - } - return expr; -} - /* Perform a static_cast from EXPR to TYPE. When C_CAST_P is true, this static_cast is being attempted as one of the possible casts allowed by a C-style cast. (In that case, accessibility of base @@ -5792,7 +5777,6 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, { tree intype; tree result; - tree orig; /* Assume the cast is valid. */ *valid_p = true; @@ -5847,17 +5831,23 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, /* Convert from "B*" to "D*". This function will check that "B" is not a virtual base of "D". */ expr = build_base_path (MINUS_EXPR, build_address (expr), - base, /*nonnull=*/false); + base, /*nonnull=*/false, complain); /* Convert the pointer to a reference -- but then remember that - there are no expressions with reference type in C++. */ - return convert_from_reference (cp_fold_convert (type, expr)); + there are no expressions with reference type in C++. + + We call rvalue so that there's an actual tree code + (NON_LVALUE_EXPR) for the static_cast; otherwise, if the operand + is a variable with the same type, the conversion would get folded + away, leaving just the variable and causing lvalue_kind to give + the wrong answer. */ + return convert_from_reference (rvalue (cp_fold_convert (type, expr))); } - /* "An lvalue of type cv1 T1 can be cast to type rvalue reference to + /* "A glvalue of type cv1 T1 can be cast to type rvalue reference to cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)." */ if (TREE_CODE (type) == REFERENCE_TYPE && TYPE_REF_IS_RVALUE (type) - && real_lvalue_p (expr) + && lvalue_or_rvalue_with_address_p (expr) && reference_related_p (TREE_TYPE (type), intype) && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype))) { @@ -5865,8 +5855,6 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, return convert_from_reference (expr); } - orig = expr; - /* Resolve overloaded address here rather than once in implicit_conversion and again in the inverse code below. */ if (TYPE_PTRMEMFUNC_P (type) && type_unknown_p (expr)) @@ -5887,9 +5875,6 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, { result = convert_from_reference (result); - /* Ignore any integer overflow caused by the cast. */ - result = ignore_overflows (result, orig); - /* [expr.static.cast] If T is a reference type, the result is an lvalue; otherwise, @@ -5929,13 +5914,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))) - { - expr = ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL); - - /* Ignore any integer overflow caused by the cast. */ - expr = ignore_overflows (expr, orig); - return expr; - } + return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL); if (TYPE_PTR_P (type) && TYPE_PTR_P (intype) && CLASS_TYPE_P (TREE_TYPE (type)) @@ -5947,12 +5926,16 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, { tree base; - if (!c_cast_p) - check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR); + if (!c_cast_p + && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR, + complain)) + return error_mark_node; base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), c_cast_p ? ba_unique : ba_check, NULL); - return build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false); + expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false, + complain); + return cp_fold_convert(type, expr); } if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) @@ -5982,10 +5965,13 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, } if (can_convert (t1, t2) || can_convert (t2, t1)) { - if (!c_cast_p) - check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR); + if (!c_cast_p + && check_for_casting_away_constness (intype, type, + STATIC_CAST_EXPR, + complain)) + return error_mark_node; return convert_ptrmem (type, expr, /*allow_inverse_p=*/1, - c_cast_p, tf_warning_or_error); + c_cast_p, complain); } } @@ -5999,8 +5985,10 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, && VOID_TYPE_P (TREE_TYPE (intype)) && TYPE_PTROB_P (type)) { - if (!c_cast_p) - check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR); + if (!c_cast_p + && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR, + complain)) + return error_mark_node; return build_nop (type, expr); } @@ -6128,7 +6116,7 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, warning (0, "casting %qT to %qT does not dereference pointer", intype, type); - expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain); + expr = cp_build_addr_expr (expr, complain); if (warn_strict_aliasing > 2) strict_aliasing_warning (TREE_TYPE (expr), type, expr); @@ -6204,8 +6192,11 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, { tree sexpr = expr; - if (!c_cast_p) - check_for_casting_away_constness (intype, type, REINTERPRET_CAST_EXPR); + if (!c_cast_p + && check_for_casting_away_constness (intype, type, + REINTERPRET_CAST_EXPR, + complain)) + return error_mark_node; /* Warn about possible alignment problems. */ if (STRICT_ALIGNMENT && warn_cast_align && (complain & tf_warning) @@ -6282,7 +6273,7 @@ build_reinterpret_cast (tree type, tree expr, tsubst_flags_t complain) whether or not the conversion succeeded. */ static tree -build_const_cast_1 (tree dst_type, tree expr, bool complain, +build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain, bool *valid_p) { tree src_type; @@ -6301,7 +6292,7 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain, if (!POINTER_TYPE_P (dst_type) && !TYPE_PTRMEM_P (dst_type)) { - if (complain) + if (complain & tf_error) error ("invalid use of const_cast with type %qT, " "which is not a pointer, " "reference, nor a pointer-to-data-member type", dst_type); @@ -6310,7 +6301,7 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain, if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE) { - if (complain) + if (complain & tf_error) error ("invalid use of const_cast with type %qT, which is a pointer " "or reference to a function type", dst_type); return error_mark_node; @@ -6326,16 +6317,31 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain, /* [expr.const.cast] - An lvalue of type T1 can be explicitly converted to an lvalue of - type T2 using the cast const_cast (where T1 and T2 are object - types) if a pointer to T1 can be explicitly converted to the type - pointer to T2 using a const_cast. */ + For two object types T1 and T2, if a pointer to T1 can be explicitly + converted to the type "pointer to T2" using a const_cast, then the + following conversions can also be made: + + -- an lvalue of type T1 can be explicitly converted to an lvalue of + type T2 using the cast const_cast; + + -- a glvalue of type T1 can be explicitly converted to an xvalue of + type T2 using the cast const_cast; and + + -- if T1 is a class type, a prvalue of type T1 can be explicitly + converted to an xvalue of type T2 using the cast const_cast. */ + if (TREE_CODE (dst_type) == REFERENCE_TYPE) { reference_type = dst_type; - if (! real_lvalue_p (expr)) + if (!TYPE_REF_IS_RVALUE (dst_type) + ? real_lvalue_p (expr) + : (CLASS_TYPE_P (TREE_TYPE (dst_type)) + ? lvalue_p (expr) + : lvalue_or_rvalue_with_address_p (expr))) + /* OK. */; + else { - if (complain) + if (complain & tf_error) error ("invalid const_cast of an rvalue of type %qT to type %qT", src_type, dst_type); return error_mark_node; @@ -6354,37 +6360,44 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain, return error_mark_node; } - if ((TYPE_PTR_P (src_type) || TYPE_PTRMEM_P (src_type)) - && comp_ptr_ttypes_const (dst_type, src_type)) + if (TYPE_PTR_P (src_type) || TYPE_PTRMEM_P (src_type)) { - if (valid_p) - { - *valid_p = true; - /* This cast is actually a C-style cast. Issue a warning if - the user is making a potentially unsafe cast. */ - check_for_casting_away_constness (src_type, dst_type, CAST_EXPR); - } - if (reference_type) + if (comp_ptr_ttypes_const (dst_type, src_type)) { - expr = cp_build_unary_op (ADDR_EXPR, expr, 0, - complain? tf_warning_or_error : tf_none); - expr = build_nop (reference_type, expr); - return convert_from_reference (expr); - } - else - { - expr = decay_conversion (expr); - /* build_c_cast puts on a NOP_EXPR to make the result not an - lvalue. Strip such NOP_EXPRs if VALUE is being used in - non-lvalue context. */ - if (TREE_CODE (expr) == NOP_EXPR - && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0))) - expr = TREE_OPERAND (expr, 0); - return build_nop (dst_type, expr); + if (valid_p) + { + *valid_p = true; + /* This cast is actually a C-style cast. Issue a warning if + the user is making a potentially unsafe cast. */ + check_for_casting_away_constness (src_type, dst_type, + CAST_EXPR, complain); + } + if (reference_type) + { + expr = cp_build_addr_expr (expr, complain); + expr = build_nop (reference_type, expr); + return convert_from_reference (expr); + } + else + { + expr = decay_conversion (expr); + /* build_c_cast puts on a NOP_EXPR to make the result not an + lvalue. Strip such NOP_EXPRs if VALUE is being used in + non-lvalue context. */ + if (TREE_CODE (expr) == NOP_EXPR + && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0))) + expr = TREE_OPERAND (expr, 0); + return build_nop (dst_type, expr); + } } + else if (valid_p + && !at_least_as_qualified_p (TREE_TYPE (dst_type), + TREE_TYPE (src_type))) + check_for_casting_away_constness (src_type, dst_type, CAST_EXPR, + complain); } - if (complain) + if (complain & tf_error) error ("invalid const_cast from type %qT to type %qT", src_type, dst_type); return error_mark_node; @@ -6407,7 +6420,7 @@ build_const_cast (tree type, tree expr, tsubst_flags_t complain) return convert_from_reference (t); } - return build_const_cast_1 (type, expr, complain & tf_error, + return build_const_cast_1 (type, expr, complain, /*valid_p=*/NULL); } @@ -6493,7 +6506,7 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain) "cast to pointer from integer of different size"); /* A C-style cast can be a const_cast. */ - result = build_const_cast_1 (type, value, /*complain=*/false, + result = build_const_cast_1 (type, value, complain & tf_warning, &valid_p); if (valid_p) return result; @@ -6518,7 +6531,7 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain) if (!CLASS_TYPE_P (type)) type = TYPE_MAIN_VARIANT (type); result_type = TREE_TYPE (result); - if (!CLASS_TYPE_P (result_type)) + if (!CLASS_TYPE_P (result_type) && TREE_CODE (type) != REFERENCE_TYPE) result_type = TYPE_MAIN_VARIANT (result_type); /* If the type of RESULT does not match TYPE, perform a const_cast to make it match. If the static_cast or @@ -6697,12 +6710,19 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, } else { - lhs = require_complete_type (lhs); + lhs = require_complete_type_sfinae (lhs, complain); if (lhs == error_mark_node) return error_mark_node; if (modifycode == NOP_EXPR) { + if (c_dialect_objc ()) + { + result = objc_maybe_build_modify_expr (lhs, rhs); + if (result) + return result; + } + /* `operator=' is not an inheritable operator. */ if (! MAYBE_CLASS_TYPE_P (lhstype)) /* Do the default thing. */; @@ -6710,7 +6730,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, { result = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs, make_node (NOP_EXPR), - /*overloaded_p=*/NULL, + /*overload=*/NULL, complain); if (result == NULL_TREE) return error_mark_node; @@ -6720,6 +6740,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, } else { + tree init = NULL_TREE; + /* A binary op has been requested. Combine the old LHS value with the RHS producing the value we should actually store into the LHS. */ @@ -6727,7 +6749,19 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype))) || MAYBE_CLASS_TYPE_P (lhstype))); + /* Preevaluate the RHS to make sure its evaluation is complete + before the lvalue-to-rvalue conversion of the LHS: + + [expr.ass] With respect to an indeterminately-sequenced + function call, the operation of a compound assignment is a + single evaluation. [ Note: Therefore, a function call shall + not intervene between the lvalue-to-rvalue conversion and the + side effect associated with any single compound assignment + operator. -- end note ] */ lhs = stabilize_reference (lhs); + if (TREE_SIDE_EFFECTS (rhs)) + rhs = mark_rvalue_use (rhs); + rhs = stabilize_expr (rhs, &init); newrhs = cp_build_binary_op (input_location, modifycode, lhs, rhs, complain); @@ -6739,8 +6773,17 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, return error_mark_node; } + if (init) + newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs); + /* Now it looks like a plain assignment. */ modifycode = NOP_EXPR; + if (c_dialect_objc ()) + { + result = objc_maybe_build_modify_expr (lhs, newrhs); + if (result) + return result; + } } gcc_assert (TREE_CODE (lhstype) != REFERENCE_TYPE); gcc_assert (TREE_CODE (TREE_TYPE (newrhs)) != REFERENCE_TYPE); @@ -6764,7 +6807,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, && C_TYPE_FIELDS_READONLY (lhstype)))) { if (complain & tf_error) - readonly_error (lhs, REK_ASSIGNMENT); + cxx_readonly_error (lhs, lv_assign); else return error_mark_node; } @@ -6791,7 +6834,9 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, } if (check_array_initializer (lhs, lhstype, newrhs)) return error_mark_node; - newrhs = digest_init (lhstype, newrhs); + newrhs = digest_init (lhstype, newrhs, complain); + if (newrhs == error_mark_node) + return error_mark_node; } else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype), @@ -6805,7 +6850,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, /* Allow array assignment in compiler-generated code. */ else if (!current_function_decl - || !DECL_ARTIFICIAL (current_function_decl)) + || !DECL_DEFAULTED_FN (current_function_decl)) { /* This routine is used for both initialization and assignment. Make sure the diagnostic message differentiates the context. */ @@ -6843,7 +6888,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, { if (TREE_CODE (newrhs) == CALL_EXPR && TYPE_NEEDS_CONSTRUCTING (lhstype)) - newrhs = build_cplus_new (lhstype, newrhs); + newrhs = build_cplus_new (lhstype, newrhs, complain); /* Can't initialize directly from a TARGET_EXPR, since that would cause the lhs to be constructed twice, and possibly result in @@ -6887,7 +6932,7 @@ build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, { tree rval = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs, make_node (modifycode), - /*overloaded_p=*/NULL, + /*overload=*/NULL, complain); if (rval) { @@ -7135,7 +7180,7 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p, /* Handle null pointer to member function conversions. */ if (null_ptr_cst_p (pfn)) { - pfn = build_c_cast (input_location, type, integer_zero_node); + pfn = build_c_cast (input_location, type, nullptr_node); return build_ptrmemfunc1 (to_type, integer_zero_node, pfn); @@ -7425,7 +7470,7 @@ convert_for_assignment (tree type, tree rhs, break; case ICR_CONVERTING: warning (OPT_Wmissing_format_attribute, - "target of conversion might be might be a candidate " + "target of conversion might be a candidate " "for a format attribute"); break; case ICR_INIT: @@ -7457,8 +7502,7 @@ convert_for_assignment (tree type, tree rhs, && TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE && (complain & tf_warning)) { - location_t loc = EXPR_HAS_LOCATION (rhs) - ? EXPR_LOCATION (rhs) : input_location; + location_t loc = EXPR_LOC_OR_HERE (rhs); warning_at (loc, OPT_Wparentheses, "suggest parentheses around assignment used as truth value"); @@ -7532,8 +7576,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags, if (fndecl) savew = warningcount, savee = errorcount; - rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE, - /*cleanup=*/NULL, complain); + rhs = initialize_reference (type, rhs, flags, complain); if (fndecl) { if (warningcount > savew) @@ -7545,7 +7588,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags, } if (exp != 0) - exp = require_complete_type (exp); + exp = require_complete_type_sfinae (exp, complain); if (exp == error_mark_node) return error_mark_node; @@ -7559,7 +7602,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags, return rhs; if (MAYBE_CLASS_TYPE_P (type)) - return ocp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); + return perform_implicit_conversion_flags (type, rhs, complain, flags); return convert_for_assignment (type, rhs, errtype, fndecl, parmnum, complain, flags); @@ -7680,15 +7723,14 @@ check_return_expr (tree retval, bool *no_warning) tree type = lambda_return_type (retval); tree oldtype = LAMBDA_EXPR_RETURN_TYPE (lambda); - if (VOID_TYPE_P (type)) - { /* Nothing. */ } - else if (oldtype == NULL_TREE) - { - pedwarn (input_location, OPT_pedantic, "lambda return type " - "can only be deduced when the return statement is " - "the only statement in the function body"); - apply_lambda_return_type (lambda, type); - } + if (oldtype == NULL_TREE) + apply_lambda_return_type (lambda, type); + /* If one of the answers is type-dependent, we can't do any + better until instantiation time. */ + else if (oldtype == dependent_lambda_return_type_node) + /* Leave it. */; + else if (type == dependent_lambda_return_type_node) + apply_lambda_return_type (lambda, type); else if (!same_type_p (type, oldtype)) error ("inconsistent types %qT and %qT deduced for " "lambda return type", type, oldtype); @@ -7865,12 +7907,19 @@ check_return_expr (tree retval, bool *no_warning) /* Under C++0x [12.8/16 class.copy], a returned lvalue is sometimes treated as an rvalue for the purposes of overload resolution to - favor move constructors over copy constructors. */ - if ((cxx_dialect != cxx98) - && named_return_value_okay_p - /* The variable must not have the `volatile' qualifier. */ - && !CP_TYPE_VOLATILE_P (TREE_TYPE (retval)) - /* The return type must be a class type. */ + favor move constructors over copy constructors. + + Note that these conditions are similar to, but not as strict as, + the conditions for the named return value optimization. */ + if ((cxx_dialect != cxx98) + && (TREE_CODE (retval) == VAR_DECL + || TREE_CODE (retval) == PARM_DECL) + && DECL_CONTEXT (retval) == current_function_decl + && !TREE_STATIC (retval) + && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))), + (TYPE_MAIN_VARIANT + (TREE_TYPE (TREE_TYPE (current_function_decl))))) + /* This is only interesting for class type. */ && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) flags = flags | LOOKUP_PREFER_RVALUE; @@ -7931,15 +7980,10 @@ comp_ptr_ttypes_real (tree to, tree from, int constp) so the usual checks are not appropriate. */ if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE) { - /* In Objective-C++, some types may have been 'volatilized' by - the compiler for EH; when comparing them here, the volatile - qualification must be ignored. */ - bool objc_quals_match = objc_type_quals_match (to, from); - - if (!at_least_as_qualified_p (to, from) && !objc_quals_match) + if (!at_least_as_qualified_p (to, from)) return 0; - if (!at_least_as_qualified_p (from, to) && !objc_quals_match) + if (!at_least_as_qualified_p (from, to)) { if (constp == 0) return 0; @@ -8109,7 +8153,7 @@ type_memfn_quals (const_tree type) if (TREE_CODE (type) == FUNCTION_TYPE) return TYPE_QUALS (type); else if (TREE_CODE (type) == METHOD_TYPE) - return cp_type_quals (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type)))); + return cp_type_quals (class_of_this_parm (type)); else gcc_unreachable (); } @@ -8177,15 +8221,13 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl) && type_quals != TYPE_UNQUALIFIED)); /* Avoid setting TREE_READONLY incorrectly. */ - if (/* If the object has a constructor, the constructor may modify - the object. */ - TYPE_NEEDS_CONSTRUCTING (type) - /* If the type isn't complete, we don't know yet if it will need - constructing. */ - || !COMPLETE_TYPE_P (type) - /* If the type has a mutable component, that component might be - modified. */ - || TYPE_HAS_MUTABLE_P (type)) + /* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr + constructor can produce constant init, so rely on cp_finish_decl to + clear TREE_READONLY if the variable has non-constant init. */ + + /* If the type has a mutable component, that component might be + modified. */ + if (TYPE_HAS_MUTABLE_P (type)) type_quals &= ~TYPE_QUAL_CONST; c_apply_type_quals_to_decl (type_quals, decl); @@ -8311,7 +8353,7 @@ casts_away_constness (tree t1, tree t2) tree non_reference (tree t) { - if (TREE_CODE (t) == REFERENCE_TYPE) + if (t && TREE_CODE (t) == REFERENCE_TYPE) t = TREE_TYPE (t); return t; } @@ -8324,11 +8366,139 @@ non_reference (tree t) int lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain) { - int win = lvalue_p (ref); + cp_lvalue_kind kind = lvalue_kind (ref); - if (!win && (complain & tf_error)) - lvalue_error (use); + if (kind == clk_none) + { + if (complain & tf_error) + lvalue_error (input_location, use); + return 0; + } + else if (kind & (clk_rvalueref|clk_class)) + { + if (!(complain & tf_error)) + return 0; + if (kind & clk_class) + /* Make this a permerror because we used to accept it. */ + permerror (input_location, "using temporary as lvalue"); + else + error ("using xvalue (rvalue reference) as lvalue"); + } + return 1; +} + +/* Return true if a user-defined literal operator is a raw operator. */ + +bool +check_raw_literal_operator (const_tree decl) +{ + tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); + tree argtype; + int arity; + bool maybe_raw_p = false; + + /* Count the number and type of arguments and check for ellipsis. */ + for (argtype = argtypes, arity = 0; + argtype && argtype != void_list_node; + ++arity, argtype = TREE_CHAIN (argtype)) + { + tree t = TREE_VALUE (argtype); + + if (same_type_p (t, const_string_type_node)) + maybe_raw_p = true; + } + if (!argtype) + return false; /* Found ellipsis. */ - return win; + if (!maybe_raw_p || arity != 1) + return false; + + return true; +} + + +/* Return true if a user-defined literal operator has one of the allowed + argument types. */ + +bool +check_literal_operator_args (const_tree decl, + bool *long_long_unsigned_p, bool *long_double_p) +{ + tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); + if (processing_template_decl || processing_specialization) + return argtypes == void_list_node; + else + { + tree argtype; + int arity; + int max_arity = 2; + + *long_long_unsigned_p = false; + *long_double_p = false; + + /* Count the number and type of arguments and check for ellipsis. */ + for (argtype = argtypes, arity = 0; + argtype && argtype != void_list_node; + argtype = TREE_CHAIN (argtype)) + { + tree t = TREE_VALUE (argtype); + ++arity; + + if (TREE_CODE (t) == POINTER_TYPE) + { + bool maybe_raw_p = false; + t = TREE_TYPE (t); + if (cp_type_quals (t) != TYPE_QUAL_CONST) + return false; + t = TYPE_MAIN_VARIANT (t); + if ((maybe_raw_p = same_type_p (t, char_type_node)) + || same_type_p (t, wchar_type_node) + || same_type_p (t, char16_type_node) + || same_type_p (t, char32_type_node)) + { + argtype = TREE_CHAIN (argtype); + if (!argtype) + return false; + t = TREE_VALUE (argtype); + if (maybe_raw_p && argtype == void_list_node) + return true; + else if (same_type_p (t, size_type_node)) + { + ++arity; + continue; + } + else + return false; + } + } + else if (same_type_p (t, long_long_unsigned_type_node)) + { + max_arity = 1; + *long_long_unsigned_p = true; + } + else if (same_type_p (t, long_double_type_node)) + { + max_arity = 1; + *long_double_p = true; + } + else if (same_type_p (t, char_type_node)) + max_arity = 1; + else if (same_type_p (t, wchar_type_node)) + max_arity = 1; + else if (same_type_p (t, char16_type_node)) + max_arity = 1; + else if (same_type_p (t, char32_type_node)) + max_arity = 1; + else + return false; + } + if (!argtype) + return false; /* Found ellipsis. */ + + if (arity != max_arity) + return false; + + return true; + } }