diff --git a/contrib/gcc/cp/ChangeLog.gcc43 b/contrib/gcc/cp/ChangeLog.gcc43 index 1f1de7689316..6d87b07b3b5a 100644 --- a/contrib/gcc/cp/ChangeLog.gcc43 +++ b/contrib/gcc/cp/ChangeLog.gcc43 @@ -35,65 +35,6 @@ * typeck.c (build_binary_op): Include types in error. -2007-05-30 Russell Yanofsky (r125211) - Douglas Gregor - Pedro Lamarao - Howard Hinnant - - PR c++/7412 - PR c++/29939 - * typeck.c (comptypes): Don't consider rvalue and lvalue - reference types to be equivalent. - (check_return_expr): Move from certain lvalues when returning - them. - * decl.c (grokdeclarator): Implement reference collapsing. - (copy_fn_p): Don't consider constructors taking rvalue references - to be copy constructors. - (move_fn_p): New. - * call.c (conversion): New "rvaluedness_matches_p" member. - (convert_class_to_reference): Require reference type as first - parameter instead of base type. - (reference_binding): Add logic to handle rvalue references. - (implicit_conversion): Update inaccurate comment. - (convert_like_real): Disable creation of temporaries that are - impossible to initialize for types with move constructors. - (build_over_call): Elide move constructors when possible. - (maybe_handle_implicit_object): Set "rvaluedness_matches_p". - (maybe_handle_ref_bind): Return conversion instead of type node. - (compare_ics): Add logic to use "rvaluedness_matches_p" values to - determine preferred conversion sequences. - * cp-tree.h (TYPE_REF_IS_RVALUE): New. - (LOOKUP_PREFER_RVALUE): New. - (DECL_MOVE_CONSTRUCTOR_P): New. - (struct cp_declarator): Add "reference" member for reference - types, with new "rvalue_ref" flag. - (cp_build_reference_type): Declare. - (move_fn_p): Declare. - * error.c (dump_type_prefix): Format rvalue reference types - correctly in error messages. - * except.c (build_throw): Move from certain lvalues when - throwing. - * mangle.c (write_type): Mangle rvalue references differently - than regular references. - * parser.c (make_reference_declarator): Add boolean parameter for - rvalue references. - (cp_parser_make_indirect_declarator): New. - (cp_parser_new_declarator_opt): Call - cp_parser_make_indirect_declarator. - (cp_parser_conversion_declarator_opt): Ditto. - (cp_parser_declarator): Ditto. - (cp_parser_ptr_operator): Parse "&&" tokens into rvalue reference - declarators. - * pt.c (tsubst): Implement reference collapsing. - (maybe_adjust_types_for_deduction): Implement special template - parameter deduction rule for rvalue references. - (type_unification_real): Update calls to - maybe_adjust_types_for_deduction. - (try_one_overload): Ditto. - (unify_pack_expansion): Ditto. - * tree.c (lvalue_p_1): Handle rvalue reference types. - (cp_build_reference_type): New. - 2007-05-18 Geoffrey Keating (r124839) * mangle.c (write_real_cst): Use 'unsigned long' for %lx. diff --git a/contrib/gcc/cp/call.c b/contrib/gcc/cp/call.c index 576790ca62f8..24b5d1fc3ec2 100644 --- a/contrib/gcc/cp/call.c +++ b/contrib/gcc/cp/call.c @@ -95,10 +95,6 @@ struct conversion { /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion from a pointer-to-derived to pointer-to-base is being performed. */ BOOL_BITFIELD base_p : 1; - /* If KIND is ck_ref_bind, true when either an lvalue reference is - being bound to an lvalue expression or an rvalue reference is - being bound to an rvalue expression. */ - BOOL_BITFIELD rvaluedness_matches_p: 1; /* The type of the expression resulting from the conversion. */ tree type; union { @@ -178,7 +174,7 @@ static conversion *standard_conversion (tree, tree, tree, bool, int); static conversion *reference_binding (tree, tree, tree, bool, int); static conversion *build_conv (conversion_kind, tree, conversion *); static bool is_subseq (conversion *, conversion *); -static conversion *maybe_handle_ref_bind (conversion **); +static tree maybe_handle_ref_bind (conversion **); static void maybe_handle_implicit_object (conversion **); static struct z_candidate *add_candidate (struct z_candidate **, tree, tree, size_t, @@ -899,12 +895,12 @@ reference_compatible_p (tree t1, tree t2) converted to T as in [over.match.ref]. */ static conversion * -convert_class_to_reference (tree reference_type, tree s, tree expr) +convert_class_to_reference (tree t, tree s, tree expr) { tree conversions; tree arglist; conversion *conv; - tree t; + tree reference_type; struct z_candidate *candidates; struct z_candidate *cand; bool any_viable_p; @@ -938,7 +934,7 @@ convert_class_to_reference (tree reference_type, tree s, tree expr) arglist = build_int_cst (build_pointer_type (s), 0); arglist = build_tree_list (NULL_TREE, arglist); - t = TREE_TYPE (reference_type); + reference_type = build_reference_type (t); while (conversions) { @@ -1001,9 +997,6 @@ convert_class_to_reference (tree reference_type, tree s, tree expr) cand->second_conv = (direct_reference_binding (reference_type, identity_conv)); - cand->second_conv->rvaluedness_matches_p - = TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn))) - == TYPE_REF_IS_RVALUE (reference_type); cand->second_conv->bad_p |= cand->convs[0]->bad_p; } } @@ -1130,16 +1123,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) to = build_qualified_type (to, cp_type_quals (from)); compatible_p = reference_compatible_p (to, from); - /* Directly bind reference when target expression's type is compatible with - the reference and expression is an lvalue. In C++0x, the wording in - [8.5.3/5 dcl.init.ref] is changed to also allow direct bindings for const - and rvalue references to rvalues of compatible class type, as part of - DR391. */ - if (compatible_p - && (lvalue_p - || (flag_cpp0x - && (CP_TYPE_CONST_NON_VOLATILE_P(to) || TYPE_REF_IS_RVALUE (rto)) - && CLASS_TYPE_P (from)))) + if (lvalue_p && compatible_p) { /* [dcl.init.ref] @@ -1152,15 +1136,6 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) lvalue. */ conv = build_identity_conv (from, expr); conv = direct_reference_binding (rto, conv); - - if (flags & LOOKUP_PREFER_RVALUE) - /* The top-level caller requested that we pretend that the lvalue - be treated as an rvalue. */ - conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto); - else - conv->rvaluedness_matches_p - = (TYPE_REF_IS_RVALUE (rto) == !lvalue_p); - if ((lvalue_p & clk_bitfield) != 0 || ((lvalue_p & clk_packed) != 0 && !TYPE_PACKED (to))) /* For the purposes of overload resolution, we ignore the fact @@ -1193,7 +1168,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) the reference is bound to the lvalue result of the conversion in the second case. */ - conv = convert_class_to_reference (rto, from, expr); + conv = convert_class_to_reference (to, from, expr); if (conv) return conv; } @@ -1216,10 +1191,8 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) /* [dcl.init.ref] - Otherwise, the reference shall be to a non-volatile const type. - - Under C++0x, [8.5.3/5 dcl.init.ref] it may also be an rvalue reference */ - if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto)) + Otherwise, the reference shall be to a non-volatile const type. */ + if (!CP_TYPE_CONST_NON_VOLATILE_P (to)) return NULL; /* [dcl.init.ref] @@ -1242,7 +1215,6 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) { conv = build_identity_conv (from, expr); conv = direct_reference_binding (rto, conv); - conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto); if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE)) conv->u.next->check_copy_constructor_p = true; return conv; @@ -1267,7 +1239,6 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) /* This reference binding, unlike those above, requires the creation of a temporary. */ conv->need_temporary_p = true; - conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto); return conv; } @@ -1309,7 +1280,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, conv = cand->second_conv; /* We used to try to bind a reference to a temporary here, but that - is now handled after the recursive call to this function at the end + is now handled by the recursive call to this function at the end of reference_binding. */ return conv; } @@ -4438,22 +4409,13 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, { tree ref_type = totype; - /* If necessary, create a temporary. - - VA_ARG_EXPR and CONSTRUCTOR expressions are special cases - that need temporaries, even when their types are reference - compatible with the type of reference being bound, so the - upcoming call to build_unary_op (ADDR_EXPR, expr, ...) - doesn't fail. */ - if (convs->need_temporary_p - || TREE_CODE (expr) == CONSTRUCTOR - || TREE_CODE (expr) == VA_ARG_EXPR) + /* If necessary, create a temporary. */ + if (convs->need_temporary_p || !lvalue_p (expr)) { tree type = convs->u.next->type; cp_lvalue_kind lvalue = real_lvalue_p (expr); - if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)) - && !TYPE_REF_IS_RVALUE (ref_type)) + if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type))) { /* If the reference is volatile or non-const, we cannot create a temporary. */ @@ -4976,9 +4938,7 @@ build_over_call (struct z_candidate *cand, int flags) if (! flag_elide_constructors) /* Do things the hard way. */; - else if (cand->num_convs == 1 - && (DECL_COPY_CONSTRUCTOR_P (fn) - || DECL_MOVE_CONSTRUCTOR_P (fn))) + else if (cand->num_convs == 1 && DECL_COPY_CONSTRUCTOR_P (fn)) { tree targ; arg = skip_artificial_parms_for (fn, converted_args); @@ -5716,28 +5676,28 @@ maybe_handle_implicit_object (conversion **ics) t = t->u.next; t = build_identity_conv (TREE_TYPE (t->type), NULL_TREE); t = direct_reference_binding (reference_type, t); - t->rvaluedness_matches_p = 1; *ics = t; } } /* If *ICS is a REF_BIND set *ICS to the remainder of the conversion, - and return the initial reference binding conversion. Otherwise, - leave *ICS unchanged and return NULL. */ + and return the type to which the reference refers. Otherwise, + leave *ICS unchanged and return NULL_TREE. */ -static conversion * +static tree maybe_handle_ref_bind (conversion **ics) { if ((*ics)->kind == ck_ref_bind) { conversion *old_ics = *ics; + tree type = TREE_TYPE (old_ics->type); *ics = old_ics->u.next; (*ics)->user_conv_p = old_ics->user_conv_p; (*ics)->bad_p = old_ics->bad_p; - return old_ics; + return type; } - return NULL; + return NULL_TREE; } /* Compare two implicit conversion sequences according to the rules set out in @@ -5761,18 +5721,18 @@ compare_ics (conversion *ics1, conversion *ics2) conversion_rank rank1, rank2; /* REF_BINDING is nonzero if the result of the conversion sequence - is a reference type. In that case REF_CONV is the reference - binding conversion. */ - conversion *ref_conv1; - conversion *ref_conv2; + is a reference type. In that case TARGET_TYPE is the + type referred to by the reference. */ + tree target_type1; + tree target_type2; /* Handle implicit object parameters. */ maybe_handle_implicit_object (&ics1); maybe_handle_implicit_object (&ics2); /* Handle reference parameters. */ - ref_conv1 = maybe_handle_ref_bind (&ics1); - ref_conv2 = maybe_handle_ref_bind (&ics2); + target_type1 = maybe_handle_ref_bind (&ics1); + target_type2 = maybe_handle_ref_bind (&ics2); /* [over.ics.rank] @@ -6063,31 +6023,15 @@ compare_ics (conversion *ics1, conversion *ics2) /* [over.ics.rank] - --S1 and S2 are reference bindings (_dcl.init.ref_) and neither refers - to an implicit object parameter, and either S1 binds an lvalue reference - to an lvalue and S2 binds an rvalue reference or S1 binds an rvalue - reference to an rvalue and S2 binds an lvalue reference - (C++0x draft standard, 13.3.3.2) - --S1 and S2 are reference bindings (_dcl.init.ref_), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers */ - if (ref_conv1 && ref_conv2 + if (target_type1 && target_type2 && same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2)) - { - if (ref_conv1->rvaluedness_matches_p - && !ref_conv2->rvaluedness_matches_p) - return 1; - else if (!ref_conv1->rvaluedness_matches_p - && ref_conv2->rvaluedness_matches_p) - return -1; - - return comp_cv_qualification (TREE_TYPE (ref_conv2->type), - TREE_TYPE (ref_conv1->type)); - } + return comp_cv_qualification (target_type2, target_type1); /* Neither conversion sequence is better than the other. */ return 0; diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h index fc924a2dc547..0b30f38809f3 100644 --- a/contrib/gcc/cp/cp-tree.h +++ b/contrib/gcc/cp/cp-tree.h @@ -56,7 +56,6 @@ struct diagnostic_context; OMP_FOR_GIMPLIFYING_P (in OMP_FOR) BASELINK_QUALIFIED_P (in BASELINK) TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR) - TYPE_REF_IS_RVALUE (in REFERENCE_TYPE) 1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE) TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. @@ -1667,10 +1666,6 @@ struct lang_decl GTY(()) #define DECL_COPY_CONSTRUCTOR_P(NODE) \ (DECL_CONSTRUCTOR_P (NODE) && copy_fn_p (NODE) > 0) -/* Nonzero if NODE (a FUNCTION_DECL) is a move constructor. */ -#define DECL_MOVE_CONSTRUCTOR_P(NODE) \ - (DECL_CONSTRUCTOR_P (NODE) && move_fn_p (NODE)) - /* Nonzero if NODE is a destructor. */ #define DECL_DESTRUCTOR_P(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.destructor_attr) @@ -2566,10 +2561,6 @@ extern void decl_shadowed_for_var_insert (tree, tree); #define TYPE_REF_OBJ_P(NODE) \ (TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE))) -/* True if reference type NODE is an rvalue reference */ -#define TYPE_REF_IS_RVALUE(NODE) \ - TREE_LANG_FLAG_0 (REFERENCE_TYPE_CHECK (NODE)) - /* Returns true if NODE is a pointer to an object, or a pointer to void. Keep these checks in ascending tree code order. */ #define TYPE_PTROBV_P(NODE) \ @@ -3453,8 +3444,6 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; (Normally, these entities are registered in the symbol table, but not found by lookup.) */ #define LOOKUP_HIDDEN (LOOKUP_CONSTRUCTOR_CALLABLE << 1) -/* Prefer that the lvalue be treated as an rvalue. */ -#define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1) #define LOOKUP_NAMESPACES_ONLY(F) \ (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES)) @@ -3761,21 +3750,13 @@ struct cp_declarator { /* The bounds to the array. */ tree bounds; } array; - /* For cdk_pointer and cdk_ptrmem. */ + /* For cdk_pointer, cdk_reference, and cdk_ptrmem. */ struct { /* The cv-qualifiers for the pointer. */ cp_cv_quals qualifiers; /* For cdk_ptrmem, the class type containing the member. */ tree class_type; } pointer; - /* For cdk_reference */ - struct { - /* The cv-qualifiers for the reference. These qualifiers are - only used to diagnose ill-formed code. */ - cp_cv_quals qualifiers; - /* Whether this is an rvalue reference */ - bool rvalue_ref; - } reference; } u; }; @@ -3936,7 +3917,6 @@ extern tree build_ptrmem_type (tree, tree); /* the grokdeclarator prototype is in decl.h */ extern tree build_this_parm (tree, cp_cv_quals); extern int copy_fn_p (tree); -extern bool move_fn_p (tree); extern tree get_scope_of_declarator (const cp_declarator *); extern void grok_special_member_properties (tree); extern int grok_ctor_properties (tree, tree); @@ -4436,7 +4416,6 @@ extern int is_dummy_object (tree); extern const struct attribute_spec cxx_attribute_table[]; extern tree make_ptrmem_cst (tree, tree); extern tree cp_build_type_attribute_variant (tree, tree); -extern tree cp_build_reference_type (tree, bool); extern tree cp_build_qualified_type_real (tree, int, tsubst_flags_t); #define cp_build_qualified_type(TYPE, QUALS) \ cp_build_qualified_type_real ((TYPE), (QUALS), tf_warning_or_error) diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c index 1c468e7d18ad..dcceebaf1fd9 100644 --- a/contrib/gcc/cp/decl.c +++ b/contrib/gcc/cp/decl.c @@ -7823,24 +7823,10 @@ grokdeclarator (const cp_declarator *declarator, if (TREE_CODE (type) == REFERENCE_TYPE) { - if (declarator->kind != cdk_reference) - { - error ("cannot declare pointer to %q#T", type); - type = TREE_TYPE (type); - } - - /* In C++0x, we allow reference to reference declarations - that occur indirectly through typedefs [7.1.3/8 dcl.typedef] - and template type arguments [14.3.1/4 temp.arg.type]. The - check for direct reference to reference declarations, which - are still forbidden, occurs below. Reasoning behind the change - can be found in DR106, DR540, and the rvalue reference - proposals. */ - else if (!flag_cpp0x) - { - error ("cannot declare reference to %q#T", type); - type = TREE_TYPE (type); - } + error (declarator->kind == cdk_reference + ? "cannot declare reference to %q#T" + : "cannot declare pointer to %q#T", type); + type = TREE_TYPE (type); } else if (VOID_TYPE_P (type)) { @@ -7866,39 +7852,8 @@ grokdeclarator (const cp_declarator *declarator, if (declarator->kind == cdk_reference) { - /* In C++0x, the type we are creating a reference to might be - a typedef which is itself a reference type. In that case, - we follow the reference collapsing rules in - [7.1.3/8 dcl.typedef] to create the final reference type: - - "If a typedef TD names a type that is a reference to a type - T, an attempt to create the type 'lvalue reference to cv TD' - creates the type 'lvalue reference to T,' while an attempt - to create the type "rvalue reference to cv TD' creates the - type TD." - */ if (!VOID_TYPE_P (type)) - type = cp_build_reference_type - ((TREE_CODE (type) == REFERENCE_TYPE - ? TREE_TYPE (type) : type), - (declarator->u.reference.rvalue_ref - && (TREE_CODE(type) != REFERENCE_TYPE - || TYPE_REF_IS_RVALUE (type)))); - - /* In C++0x, we need this check for direct reference to - reference declarations, which are forbidden by - [8.3.2/5 dcl.ref]. Reference to reference declarations - are only allowed indirectly through typedefs and template - type arguments. Example: - - void foo(int & &); // invalid ref-to-ref decl - - typedef int & int_ref; - void foo(int_ref &); // valid ref-to-ref decl - */ - if (inner_declarator && inner_declarator->kind == cdk_reference) - error ("cannot declare reference to %q#T, which is not " - "a typedef or a template type argument", type); + type = build_reference_type (type); } else if (TREE_CODE (type) == METHOD_TYPE) type = build_ptrmemfunc_type (build_pointer_type (type)); @@ -9123,7 +9078,6 @@ copy_fn_p (tree d) result = -1; } else if (TREE_CODE (arg_type) == REFERENCE_TYPE - && !TYPE_REF_IS_RVALUE (arg_type) && TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)) == DECL_CONTEXT (d)) { if (CP_TYPE_CONST_P (TREE_TYPE (arg_type))) @@ -9141,57 +9095,6 @@ copy_fn_p (tree d) return result; } -/* D is a constructor or overloaded `operator='. - - Let T be the class in which D is declared. Then, this function - returns true when D is a move constructor or move assignment - operator, false otherwise. */ - -bool -move_fn_p (tree d) -{ - tree args; - tree arg_type; - bool result = false; - - gcc_assert (DECL_FUNCTION_MEMBER_P (d)); - - if (!flag_cpp0x) - /* There are no move constructors if we aren't in C++0x mode. */ - return false; - - if (TREE_CODE (d) == TEMPLATE_DECL - || (DECL_TEMPLATE_INFO (d) - && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d)))) - /* Instantiations of template member functions are never copy - functions. Note that member functions of templated classes are - represented as template functions internally, and we must - accept those as copy functions. */ - return 0; - - args = FUNCTION_FIRST_USER_PARMTYPE (d); - if (!args) - return 0; - - arg_type = TREE_VALUE (args); - if (arg_type == error_mark_node) - return 0; - - if (TREE_CODE (arg_type) == REFERENCE_TYPE - && TYPE_REF_IS_RVALUE (arg_type) - && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)), - DECL_CONTEXT (d))) - result = true; - - args = TREE_CHAIN (args); - - if (args && args != void_list_node && !TREE_PURPOSE (args)) - /* There are more non-optional args. */ - return false; - - return result; -} - /* Remember any special properties of member function DECL. */ void grok_special_member_properties (tree decl) diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c index 92b042a7f3fa..c169cabedb64 100644 --- a/contrib/gcc/cp/error.c +++ b/contrib/gcc/cp/error.c @@ -507,15 +507,7 @@ dump_type_prefix (tree t, int flags) pp_cxx_whitespace (cxx_pp); pp_cxx_left_paren (cxx_pp); } - if (TREE_CODE (t) == POINTER_TYPE) - pp_character(cxx_pp, '*'); - else if (TREE_CODE (t) == REFERENCE_TYPE) - { - if (TYPE_REF_IS_RVALUE (t)) - pp_string (cxx_pp, "&&"); - else - pp_character (cxx_pp, '&'); - } + pp_character (cxx_pp, "&*"[TREE_CODE (t) == POINTER_TYPE]); pp_base (cxx_pp)->padding = pp_before; pp_cxx_cv_qualifier_seq (cxx_pp, t); } diff --git a/contrib/gcc/cp/except.c b/contrib/gcc/cp/except.c index 66a3b1635946..f97ab063dde5 100644 --- a/contrib/gcc/cp/except.c +++ b/contrib/gcc/cp/except.c @@ -709,25 +709,12 @@ build_throw (tree exp) /* And initialize the exception object. */ if (CLASS_TYPE_P (temp_type)) { - int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING; - - /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes - treated as an rvalue for the purposes of overload resolution - to favor move constructors over copy constructors. */ - if (/* Must be a local, automatic variable. */ - TREE_CODE (exp) == VAR_DECL - && DECL_CONTEXT (exp) == current_function_decl - && ! TREE_STATIC (exp) - /* The variable must not have the `volatile' qualifier. */ - && !(cp_type_quals (TREE_TYPE (exp)) & TYPE_QUAL_VOLATILE)) - flags = flags | LOOKUP_PREFER_RVALUE; - /* Call the copy constructor. */ exp = (build_special_member_call (object, complete_ctor_identifier, build_tree_list (NULL_TREE, exp), TREE_TYPE (object), - flags)); + LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING)); if (exp == error_mark_node) { error (" in thrown expression"); diff --git a/contrib/gcc/cp/mangle.c b/contrib/gcc/cp/mangle.c index 6a49350f99c4..8bfdc20ef7a0 100644 --- a/contrib/gcc/cp/mangle.c +++ b/contrib/gcc/cp/mangle.c @@ -1541,10 +1541,6 @@ write_local_name (const tree function, const tree local_entity, ::= G # imaginary (C 2000) [not supported] ::= U # vendor extended type qualifier - C++0x extensions - - ::= RR # rvalue reference-to - TYPE is a type node. */ static void @@ -1639,8 +1635,6 @@ write_type (tree type) break; case REFERENCE_TYPE: - if (TYPE_REF_IS_RVALUE (type)) - write_char('R'); write_char ('R'); write_type (TREE_TYPE (type)); break; diff --git a/contrib/gcc/cp/parser.c b/contrib/gcc/cp/parser.c index 0872c28e4617..a021d5bcdfa0 100644 --- a/contrib/gcc/cp/parser.c +++ b/contrib/gcc/cp/parser.c @@ -843,7 +843,7 @@ static cp_declarator *make_array_declarator static cp_declarator *make_pointer_declarator (cp_cv_quals, cp_declarator *); static cp_declarator *make_reference_declarator - (cp_cv_quals, cp_declarator *, bool); + (cp_cv_quals, cp_declarator *); static cp_parameter_declarator *make_parameter_declarator (cp_decl_specifier_seq *, cp_declarator *, tree); static cp_declarator *make_ptrmem_declarator @@ -937,15 +937,14 @@ make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target) /* Like make_pointer_declarator -- but for references. */ cp_declarator * -make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target, - bool rvalue_ref) +make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target) { cp_declarator *declarator; declarator = make_declarator (cdk_reference); declarator->declarator = target; - declarator->u.reference.qualifiers = cv_qualifiers; - declarator->u.reference.rvalue_ref = rvalue_ref; + declarator->u.pointer.qualifiers = cv_qualifiers; + declarator->u.pointer.class_type = NULL_TREE; return declarator; } @@ -1927,8 +1926,6 @@ static bool cp_parser_is_keyword (cp_token *, enum rid); static tree cp_parser_make_typename_type (cp_parser *, tree, tree); -static cp_declarator * cp_parser_make_indirect_declarator - (enum tree_code, tree, cp_cv_quals, cp_declarator *); /* Returns nonzero if we are parsing tentatively. */ @@ -2602,27 +2599,6 @@ cp_parser_make_typename_type (cp_parser *parser, tree scope, tree id) return make_typename_type (scope, id, typename_type, tf_error); } -/* This is a wrapper around the - make_{pointer,ptrmem,reference}_declarator functions that decides - which one to call based on the CODE and CLASS_TYPE arguments. The - CODE argument should be one of the values returned by - cp_parser_ptr_operator. */ -static cp_declarator * -cp_parser_make_indirect_declarator (enum tree_code code, tree class_type, - cp_cv_quals cv_qualifiers, - cp_declarator *target) -{ - if (code == INDIRECT_REF) - if (class_type == NULL_TREE) - return make_pointer_declarator (cv_qualifiers, target); - else - return make_ptrmem_declarator (cv_qualifiers, class_type, target); - else if (code == ADDR_EXPR && class_type == NULL_TREE) - return make_reference_declarator (cv_qualifiers, target, false); - else if (code == NON_LVALUE_EXPR && class_type == NULL_TREE) - return make_reference_declarator (cv_qualifiers, target, true); - gcc_unreachable (); -} /* Create a new C++ parser. */ @@ -5411,8 +5387,15 @@ cp_parser_new_declarator_opt (cp_parser* parser) /* Parse another optional declarator. */ declarator = cp_parser_new_declarator_opt (parser); - return cp_parser_make_indirect_declarator - (code, type, cv_quals, declarator); + /* Create the representation of the declarator. */ + if (type) + declarator = make_ptrmem_declarator (cv_quals, type, declarator); + else if (code == INDIRECT_REF) + declarator = make_pointer_declarator (cv_quals, declarator); + else + declarator = make_reference_declarator (cv_quals, declarator); + + return declarator; } /* If the next token is a `[', there is a direct-new-declarator. */ @@ -8071,8 +8054,16 @@ cp_parser_conversion_declarator_opt (cp_parser* parser) /* Parse another optional declarator. */ declarator = cp_parser_conversion_declarator_opt (parser); - return cp_parser_make_indirect_declarator - (code, class_type, cv_quals, declarator); + /* Create the representation of the declarator. */ + if (class_type) + declarator = make_ptrmem_declarator (cv_quals, class_type, + declarator); + else if (code == INDIRECT_REF) + declarator = make_pointer_declarator (cv_quals, declarator); + else + declarator = make_reference_declarator (cv_quals, declarator); + + return declarator; } return NULL; @@ -11531,8 +11522,15 @@ cp_parser_declarator (cp_parser* parser, && !cp_parser_parse_definitely (parser)) declarator = NULL; - declarator = cp_parser_make_indirect_declarator - (code, class_type, cv_quals, declarator); + /* Build the representation of the ptr-operator. */ + if (class_type) + declarator = make_ptrmem_declarator (cv_quals, + class_type, + declarator); + else if (code == INDIRECT_REF) + declarator = make_pointer_declarator (cv_quals, declarator); + else + declarator = make_reference_declarator (cv_quals, declarator); } /* Everything else is a direct-declarator. */ else @@ -11973,15 +11971,12 @@ cp_parser_direct_declarator (cp_parser* parser, & cv-qualifier-seq [opt] Returns INDIRECT_REF if a pointer, or pointer-to-member, was used. - Returns ADDR_EXPR if a reference was used, or NON_LVALUE_EXPR for - an rvalue reference. In the case of a pointer-to-member, *TYPE is - filled in with the TYPE containing the member. *CV_QUALS is - filled in with the cv-qualifier-seq, or TYPE_UNQUALIFIED, if there - are no cv-qualifiers. Returns ERROR_MARK if an error occurred. - Note that the tree codes returned by this function have nothing - to do with the types of trees that will be eventually be created - to represent the pointer or reference type being parsed. They are - just constants with suggestive names. */ + Returns ADDR_EXPR if a reference was used. In the case of a + pointer-to-member, *TYPE is filled in with the TYPE containing the + member. *CV_QUALS is filled in with the cv-qualifier-seq, or + TYPE_UNQUALIFIED, if there are no cv-qualifiers. Returns + ERROR_MARK if an error occurred. */ + static enum tree_code cp_parser_ptr_operator (cp_parser* parser, tree* type, @@ -11997,18 +11992,13 @@ cp_parser_ptr_operator (cp_parser* parser, /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); - - /* If it's a `*', `&' or `&&' we have a pointer or reference. */ - if (token->type == CPP_MULT) - code = INDIRECT_REF; - else if (token->type == CPP_AND) - code = ADDR_EXPR; - else if (flag_cpp0x && token->type == CPP_AND_AND) /* C++0x only */ - code = NON_LVALUE_EXPR; - - if (code != ERROR_MARK) + /* If it's a `*' or `&' we have a pointer or reference. */ + if (token->type == CPP_MULT || token->type == CPP_AND) { - /* Consume the `*', `&' or `&&'. */ + /* Remember which ptr-operator we were processing. */ + code = (token->type == CPP_AND ? ADDR_EXPR : INDIRECT_REF); + + /* Consume the `*' or `&'. */ cp_lexer_consume_token (parser->lexer); /* A `*' can be followed by a cv-qualifier-seq, and so can a diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c index 69170d608675..f12fc7b74d4e 100644 --- a/contrib/gcc/cp/pt.c +++ b/contrib/gcc/cp/pt.c @@ -110,8 +110,7 @@ static void tsubst_enum (tree, tree, tree); static tree add_to_template_args (tree, tree); static tree add_outermost_template_args (tree, tree); static bool check_instantiated_args (tree, tree, tsubst_flags_t); -static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*, - tree); +static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*); static int type_unification_real (tree, tree, tree, tree, int, unification_kind_t, int); static void note_template_header (int); @@ -7547,13 +7546,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) -- Attempting to create a pointer to reference type. -- Attempting to create a reference to a reference type or - a reference to void. - - Core issue 106 says that creating a reference to a reference - during instantiation is no longer a cause for failure. We - only enforce this check in strict C++98 mode. */ - if ((TREE_CODE (type) == REFERENCE_TYPE - && ((!flag_cpp0x && flag_iso) || code != REFERENCE_TYPE)) + a reference to void. */ + if (TREE_CODE (type) == REFERENCE_TYPE || (code == REFERENCE_TYPE && TREE_CODE (type) == VOID_TYPE)) { static location_t last_loc; @@ -7587,22 +7581,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (TREE_CODE (type) == METHOD_TYPE) r = build_ptrmemfunc_type (r); } - else if (TREE_CODE (type) == REFERENCE_TYPE) - /* In C++0x, during template argument substitution, when there is an - attempt to create a reference to a reference type, reference - collapsing is applied as described in [14.3.1/4 temp.arg.type]: - - "If a template-argument for a template-parameter T names a type - that is a reference to a type A, an attempt to create the type - 'lvalue reference to cv T' creates the type 'lvalue reference to - A,' while an attempt to create the type type rvalue reference to - cv T' creates the type T" - */ - r = cp_build_reference_type - (TREE_TYPE (type), - TYPE_REF_IS_RVALUE (t) && TYPE_REF_IS_RVALUE (type)); else - r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t)); + r = build_reference_type (type); r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain); if (r != error_mark_node) @@ -9812,14 +9792,12 @@ fn_type_unification (tree fn, sections are symmetric. PARM is the type of a function parameter or the return type of the conversion function. ARG is the type of the argument passed to the call, or the type of the value - initialized with the result of the conversion function. - ARG_EXPR is the original argument expression, which may be null. */ + initialized with the result of the conversion function. */ static int maybe_adjust_types_for_deduction (unification_kind_t strict, tree* parm, - tree* arg, - tree arg_expr) + tree* arg) { int result = 0; @@ -9873,16 +9851,6 @@ maybe_adjust_types_for_deduction (unification_kind_t strict, *arg = TYPE_MAIN_VARIANT (*arg); } - /* From C++0x [14.8.2.1/3 temp.deduct.call] (after DR606), "If P is - of the form T&&, where T is a template parameter, and the argument - is an lvalue, T is deduced as A& */ - if (TREE_CODE (*parm) == REFERENCE_TYPE - && TYPE_REF_IS_RVALUE (*parm) - && TREE_CODE (TREE_TYPE (*parm)) == TEMPLATE_TYPE_PARM - && cp_type_quals (TREE_TYPE (*parm)) == TYPE_UNQUALIFIED - && arg_expr && real_lvalue_p (arg_expr)) - *arg = build_reference_type (*arg); - /* [temp.deduct.call] If P is a cv-qualified type, the top level cv-qualifiers @@ -9919,7 +9887,7 @@ type_unification_real (tree tparms, unification_kind_t strict, int flags) { - tree parm, arg, arg_expr; + tree parm, arg; int i; int ntparms = TREE_VEC_LENGTH (tparms); int sub_strict; @@ -9961,7 +9929,6 @@ type_unification_real (tree tparms, parms = TREE_CHAIN (parms); arg = TREE_VALUE (args); args = TREE_CHAIN (args); - arg_expr = NULL; if (arg == error_mark_node) return 1; @@ -10011,7 +9978,6 @@ type_unification_real (tree tparms, return 1; } - arg_expr = arg; arg = unlowered_expr_type (arg); if (arg == error_mark_node) return 1; @@ -10021,8 +9987,7 @@ type_unification_real (tree tparms, int arg_strict = sub_strict; if (!subr) - arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg, - arg_expr); + arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg); if (unify (tparms, targs, parm, arg, arg_strict)) return 1; @@ -10199,7 +10164,7 @@ try_one_overload (tree tparms, else if (addr_p) arg = build_pointer_type (arg); - sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg, NULL); + sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg); /* We don't copy orig_targs for this because if we have already deduced some template args from previous args, unify would complain when we diff --git a/contrib/gcc/cp/tree.c b/contrib/gcc/cp/tree.c index 4e392f9924e2..eee91514bf24 100644 --- a/contrib/gcc/cp/tree.c +++ b/contrib/gcc/cp/tree.c @@ -64,28 +64,8 @@ lvalue_p_1 (tree ref, cp_lvalue_kind op1_lvalue_kind = clk_none; cp_lvalue_kind op2_lvalue_kind = clk_none; - /* Expressions of reference type are sometimes wrapped in - INDIRECT_REFs. INDIRECT_REFs are just internal compiler - representation, not part of the language, so we have to look - through them. */ - if (TREE_CODE (ref) == INDIRECT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) - == REFERENCE_TYPE) - return lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues); - if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE) - { - /* unnamed rvalue references are rvalues */ - if (TYPE_REF_IS_RVALUE (TREE_TYPE (ref)) - && TREE_CODE (ref) != PARM_DECL - && TREE_CODE (ref) != VAR_DECL - && TREE_CODE (ref) != COMPONENT_REF) - return clk_none; - - /* lvalue references and named rvalue refences are lvalues */ - return clk_ordinary; - } + return clk_ordinary; if (ref == current_class_ptr) return clk_none; @@ -471,53 +451,6 @@ build_cplus_array_type (tree elt_type, tree index_type) return t; } - -/* Return a reference type node referring to TO_TYPE. If RVAL is - true, return an rvalue reference type, otherwise return an lvalue - reference type. If a type node exists, reuse it, otherwise create - a new one. */ -tree -cp_build_reference_type (tree to_type, bool rval) -{ - tree lvalue_ref, t; - lvalue_ref = build_reference_type (to_type); - if (!rval) - return lvalue_ref; - - /* This code to create rvalue reference types is based on and tied - to the code creating lvalue reference types in the middle-end - functions build_reference_type_for_mode and build_reference_type. - - It works by putting the rvalue reference type nodes after the - lvalue reference nodes in the TYPE_NEXT_REF_TO linked list, so - they will effectively be ignored by the middle end. */ - - for (t = lvalue_ref; (t = TYPE_NEXT_REF_TO (t)); ) - if (TYPE_REF_IS_RVALUE (t)) - return t; - - t = copy_node (lvalue_ref); - - TYPE_REF_IS_RVALUE (t) = true; - TYPE_NEXT_REF_TO (t) = TYPE_NEXT_REF_TO (lvalue_ref); - TYPE_NEXT_REF_TO (lvalue_ref) = t; - TYPE_MAIN_VARIANT (t) = t; - - if (TYPE_STRUCTURAL_EQUALITY_P (to_type)) - SET_TYPE_STRUCTURAL_EQUALITY (t); - else if (TYPE_CANONICAL (to_type) != to_type) - TYPE_CANONICAL (t) - = cp_build_reference_type (TYPE_CANONICAL (to_type), rval); - else - TYPE_CANONICAL (t) = t; - - layout_type (t); - - return t; - -} - - /* Make a variant of TYPE, qualified with the TYPE_QUALS. Handles arrays correctly. In particular, if TYPE is an array of T's, and diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c index 9fd40c741840..34a301d62fa3 100644 --- a/contrib/gcc/cp/typeck.c +++ b/contrib/gcc/cp/typeck.c @@ -1039,12 +1039,8 @@ comptypes (tree t1, tree t2, int strict) return false; break; - case REFERENCE_TYPE: - if (TYPE_REF_IS_RVALUE (t1) != TYPE_REF_IS_RVALUE (t2)) - return false; - /* fall through to checks for pointer types */ - case POINTER_TYPE: + case REFERENCE_TYPE: if (TYPE_MODE (t1) != TYPE_MODE (t2) || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2) || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))) @@ -6503,7 +6499,6 @@ check_return_expr (tree retval, bool *no_warning) promotions. */ tree valtype; int fn_returns_value_p; - bool named_return_value_okay_p; *no_warning = false; @@ -6651,26 +6646,21 @@ check_return_expr (tree retval, bool *no_warning) See finish_function and finalize_nrv for the rest of this optimization. */ - named_return_value_okay_p = - (retval != NULL_TREE - /* Must be a local, automatic variable. */ - && TREE_CODE (retval) == VAR_DECL - && DECL_CONTEXT (retval) == current_function_decl - && ! TREE_STATIC (retval) - && (DECL_ALIGN (retval) - >= DECL_ALIGN (DECL_RESULT (current_function_decl))) - /* The cv-unqualified type of the returned value must be the - same as the cv-unqualified return type of the - function. */ - && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))), - (TYPE_MAIN_VARIANT - (TREE_TYPE (TREE_TYPE (current_function_decl)))))); - if (fn_returns_value_p && flag_elide_constructors) { - if (named_return_value_okay_p - && (current_function_return_value == NULL_TREE - || current_function_return_value == retval)) + if (retval != NULL_TREE + && (current_function_return_value == NULL_TREE + || current_function_return_value == retval) + && TREE_CODE (retval) == VAR_DECL + && DECL_CONTEXT (retval) == current_function_decl + && ! TREE_STATIC (retval) + && ! DECL_ANON_UNION_VAR_P (retval) + && (DECL_ALIGN (retval) + >= DECL_ALIGN (DECL_RESULT (current_function_decl))) + && same_type_p ((TYPE_MAIN_VARIANT + (TREE_TYPE (retval))), + (TYPE_MAIN_VARIANT + (TREE_TYPE (TREE_TYPE (current_function_decl)))))) current_function_return_value = retval; else current_function_return_value = error_mark_node; @@ -6689,29 +6679,18 @@ check_return_expr (tree retval, bool *no_warning) { /* The type the function is declared to return. */ tree functype = TREE_TYPE (TREE_TYPE (current_function_decl)); - int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING; /* The functype's return type will have been set to void, if it was an incomplete type. Just treat this as 'return;' */ if (VOID_TYPE_P (functype)) return error_mark_node; - /* 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 (flag_cpp0x - && named_return_value_okay_p - /* The variable must not have the `volatile' qualifier. */ - && !(cp_type_quals (TREE_TYPE (retval)) & TYPE_QUAL_VOLATILE) - /* The return type must be a class type. */ - && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) - flags = flags | LOOKUP_PREFER_RVALUE; - /* First convert the value to the function's return type, then to the type of return value's location to handle the case that functype is smaller than the valtype. */ retval = convert_for_initialization - (NULL_TREE, functype, retval, flags, "return", NULL_TREE, 0); + (NULL_TREE, functype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, + "return", NULL_TREE, 0); retval = convert (valtype, retval); /* If the conversion failed, treat this just like `return;'. */