Below, flag_elide_constructor by default is 1 which means attempt to elide constructors when possible. Whether the constructor (includes operator= (const X&) if defined) can be elided, depends on if it is trivial or not. Predicate TYPE_HAS_COMPLEX_INIT_REF holds if the class has non-trivial copy ctor; and TYPE_HAS_COMPLEX_ASSIGN_REF holds if the class has non-trivial “operator = (const X&)”.
build_over_call (continue)
4534 if (warn_format )
4535 check_function_format (NULL, TYPE_ATTRIBUTES (TREE_TYPE (fn)),
4536 converted_args);
4537
4538 /* Avoid actually calling copy constructors and copy assignment operators,
4539 if possible. */
4540
4541 if (! flag_elide_constructors )
4542 /* Do things the hard way. */ ;
4543 else if (TREE_VEC_LENGTH (convs) == 1
4544 && DECL_COPY_CONSTRUCTOR_P (fn))
4545 {
4546 tree targ;
4547 arg = skip_artificial_parms_for (fn, converted_args);
4548 arg = TREE_VALUE (arg);
4549
4550 /* Pull out the real argument, disregarding const-correctness. */
4551 targ = arg;
4552 while (TREE_CODE (targ) == NOP_EXPR
4553 || TREE_CODE (targ) == NON_LVALUE_EXPR
4554 || TREE_CODE (targ) == CONVERT_EXPR)
4555 targ = TREE_OPERAND (targ, 0);
4556 if (TREE_CODE (targ) == ADDR_EXPR)
4557 {
4558 targ = TREE_OPERAND (targ, 0);
4559 if (!same_type_ignoring_top_level_qualifiers_p
4560 (TREE_TYPE (TREE_TYPE (arg)), TREE_TYPE (targ)))
4561 targ = NULL_TREE;
4562 }
4563 else
4564 targ = NULL_TREE;
4565
4566 if (targ)
4567 arg = targ;
4568 else
4569 arg = build_indirect_ref (arg, 0);
4570
4571 /* [class.copy]: the copy constructor is implicitly defined even if
4572 the implementation elided its use. */
4573 if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
4574 mark_used (fn);
4575
4576 /* If we're creating a temp and we already have one, don't create a
4577 new one. If we're not creating a temp but we get one, use
4578 INIT_EXPR to collapse the temp into our target. Otherwise, if the
4579 ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
4580 temp or an INIT_EXPR otherwise. */
4581 if (integer_zerop (TREE_VALUE (args)))
4582 {
4583 if (TREE_CODE (arg) == TARGET_EXPR)
4584 return arg;
4585 else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
4586 return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
4587 }
4588 else if (TREE_CODE (arg) == TARGET_EXPR
4589 || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
4590 {
4591 tree to = stabilize_reference
4592 (build_indirect_ref (TREE_VALUE (args), 0));
4593
4594 val = build (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
4595 return val;
4596 }
4597 }
According to [3], clause 12.8 “Copying class objects”, terms 2:
A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6)). [Example: X::X(const X&) and X::X(X&, int=1) are copy constructors.
class X {
public :
X(int);
X(const X&, int = 1);
};
X a(1); // calls X(int);
X b(a, 0); // calls X(const X&, int);
X c = b; // calls X(const X&, int);
—end example ]
See in above, at line 4543, the value of “TREE_VEC_LENGTH (convs)” reflects the number of argumentsof the invocation (includes returned value); as constructor hasn’t returned value, here 1 means the argument number in calling this copy constructor is 1.
Before coming here, arguments undergo conversions described in previous sections, generally, can build a INDIRECT_REF node to represent this reference directly, unless it is already a reference. WHILE loop at line 4552 and IF statement at line 4556 discriminate references, consider below example:
void f (char& t) {}
void g (int& b) { f (*(char*)b); }
int main () {
int b = 5;
g (b);
}
Type gotten by “TREE_TYPE (TREE_TYPE (arg))” at line 4560 is “char”, while type gotten by “TREE_TYPE (targ)” is “int”, the reference type “int& b” can’t be used directly, it expects type “char&”.
Then if TYPE_HAS_COMPLEX_INIT_REF at line 4573 holds, it means the class defines copy constructor, has virtual base, or virtual method (obvious, such copy constructor is non-trival), mark_used is invoked to mark the copy ctor as used and synthesize its definition, if it is not declared by user but generated artifically by compiler.
At line 4581, args are the arguments of invocation. It is a tree_list with TREE_VALUE of every node holds the corresponding argument. In above example, TREE_VALUE (args) in “X b(a, 0)” is the implicit this pointer which is 0 (satisfies condition at line 4581); while in “X c = b”, it is “&c”. For the former case, it needs create the object (confined by C++ syntax, it can only be a temporary within a function), and for the rear one we can use ‘c’ as the subject of initialization. So in case TYPE_HAS_TRIVIAL_INIT_REF holds, we can ingore invoking copy constructor. And if the copy constructor can’t be avoided, we then go to below line 4637 to handle it.
Below at line 4599, copy_fn_p returns nonzero, if fn is a constructor or overloaded `operator='; and DECL_OVERLOADED_OPERATOR_P at line 4598 holds, if fn is an overloaded ‘operator=’; so to enter block at line 4601, it should be: fn is an overloaded ‘operator=’, but the assignment of this class type can use a bitwise copy (satisfies condition at line 4600).
build_over_call (continue)
4598 else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
4599 && copy_fn_p (fn)
4600 && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
4601 {
4602 tree to = stabilize_reference
4603 (build_indirect_ref (TREE_VALUE (converted_args), 0));
4604 tree type = TREE_TYPE (to);
4605 tree as_base = CLASSTYPE_AS_BASE (type);
4606
4607 arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0);
4608 if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
4609 val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
4610 else
4611 {
4612 /* We must only copy the non-tail padding parts. Use
4613 CLASSTYPE_AS_BASE for the bitwise copy. */
4614 tree to_ptr, arg_ptr, to_as_base, arg_as_base, base_ptr_type;
4615 tree save_to;
4616
4617 to_ptr = save_expr (build_unary_op (ADDR_EXPR, to, 0));
4618 arg_ptr = build_unary_op (ADDR_EXPR, arg, 0);
4619
4620 base_ptr_type = build_pointer_type (as_base);
4621 to_as_base = build_nop (base_ptr_type, to_ptr);
4622 to_as_base = build_indirect_ref (to_as_base, 0);
4623 arg_as_base = build_nop (base_ptr_type, arg_ptr);
4624 arg_as_base = build_indirect_ref (arg_as_base, 0);
4625
4626 save_to = build_indirect_ref (to_ptr, 0);
4627
4628 val = build (MODIFY_EXPR, as_base, to_as_base, arg_as_base);
4629 val = convert_to_void (val, NULL);
4630 val = build (COMPOUND_EXPR, type, val, save_to);
4631 TREE_NO_UNUSED_WARNING (val) = 1;
4632 }
4633
4634 return val;
4635 }
Line 4602 fetches the class type from the implicit this pointer. CLASSTYPE_AS_BASE at line 4605 returns the part of the class without virutal bases; however as the copy assignment is trivial, that means the class should not contain any virtual base. The class base returned should have the same size of the class; except if the class has padding bytes at tail (see in layout_class_type , the size of class base excludes tail padding bytes). The tail padding bytes should not be copied bitwise.
If the copy ctor or the overloaded ‘operator=’ is non-trivial, it needs below treatment to generate the code to invoking corresponding function.
build_over_call (continue)
4637 mark_used (fn);
4638
4639 if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
4640 {
4641 tree t, *p = &TREE_VALUE (converted_args);
4642 tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)),
4643 DECL_CONTEXT (fn),
4644 ba_any, NULL);
4645 my_friendly_assert (binfo && binfo != error_mark_node, 20010730);
4646
4647 *p = build_base_path (PLUS_EXPR, *p, binfo, 1);
4648 if (TREE_SIDE_EFFECTS (*p))
4649 *p = save_expr (*p);
4650 t = build_pointer_type (TREE_TYPE (fn));
4651 if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn)))
4652 fn = build_java_interface_fn_ref (fn, *p);
4653 else
4654 fn = build_vfn_ref (build_indirect_ref (*p, 0), DECL_VINDEX (fn));
4655 TREE_TYPE (fn) = t;
4656 }
4657 else if (DECL_INLINE (fn))
4658 fn = inline_conversion (fn);
4659 else
4660 fn = build_addr_func (fn);
4661
4662 return build_cxx_call (fn, args, converted_args);
4663 }
If the function invoked is not virtual, just takes its address and emits code to call it. For inline function, note that inline function unless explicitly referred by reference or pointer, should not have TREE_ADDRESSABLE set (build_addr_func sets the bit) as it is always expanded at the point of invocation.
1464 tree
1465 inline_conversion (tree exp) in typeck.c
1466 {
1467 if (TREE_CODE (exp) == FUNCTION_DECL)
1468 exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
1469
1470 return exp;
1471 }
While if the function is virtual function, first it needs to see whether the base defining function is accessible from the class specified by p . Then it adjusts the “this” argument to the base. Next we should get the address of virtual function from vtable. Note that instance below is node of INDIRECT_REF.
470 tree
471 build_vfn_ref (tree instance, tree idx) in class.c
472 {
473 tree aref = build_vtbl_ref_1 (instance, idx);
474
475 /* When using function descriptors, the address of the
476 vtable entry is treated as a function pointer. */
477 if (TARGET_VTABLE_USES_DESCRIPTORS)
478 aref = build1 (NOP_EXPR, TREE_TYPE (aref),
479 build_unary_op (ADDR_EXPR, aref, /*noconvert=*/ 1));
480
481 return aref;
482 }
Recall that “BINFO_VTABLE (binfo)” below at line 446 returns the vtable of the base binfo . As binfo belongs to binfo of the most derived class, in prevoius we have seenn that such vtable is part of that of the most derived class. And at line 437, fixed_type_or_null will return NULL, because instance is a pointer addition, fixed_type_or_null doesn’t know its dynamic type. Next build_vfield_ref will build COMPONENT_REF to represent this vtable accesses
427 ic tree
428 build_vtbl_ref_1 (tree instance, tree idx) in class.c
429 {
430 tree aref;
431 tree vtbl = NULL_TREE;
432
433 /* Try to figure out what a reference refers to, and
434 access its virtual function table directly. */
435
436 int cdtorp = 0;
437 tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
438
439 tree basetype = non_reference (TREE_TYPE (instance));
440
441 if (fixed_type && !cdtorp)
442 {
443 tree binfo = lookup_base (fixed_type, basetype,
444 ba_ignore|ba_quiet, NULL);
445 if (binfo)
446 vtbl = BINFO_VTABLE (binfo);
447 }
448
449 if (!vtbl)
450 vtbl = build_vfield_ref (instance, basetype);
451
452 assemble_external (vtbl);
453
454 aref = build_array_ref (vtbl, idx);
455
456 return aref;
457 }
At last, accessing the vtable at specified index, it can get the expected virtual function address, and code to invoking the virtual is generated by build_cxx_call at line 4662 above.
CHECK_COPY_CONSTRUCTOR_P is true in an IDENTITY_CONV or BASE_CONV if the copy constructor must be accessible, even though it is not being used. Remember the last conversion in the sequence is always IDENTITY_CONV.
And if we see an ambiguous conversion, coming here, it must through implicit conversion (implicit_conversion ). In this function, at calling build_user_type_conversion_1 , the argument flags is LOOKUP_ONLYCONVERTING which suppresses error message, so here invokes the function again with LOOKUP_NORMAL to give out the error message (here is the point the conversion is done, which is preferred by issuing error message).
convert_like_real (continue)
4017 case IDENTITY_CONV:
4018 if (type_unknown_p (expr))
4019 expr = instantiate_type (totype, expr, tf_error | tf_warning);
4020 /* Convert a non-array constant variable to its underlying
4021 value, unless we are about to bind it to a reference, in
4022 which case we need to leave it as an lvalue. */
4023 if (inner >= 0
4024 && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
4025 expr = decl_constant_value (expr);
4026 if (CHECK_COPY_CONSTRUCTOR_P (convs))
4027 check_constructor_callable (totype, expr);
4028
4029 return expr;
4030 case AMBIG_CONV:
4031 /* Call build_user_type_conversion again for the error. */
4032 return build_user_type_conversion
4033 (totype, TREE_OPERAND (convs, 0), LOOKUP_NORMAL);
4034
4035 default :
4036 break ;
4037 };
Note that above, USER_CONV, IDENTITY_CONV or AMBIG_CONV returns at the end of their CASE block; arriving at below code, it would be other conversions. Note the recursion below at line 4039, it is the only point in the function we can step down the whole sequence. So it is clear that USER_CONV, IDENTITY_CONV, and AMBIG_CONV are the exitting point for the recursion. It does so because the sequence links the conversions in reversed order (target followed by source). See that not all conversions in the sequence would be visited, for example, in user defined conversion, the IDENTITY_CONV which is always at tail would be skipped, because the recursion stops at USER_CONV.
convert_like_real (continue)
4039 expr = convert_like_real (TREE_OPERAND (convs, 0), expr, fn, argnum,
4040 TREE_CODE (convs) == REF_BIND ? -1 : 1,
4041 /*issue_conversion_warnings=*/ false);
4042 if (expr == error_mark_node)
4043 return error_mark_node;
4044
4045 switch (TREE_CODE (convs))
4046 {
4047 case RVALUE_CONV:
4048 if (! IS_AGGR_TYPE (totype))
4049 return expr;
4050 /* Else fall through. */
4051 case BASE_CONV:
4052 if (TREE_CODE (convs) == BASE_CONV && !NEED_TEMPORARY_P (convs))
4053 {
4054 /* We are going to bind a reference directly to a base-class
4055 subobject of EXPR. */
4056 if (CHECK_COPY_CONSTRUCTOR_P (convs))
4057 check_constructor_callable (TREE_TYPE (expr), expr);
4058 /* Build an expression for `*((base*) &expr)'. */
4059 expr = build_unary_op (ADDR_EXPR, expr, 0);
4060 expr = perform_implicit_conversion (build_pointer_type (totype),
4061 expr);
4062 expr = build_indirect_ref (expr, "implicit conversion");
4063 return expr;
4064 }
4065
4066 /* Copy-initialization where the cv-unqualified version of the source
4067 type is the same class as, or a derived class of, the class of the
4068 destination [is treated as direct-initialization]. [dcl.init] */
4069 expr = build_temp (expr, totype, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
4070 &diagnostic_fn);
4071 if (diagnostic_fn && fn)
4072 diagnostic_fn (" initializing argument %P of `%D'", argnum, fn);
4073 return build_cplus_new (totype, expr);
4074
4075 case REF_BIND:
4076 {
4077 tree ref_type = totype;
4078
4079 /* If necessary, create a temporary. */
4080 if (NEED_TEMPORARY_P (convs) || !lvalue_p (expr))
4081 {
4082 tree type = TREE_TYPE (TREE_OPERAND (convs, 0));
4083 cp_lvalue_kind lvalue = real_lvalue_p (expr);
4084
4085 if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
4086 {
4087 /* If the reference is volatile or non-const, we
4088 cannot create a temporary. */
4089 if (lvalue & clk_bitfield)
4090 error ("cannot bind bitfield `%E' to `%T'",
4091 expr, ref_type);
4092 else if (lvalue & clk_packed)
4093 error ("cannot bind packed field `%E' to `%T'",
4094 expr, ref_type);
4095 else
4096 error ("cannot bind rvalue `%E' to `%T'", expr, ref_type);
4097 return error_mark_node;
4098 }
4099 /* If the source is a packed field, and we must use a copy
4100 constructor, then building the target expr will require
4101 binding the field to the reference parameter to the
4102 copy constructor, and we'll end up with an infinite
4103 loop. If we can use a bitwise copy, then we'll be
4104 OK. */
4105 if ((lvalue & clk_packed)
4106 && CLASS_TYPE_P (type)
4107 && !TYPE_HAS_TRIVIAL_INIT_REF (type))
4108 {
4109 error ("cannot bind packed field `%E' to `%T'",
4110 expr, ref_type);
4111 return error_mark_node;
4112 }
4113 expr = build_target_expr_with_type (expr, type);
4114 }
4115
4116 /* Take the address of the thing to which we will bind the
4117 reference. */
4118 expr = build_unary_op (ADDR_EXPR, expr, 1);
4119 if (expr == error_mark_node)
4120 return error_mark_node;
4121
4122 /* Convert it to a pointer to the type referred to by the
4123 reference. This will adjust the pointer if a derived to
4124 base conversion is being performed. */
4125 expr = cp_convert (build_pointer_type (TREE_TYPE (ref_type)),
4126 expr);
4127 /* Convert the pointer to the desired reference type. */
4128 return build_nop (ref_type, expr);
4129 }
4130
4131 case LVALUE_CONV:
4132 return decay_conversion (expr);
4133
4134 case QUAL_CONV:
4135 /* Warn about deprecated conversion if appropriate. */
4136 string_conv_p (totype, expr, 1);
4137 break ;
4138
4139 default :
4140 break ;
4141 }
4142 return ocp_convert (totype, expr, CONV_IMPLICIT,
4143 LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
4144 }
Obvious, LVALUE_CONV, RVALUE_CONV, REF_BIND, QUAL_CONV, and BASE_CONV here are performed according to steps of converting source to target type. Conversions of PTR_CONV, QUAL_CONV, and PMEM_CONV are processed in below function.
Below argument convtype is a collect of bitfields, in which bit CONV_FORCE_TEMP means to require a new temporary when converting to the same aggregate type (however within our inovcation context here, the argument is CONV_IMPLICIT which means to perform implicit conversions). The function converts expression passed in argument expr to the type specified by the argument type .
614 tree
615 ocp_convert (tree type, tree expr, int convtype, int flags) in cvt.c
616 {
617 tree e = expr;
618 enum tree_code code = TREE_CODE (type);
619
620 if (error_operand_p (e) || type == error_mark_node)
621 return error_mark_node;
622
623 complete_type (type);
624 complete_type (TREE_TYPE (expr));
625
626 e = decl_constant_value (e);
627
628 if (IS_AGGR_TYPE (type) && (convtype & CONV_FORCE_TEMP)
629 /* Some internal structures (vtable_entry_type, sigtbl_ptr_type)
630 don't go through finish_struct, so they don't have the synthesized
631 constructors. So don't force a temporary. */
632 && TYPE_HAS_CONSTRUCTOR (type))
633 /* We need a new temporary; don't take this shortcut. */ ;
634 else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
635 {
636 if (same_type_p (type, TREE_TYPE (e)))
637 /* The call to fold will not always remove the NOP_EXPR as
638 might be expected, since if one of the types is a typedef;
639 the comparison in fold is just equality of pointers, not a
640 call to comptypes. We don't call fold in this case because
641 that can result in infinite recursion; fold will call
642 convert, which will call ocp_convert, etc. */
643 return e;
644 /* For complex data types, we need to perform componentwise
645 conversion. */
646 else if (TREE_CODE (type) == COMPLEX_TYPE)
647 return fold (convert_to_complex (type, e));
648 else if (TREE_CODE (e) == TARGET_EXPR)
649 {
650 /* Don't build a NOP_EXPR of class type. Instead, change the
651 type of the temporary. Only allow this for cv-qual changes,
652 though. */
653 if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (e)),
654 TYPE_MAIN_VARIANT (type)))
655 abort ();
656 TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
657 return e;
658 }
659 else if (TREE_ADDRESSABLE (type))
660 /* We shouldn't be treating objects of ADDRESSABLE type as rvalues. */
661 abort ();
662 else
663 return fold (build1 (NOP_EXPR, type, e));
664 }
665
666 if (code == VOID_TYPE && (convtype & CONV_STATIC))
667 {
668 e = convert_to_void (e, /*implicit=*/ NULL);
669 return e;
670 }
671
672 if (INTEGRAL_CODE_P (code))
673 {
674 tree intype = TREE_TYPE (e);
675 /* enum = enum, enum = int, enum = float, (enum)pointer are all
676 errors. */
677 if (TREE_CODE (type) == ENUMERAL_TYPE
678 && ((ARITHMETIC_TYPE_P (intype) && ! (convtype & CONV_STATIC))
679 || (TREE_CODE (intype) == POINTER_TYPE)))
680 {
681 pedwarn ("conversion from `%#T' to `%#T'", intype, type);
682
683 if (flag_pedantic_errors )
684 return error_mark_node;
685 }
686 if (IS_AGGR_TYPE (intype))
687 {
688 tree rval;
689 rval = build_type_conversion (type, e);
690 if (rval)
691 return rval;
692 if (flags & LOOKUP_COMPLAIN)
693 error ("`%#T' used where a `%T' was expected", intype, type);
694 if (flags & LOOKUP_SPECULATIVELY)
695 return NULL_TREE;
696 return error_mark_node;
697 }
698 if (code == BOOLEAN_TYPE)
699 return cp_truthvalue_conversion (e);
700
701 return fold (convert_to_integer (type, e));
702 }
703 if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type))
704 return fold (cp_convert_to_pointer (type, e, false));
Above, line from 672 to 702 processes conversion to integer type. The function would be used for static_cast , const_cast , and reinterpret_cast , which are represented by the bitfield of CONV_STATIC, CONV_CONST and CONV_REINTERPRET respectively. In above code, it can see clearly the restriction of the casts.