C++ is a type-strong language. However, in practice, we always can write code like: “1 + 5.0f;”, in which “1” is of integer type, and “5.0f” is of floating point type. We can even write more amazing code like: “a + b;” assuming both “a” and “b” are instances of certain class. It dues to the compiler will generate code for us to do the necessary and appropriate conversions. In this section, we will see the conversions that compiler will use behind and rules of these conversions enacted by the language standard.
We first begin with function can_convert_arg , which is used to test if two specified types agree with each other.
5996 bool
5997 can_convert_arg (tree to, tree from, tree arg) in call.c
5998 {
5999 tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
6000 return (t && ! ICS_BAD_FLAG (t));
6001 }
Indicated by its name, conversions carried in below function, are those the compiler can be used freely as it considers as appropriately. It is one of interesting and powerful features of C++ language; and frequently confuses programmer even the seniors. In [3], section 13.3.3.1 “Implicit conversion sequences” explains what implicit conversion is in detail:
1. An implicit conversion sequence is a sequence of conversions used to convert an argument in a function call to the type of the corresponding parameter of the function being called. The sequence of conversions is an implicit conversion as defined in clause 4, which means it is governed by the rules for initialization of an object or reference by a single expression (8.5, 8.5.3). 2. Implicit conversion sequences are concerned only with the type, cv-qualification, and lvalueness of the argument and how these are converted to match the corresponding properties of the parameter. Other properties, such as the lifetime, storage class, alignment, or accessibility of the argument and whether or not the argument is a bit-field are ignored. So, although an implicit conversion sequence can be defined for a given argument-parameter pair, the conversion from the argument to the parameter might still be ill-formed in the final analysis. 3. A well-formed implicit conversion sequence is one of the following forms: — a standard conversion sequence (13.3.3.1.1), — a user-defined conversion sequence (13.3.3.1.2), or — an ellipsis conversion sequence (13.3.3.1.3). 4. However, when considering the argument of a user-defined conversion function that is a candidate by 13.3.1.3 when invoked for the copying of the temporary in the second step of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or 13.3.1.6 in all cases, only standard conversion sequences and ellipsis conversion sequences are allowed. 5. For the case where the parameter type is a reference, see 13.3.3.1.4. (reference binding ) 6. When the parameter type is not a reference, the implicit conversion sequence models a copy-initialization of the parameter from the argument expression. The implicit conversion sequence is the one required to convert the argument expression to an rvalue of the type of the parameter. [Note: when the parameter has a class type, this is a conceptual conversion defined for the purposes of clause 13; the actual initialization is defined in terms of constructors and is not a conversion.] Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion. [Example: a parameter of type A can be initialized from an argument of type const A. The implicit conversion sequence for that case is the identity sequence; it contains no “conversion” from const A to A.] When the parameter has a class type and the argument expression has the same type, the implicit conversion sequence is an identity conversion. When the parameter has a class type and the argument expression has a derived class type, the implicit conversion sequence is a derived-to-base Conversion from the derived class to the base class. [Note: there is no such standard conversion; this derived-to-base Conversion exists only in the description of implicit conversion sequences.] A derived-to-base Conversion has Conversion rank (13.3.3.1.1). 7. In all contexts, when converting to the implicit object parameter or when converting to the left operand of an assignment operation only standard conversion sequences that create no temporary object for the result are allowed. 8. If no conversions are required to match an argument to a parameter type, the implicit conversion sequence is the standard conversion sequence consisting of the identity conversion (13.3.3.1.1). 9. If no sequence of conversions can be found to convert an argument to a parameter type or the conversion is otherwise ill-formed, an implicit conversion sequence cannot be formed. 10. If several different sequences of conversions exist that each convert the argument to the parameter type, the implicit conversion sequence associated with the parameter is defined to be the unique conversion sequence designated the ambiguous conversion sequence. For the purpose of ranking implicit conversion sequences as described in 13.3.3.2, the ambiguous conversion sequence is treated as a user-defined sequence that is indistinguishable from any other user-defined conversion sequence (The ambiguous conversion sequence is ranked with user-defined conversion sequences because multiple conversion sequences for an argument can exist only if they involve different user-defined conversions. The ambiguous conversion sequence is indistinguishable from any other user-defined conversion sequence because it represents at least two user-defined conversion sequences, each with a different user-defined conversion, and any other user-defined conversion sequence must be indistinguishable from at least one of them. This rule prevents a function from becoming non-viable because of an ambiguous conversion sequence for one of its parameters. Consider this example, class B; class A { A (B&); }; class B { operator A (); }; class C { C (B&); }; void f(A) { } void f(C) { } B b; f(b); //ambiguous because b -> C via constructor and // b -> A via constructor or conversion function. If it were not for this rule, f(A) would be eliminated as a viable function for the call f(b) causing overload resolution to select f(C) as the function to call even though it is not clearly the best choice. On the other hand, if an f(B) were to be declared then f(b) would resolve to that f(B) because the exact match with f(B) is better than any of the sequences required to match f(A). If a function that uses the ambiguous conversion sequence is selected as the best viable function, the call will be ill-formed because the conversion of one of the arguments in the call is ambiguous. 11. The three forms of implicit conversion sequences mentioned above are defined in the following subclauses. |
Before going ahead into the code, first we need clarify the concept of lvalue and rvalue. An lvalue refers to an object or function. It must be an entity that is addressable; i.e., if it refers to object, it should be able to be placed on left-hand-side of an assignment operation (that is why it called lvalue). And those that are non-lvalue are called rvalue (which can’t be used on left-hand-side of assginment operation).
1097 static tree
1098 implicit_conversion (tree to, tree from, tree expr, int flags) in call.c
1099 {
1100 tree conv;
1101
1102 if (from == error_mark_node || to == error_mark_node
1103 || expr == error_mark_node)
1104 return NULL_TREE;
1105
1106 if (TREE_CODE (to) == REFERENCE_TYPE)
1107 conv = reference_binding (to, from, expr, flags);
1108 else
1109 conv = standard_conversion (to, from, expr, flags);
1110
1111 if (conv)
1112 return conv;
1113
1114 if (expr != NULL_TREE
1115 && (IS_AGGR_TYPE (from)
1116 || IS_AGGR_TYPE (to))
1117 && (flags & LOOKUP_NO_CONVERSION) == 0)
1118 {
1119 struct z_candidate *cand;
1120
1121 cand = build_user_type_conversion_1
1122 (to, expr, LOOKUP_ONLYCONVERTING);
1123 if (cand)
1124 conv = cand->second_conv;
1125
1126 /* We used to try to bind a reference to a temporary here, but that
1127 now handled by the recursive call to this function at the end
1128 of reference_binding. */
1129 return conv;
1130 }
1131
1132 return NULL_TREE;
1133 }
See the conversion processing routines may recurse each other, here to handle reference type, the function invokes reference_binding again. However, as we are going forward within the tree of the expression, as long as no loop back of dependence exists there will not be the infinite recursion. And as C++ is the language requires declaration before using, mutual dependence is illegal; the parser should be able to find out this ill form.
[3] section 13.3.3.1.1 “Standard conversion sequence” gives detail about the sequence.
1. Table 9 summarizes the conversions defined in clause 4 (“Standard conversions”, section 4 in [3]) and partitions them into four disjoint categories: Lvalue Transformation, Qualification Adjustment, Promotion, and Conversion. [Note: these categories are orthogonal with respect to lvalue-ness, cv-qualification, and data representation: the Lvalue Transformations do not change the cv-qualification or data representation of the type; the Qualification Adjustments do not change the lvalue -ness or data representation of the type; and the Promotions and Conversions do not change the lvalue-ness or cv-qualification of the type.] 2. [Note: As described in clause 4, a standard conversion sequence is either the Identity conversion by itself (that is, no conversion) or consists of one to three conversions from the other four categories. At most one conversion from each category is allowed in a single standard conversion sequence. If there are two or more conversions in the sequence, the conversions are applied in the canonical order: Lvalue Transformation , Promotion or Conversion , Qualification Adjustment . —end note ] 3. Each conversion in Table 9 also has an associated rank (Exact Match, Promotion, or Conversion). These are used to rank standard conversion sequences (13.3.3.2). The rank of a conversion sequence is determined by considering the rank of each conversion in the sequence and the rank of any reference binding (13.3.3.1.4). If any of those has Conversion rank, the sequence has Conversion rank; otherwise, if any of those has Promotion rank, the sequence has Promotion rank; otherwise, the sequence has Exact Match rank. Table 9: - conversions
|
Below we just skip the resolving of overload from line 472 to 479 (it will be covered by section about reference binding, remember type_unknown_p returns true if expr is an overload). Always keep in mind that below standard_conversion handles implicit conversion, only conversions mentioned in above table are considered; never confuse it with force conversion.
456 static tree
457 standard_conversion (tree to, tree from, tree expr, int flags) in call.c
458 {
459 enum tree_code fcode, tcode;
460 tree conv;
461 bool fromref = false;
462
463 to = v (to);
464 if (TREE_CODE (from) == REFERENCE_TYPE)
465 {
466 fromref = true;
467 from = TREE_TYPE (from);
468 }
469 to = strip_top_quals (to);
470 from = strip_top_quals (from);
471
472 if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
473 && expr && type_unknown_p (expr))
474 {
475 expr = instantiate_type (to, expr, tf_conv);
476 if (expr == error_mark_node)
477 return NULL_TREE;
478 from = TREE_TYPE (expr);
479 }
480
481 fcode = TREE_CODE (from);
482 tcode = TREE_CODE (to);
483
484 conv = build1 (IDENTITY_CONV, from, expr);
485
486 if (fcode == FUNCTION_TYPE)
487 {
488 from = build_pointer_type (from);
489 fcode = TREE_CODE (from);
490 conv = build_conv (LVALUE_CONV, from, conv);
491 }
492 else if (fcode == ARRAY_TYPE)
493 {
494 from = build_pointer_type (TREE_TYPE (from));
495 fcode = TREE_CODE (from);
496 conv = build_conv (LVALUE_CONV, from, conv);
497 }
498 else if (fromref || (expr && lvalue_p (expr)))
499 conv = build_conv (RVALUE_CONV, from, conv);
500
501 /* Allow conversion between `__complex__' data types. */
502 if (tcode == COMPLEX_TYPE && fcode == COMPLEX_TYPE)
503 {
504 /* The standard conversion sequence to convert FROM to TO is
505 the standard conversion sequence to perform componentwise
506 conversion. */
507 tree part_conv = standard_conversion
508 (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, flags);
509
510 if (part_conv)
511 {
512 conv = build_conv (TREE_CODE (part_conv), to, conv);
513 ICS_STD_RANK (conv) = ICS_STD_RANK (part_conv);
514 }
515 else
516 conv = NULL_TREE;
517
518 return conv;
519 }
520
521 if (same_type_p (from, to))
522 return conv;
Line 484 builds IDENTITY_COV for identity conversion. The type of *_CONV node indicates the source type and its first operand is the expression to be converted. So conversion sequence will be built with a big nested *_CONV node, with the top *_CONV is the last conversion being done, and the innermost being the first which always is IDENTITY_CONV.
In internal, the front-end defines following ranks for conversions instead those shown by table-9 above. And note that the less value indicates more preference.
343 #define IDENTITY_RANK 0 in call.c
344 #define EXACT_RANK 1
345 #define PROMO_RANK 2
346 #define STD_RANK 3
347 #define PBOOL_RANK 4
348 #define USER_RANK 5
349 #define ELLIPSIS_RANK 6
350 #define BAD_RANK 7
Conversions that can be generated internally include: IDENTITY_CONV, LVALUE_CONV, QUAL_CONV, STD_CONV, PTR_CONV, PMEM_CONV, BASE_CONV, REF_BIND, USER_CONV, AMBIG_CONV, and RVALUE_CONV.
408 static tree
409 build_conv (enum tree_code code, tree type, tree from) in call.c
410 {
411 tree t;
412 int rank = ICS_STD_RANK (from);
413
414 /* We can't use buildl1 here because CODE could be USER_CONV, which
415 takes two arguments. In that case, the caller is responsible for
416 filling in the second argument. */
417 t = make_node (code);
418 TREE_TYPE (t) = type;
419 TREE_OPERAND (t, 0) = from;
420
421 switch (code)
422 {
423 case PTR_CONV:
424 case PMEM_CONV:
425 case BASE_CONV:
426 case STD_CONV:
427 if (rank < STD_RANK)
428 rank = STD_RANK;
429 break ;
430
431 case QUAL_CONV:
432 if (rank < EXACT_RANK)
433 rank = EXACT_RANK;
434
435 default :
436 break ;
437 }
438 ICS_STD_RANK (t) = rank;
439 ICS_USER_FLAG (t) = (code == USER_CONV || ICS_USER_FLAG (from));
440 ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from);
441 return t;
442 }
In above function, ICS_STD_RANK in fact will store the highest rank value seen so far, whose usage we will see in later paragraphes.
Then above line 486 and 492 in standard_conversion handle function-to-pointer and array-to-point conversion, which is described by [3] clause 4.2 “Array-to-pointer conversion and clause” 4.3 “Function-to-pointer conversion” as below.
1. An lvalue or rvalue of type “array ofN T” or “array of unknown bound of T” can be converted to an rvalue of type “pointer to T.” The result is a pointer to the first element of the array. 2. A string literal (2.13.4) that is not a wide string literal can be converted to an rvalue of type “pointer to char”; a wide string literal can be converted to an rvalue of type “pointer to wchar_t”. In either case, the result is a pointer to the first element of the array. This conversion is considered only when there is an explicit appropriate pointer target type, and not when there is a general need to convert from an lvalue to an rvalue . [Note: this conversion is deprecated. See Annex D.] For the purpose of ranking in overload resolution (13.3.3.1.1), this conversion is considered an array-to-pointer conversion followed by a qualification conversion (4.4). [Example: "abc" is converted to “pointer to const char” as an array-to-pointer conversion, and then to “pointer to char” as a qualification conversion.] |
1. An lvalue of function type T can be converted to an rvalue of type “pointer to T.” The result is a pointer to the function. (This conversion never applies to nonstatic member functions because an lvalue that refers to a nonstatic member function cannot be obtained.) 2. [Note: See 13.4 for additional rules for the case where the function is overloaded.] |
Note that in terms 1 of both clauses, rvalue of type “pointer to T” just means the pointer itself can’t be modified, but its content can be changed. For example:
char a[10];
char *p = …;
a = p; // a is converted to rvalue of char*, assignment not allowed
*(a+1) = *p; // object pointed by a+1 is lvalue, it is OK
Compared with below clause, these two clauses include creation of pointer type, the front-end must tells out these two situations from other cases of lvalue transformation. So the front-end uses LVALUE_CONV for them.
Then in standard_conversion , arriving at line 498, if the condition is satisified, terms 1 mentioned in [3] clause 4.1 “Lvalue-to-rvalue conversion” will be implemented. The front-end uses RVALUE_CONV for the case. One difference of LVALUE_CONV and RVALUE_CONV is that when building LVALUE_CONV, we have known the rvalue (see the pointer type built at line 488 and 494), while for RVALUE_CONV, the rvalue is unknown at that point, and later the front-end needs invoke decay_conversion to do the real conversion.
1. An lvalue (3.10) of a non-function, non-array type T can be converted to an rvalue . If T is an incomplete type, a program that necessitates this conversion is ill-formed. If the object to which the lvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior. If T is a non-class type, the type of the rvalue is the cv-unqualified version of T. Otherwise, the type of the rvalue is T. [In C++ class rvalues can have cv-qualified types (because they are objects). This differs from ISO C, in which non-lvalues never have cv-qualified types.] 2. The value contained in the object indicated by the lvalue is the rvalue result. When an lvalue-to-rvalue conversion occurs within the operand of sizeof (5.3.3) the value contained in the referenced object is not accessed, since that operator does not evaluate its operand. |
Focus upon following function, given expression ref , it can tell if it is lvalue or not. And see that pointer type built for LVALUE_CONV above is rvalue told by this function. This function should be studied carefully.
211 int
212 lvalue_p (tree ref) in tree.c
213 {
214 return
215 (lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
216 }
The various kinds of lvalues we distinguish are given in below.
2964 typedef enum cp_lvalue_kind { in cp-tree.h
2965 clk_none = 0, /* Things that are not an lvalue. */
2966 clk_ordinary = 1, /* An ordinary lvalue. */
2967 clk_class = 2, /* An rvalue of class-type. */
2968 clk_bitfield = 4, /* An lvalue for a bit-field. */
2969 clk_packed = 8 /* An lvalue for a packed field. */
2970 } cp_lvalue_kind ;
In [3], clause 3.10 (lvalues and rvalues), gives the following explaination.
1. Every expression is either an lvalue or an rvalue . 2. An lvalue refers to an object or function. Some rvalue expressions—those of class or cv-qualified class type—also refer to objects (Expressions such as invocations of constructors and of functions that return a class type refer to objects, and the implementation can invoke a member function upon such objects, but the expressions are not lvalues ). 3. [Note: some built-in operators and function calls yield lvalues . [Example: if E is an expression of pointer type, then *E is an lvalue expression referring to the object or function to which E points. As another example, the function int& f(); yields an lvalue , so the call f() is an lvalue expression.]] 4. [Note: some builtin operators expect lvalue operands. [Example: built-in assignment operators all expect their left hand operands to be lvalues .] Other built-in operators yield rvalues , and some expect them. [Example: the unary and binary + operators expect rvalue arguments and yield rvalue results.] The discussion of each built-in operator in clause 5 indicates whether it expects lvalue operands and whether it yields an lvalue .] 5. The result of calling a function that does not return a reference is an rvalue . User defined operators are functions, and whether such operators expect or yield lvalues is determined by their parameter and return types. 6. An expression which holds a temporary object resulting from a cast to a nonreference type is an rvalue (this includes the explicit creation of an object using functional notation (5.2.3)). 7. Whenever an lvalue appears in a context where an rvalue is expected, the lvalue is converted to an rvalue ; see 4.1, 4.2, and 4.3. 8. The discussion of reference initialization in 8.5.3 and of temporaries in 12.2 indicates the behavior of lvalues and rvalues in other significant contexts. 9. Class rvalues can have cv-qualified types; non-class rvalues always have cv-unqualified types. Rvalues shall always have complete types or the void type; in addition to these types, lvalues can also have incomplete types. 10. An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [Example: a member function called for an object (9.3) can modify the object.] 11. Functions cannot be modified, but pointers to functions can be modifiable. 12. A pointer to an incomplete type can be modifiable. At some point in the program when the pointed to type is complete, the object at which the pointer points can also be modified. 13. The referent of a const-qualified expression shall not be modified (through that expression), except that if it is of class type and has a mutable component, that component can be modified (7.1.5.1). 14. If an expression can be used to modify the object to which it refers, the expression is called modifiable. A program that attempts to modify an object through a nonmodifiable lvalue or rvalue expression is illformed. 15. If a program attempts to access the stored value of an object through an lvalue of other than one of the following types the behavior is undefined (The intent of this list is to specify those circumstances in which an object may or may not be aliased): — the dynamic type of the object, — a cv-qualified version of the dynamic type of the object, — a type that is the signed or unsigned type corresponding to the dynamic type of the object, — a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object, — an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), — a type that is a (possibly cv-qualified) base class type of the dynamic type of the object, — a char or unsigned char type. |
Considering non-static method processed below, as non-static method must be invoked as: “a.fa();” with given object which may not addressable (for example, in statement “A().fa();”, “A()” returns an rvalue), non-static method is just considered as rvalue. Further, expression “A().fa();” can modify the object, so “A()” can be considered as lvalue if not require strict lvalue (argument treat_class_rvalues_as_lvalues is 1). Pay attention to TARGET_EXPR at line 156, it would wrapsthe temperary object returned by “A()” ( see comment at line 161).
62 static cp_lvalue_kind
63 lvalue_p_1 (tree ref, in tree.c
64 int treat_class_rvalues_as_lvalues)
65 {
66 cp_lvalue_kind op1_lvalue_kind = clk_none;
67 cp_lvalue_kind op2_lvalue_kind = clk_none;
68
69 if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
70 return clk_ordinary;
71
72 if (ref == current_class_ptr )
73 return clk_none;
74
75 switch (TREE_CODE (ref))
76 {
77 /* preincrements and predecrements are valid lvals, provided
78 what they refer to are valid lvals. */
79 case PREINCREMENT_EXPR:
80 case PREDECREMENT_EXPR:
81 case SAVE_EXPR:
82 case UNSAVE_EXPR:
83 case TRY_CATCH_EXPR:
84 case WITH_CLEANUP_EXPR:
85 case REALPART_EXPR:
86 case IMAGPART_EXPR:
87 return lvalue_p_1 (TREE_OPERAND (ref, 0),
88 treat_class_rvalues_as_lvalues);
89
90 case COMPONENT_REF:
91 op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
92 treat_class_rvalues_as_lvalues);
93 /* In an expression of the form "X.Y", the packed-ness of the
94 expression does not depend on "X". */
95 op1_lvalue_kind &= ~clk_packed;
96 /* Look at the member designator. */
97 if (!op1_lvalue_kind
98 /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
99 situations. */
100 || TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
101 ;
102 else if (DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
103 {
104 /* Clear the ordinary bit. If this object was a class
105 rvalue we want to preserve that information. */
106 op1_lvalue_kind &= ~clk_ordinary;
107 /* The lvalue is for a bitfield. */
108 op1_lvalue_kind |= clk_bitfield;
109 }
110 else if (DECL_PACKED (TREE_OPERAND (ref, 1)))
111 op1_lvalue_kind |= clk_packed;
112
113 return op1_lvalue_kind;
114
115 case STRING_CST:
116 return clk_ordinary;
117
118 case VAR_DECL:
119 if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
120 && DECL_LANG_SPECIFIC (ref)
121 && DECL_IN_AGGR_P (ref))
122 return clk_none;
123 case INDIRECT_REF:
124 case ARRAY_REF:
125 case PARM_DECL:
126 case RESULT_DECL:
127 if (TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
128 return clk_ordinary;
129 break ;
130
131 /* A currently unresolved scope ref. */
132 case SCOPE_REF:
133 abort ();
134 case MAX_EXPR:
135 case MIN_EXPR:
136 op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
137 treat_class_rvalues_as_lvalues);
138 op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
139 treat_class_rvalues_as_lvalues);
140 break ;
141
142 case COND_EXPR:
143 op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
144 treat_class_rvalues_as_lvalues);
145 op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2),
146 treat_class_rvalues_as_lvalues);
147 break ;
148
149 case MODIFY_EXPR:
150 return clk_ordinary;
151
152 case COMPOUND_EXPR:
153 return lvalue_p_1 (TREE_OPERAND (ref, 1),
154 treat_class_rvalues_as_lvalues);
155
156 case TARGET_EXPR:
157 return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
158
159 case CALL_EXPR:
160 case VA_ARG_EXPR:
161 /* Any class-valued call would be wrapped in a TARGET_EXPR. */
162 return clk_none;
163
164 case FUNCTION_DECL:
165 /* All functions (except non-static-member functions) are
166 lvalues. */
167 return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref)
168 ? clk_none : clk_ordinary);
169
170 case NON_DEPENDENT_EXPR:
171 /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
172 things like "&E" where "E" is an expression with a
173 non-dependent type work. It is safe to be lenient because an
174 error will be issued when the template is instantiated if "E"
175 is not an lvalue. */
176 return clk_ordinary;
177
178 default :
179 break ;
180 }
181
182 /* If one operand is not an lvalue at all, then this expression is
183 not an lvalue. */
184 if (!op1_lvalue_kind || !op2_lvalue_kind)
185 return clk_none;
186
187 /* Otherwise, it's an lvalue, and it has all the odd properties
188 contributed by either operand. */
189 op1_lvalue_kind = op1_lvalue_kind | op2_lvalue_kind;
190 /* It's not an ordinary lvalue if it involves either a bit-field or
191 a class rvalue. */
192 if ((op1_lvalue_kind & ~clk_ordinary) != clk_none)
193 op1_lvalue_kind &= ~clk_ordinary;
194 return op1_lvalue_kind;
195 }
Above, NON_DEPENDENT_EXPR is a placeholder for an expression that is not type-dependent, but does occur in a template. See INDIRECT_REF is lvalue (however pointer is rvalue itself, it is the case described by terms 3 above); and normal variable is also lvalue (line 118); further if an array is referred, its reference is lvalue, otherwise the array would be decayed to pointer of rvalue. Next note that MODIFY_EXPR at line 149, no doubt must be lvalue, and COMPOUND_EXPR following depends on its second operand. And for expressions may contains operand of lvalue, lvalue_p_1 recurs into the operand.
It is worth note that call expression “f();” of “int& f();” is lvalue, but expression like “f() = 5;” is illegal; the only case this lvalue can be used directly is using “f()” as parameter which is covered by PARM_DECL at line 125; so CALL_EXPR not within PARM_DECL is just regarded as rvalue. Further, being lvalue, PARM_DECL, RESULT_DECL, ARRAY_REF, and INDIRECT_REF can be of type of non-static method of class.
standard_conversion (continue)
524 if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to))
525 && expr && null_ptr_cst_p (expr))
526 conv = build_conv (STD_CONV, to, conv);
527 else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE
528 && TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE
529 && TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE
530 && ((*targetm .vector_opaque_p) (TREE_TYPE (to))
531 || (*targetm .vector_opaque_p) (TREE_TYPE (from))))
532 conv = build_conv (STD_CONV, to, conv);
533 else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
534 || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
535 {
536 /* For backwards brain damage compatibility, allow interconversion of
537 pointers and integers with a pedwarn. */
538 conv = build_conv (STD_CONV, to, conv);
539 ICS_BAD_FLAG (conv) = 1;
540 }
541 else if (tcode == ENUMERAL_TYPE && fcode == INTEGER_TYPE)
542 {
543 /* For backwards brain damage compatibility, allow interconversion of
544 enums and integers with a pedwarn. */
545 conv = build_conv (STD_CONV, to, conv);
546 ICS_BAD_FLAG (conv) = 1;
547 }
Note above, converting between pointers and integers and between integers and enums are both bad conversions in the context of C++ langauge (but it just gives warning under C). So the conversion is recorded and given the rank of lowest priority.
standard_conversion (continue)
548 else if ((tcode == POINTER_TYPE && fcode == POINTER_TYPE)
549 || (TYPE_PTRMEM_P (to) && TYPE_PTRMEM_P (from)))
550 {
551 tree to_pointee;
552 tree from_pointee;
553
554 if (tcode == POINTER_TYPE
555 && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (from),
556 TREE_TYPE (to)))
557 ;
558 else if (VOID_TYPE_P (TREE_TYPE (to))
559 && !TYPE_PTRMEM_P (from)
560 && TREE_CODE (TREE_TYPE (from)) != FUNCTION_TYPE)
561 {
562 from = build_pointer_type
563 (cp_build_qualified_type (void_type_node,
564 cp_type_quals (TREE_TYPE (from))));
565 conv = build_conv (PTR_CONV, from, conv);
566 }
567 else if (TYPE_PTRMEM_P (from))
568 {
569 tree fbase = TYPE_PTRMEM_CLASS_TYPE (from);
570 tree tbase = TYPE_PTRMEM_CLASS_TYPE (to);
571
572 if (DERIVED_FROM_P (fbase, tbase)
573 && (same_type_ignoring_top_level_qualifiers_p
574 (TYPE_PTRMEM_POINTED_TO_TYPE (from),
575 TYPE_PTRMEM_POINTED_TO_TYPE (to))))
576 {
577 from = build_ptrmem_type (tbase,
578 TYPE_PTRMEM_POINTED_TO_TYPE (from));
579 conv = build_conv (PMEM_CONV, from, conv);
580 }
581 else if (!same_type_p (fbase, tbase))
582 return NULL;
583 }
584 else if (IS_AGGR_TYPE (TREE_TYPE (from))
585 && IS_AGGR_TYPE (TREE_TYPE (to))
586 /* [conv.ptr]
587
588 An rvalue of type "pointer to cv D," where D is a
589 class type, can be converted to an rvalue of type
590 "pointer to cv B," where B is a base class (clause
591 _class.derived_) of D. If B is an inaccessible
592 (clause _class.access_) or ambiguous
593 (_class.member.lookup_) base class of D, a program
594 that necessitates this conversion is ill-formed. */
595 /* Therefore, we use DERIVED_FROM_P, and not
596 ACESSIBLY_UNIQUELY_DERIVED_FROM_P, in this test. */
597 && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
598 {
599 from =
600 cp_build_qualified_type (TREE_TYPE (to),
601 cp_type_quals (TREE_TYPE (from)));
602 from = build_pointer_type (from);
603 conv = build_conv (PTR_CONV, from, conv);
604 }
605
606 if (tcode == POINTER_TYPE)
607 {
608 to_pointee = TREE_TYPE (to);
609 from_pointee = TREE_TYPE (from);
610 }
611 else
612 {
613 to_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (to);
614 from_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (from);
615 }
616
617 if (same_type_p (from, to))
618 /* OK */ ;
619 else if (comp_ptr_ttypes (to_pointee, from_pointee))
620 conv = build_conv (QUAL_CONV, to, conv);
621 else if (expr && string_conv_p (to, expr, 0))
622 /* converting from string constant to char *. */
623 conv = build_conv (QUAL_CONV, to, conv);
624 else if (ptr_reasonably_similar (to_pointee, from_pointee))
625 {
626 conv = build_conv (PTR_CONV, to, conv);
627 ICS_BAD_FLAG (conv) = 1;
628 }
629 else
630 return 0;
631
632 from = to;
633 }
Again in [3] clause 4.10 “Pointer covnersions”, finds following paragraphes. And note that code at line 499 in the function has converted lvalue into rvalue, conv above holds the conversion.
1. A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of pointer to object or pointer to function type. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (4.4). 2. An rvalue of type “pointer to cv T,” where T is an object type, can be converted to an rvalue of type “pointer to cv void.” The result of converting a “pointer to cv T” to a “pointer to cv void” points to the start of the storage location where the object of type T resides, as if the object is a most derived object (1.8) of type T (that is, not a base class subobject). 3. An rvalue of type “pointer to cv D,” where D is a class type, can be converted to an rvalue of type “pointer to cv B,” where B is a base class (clause 10) of D. If B is an inaccessible (clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion is a pointer to the base class sub-object of the derived class object. The null pointer value is converted to the null pointer value of the destination type. |
Terms 1 is worked by line 526 above. It is one step STD_CONV. And condition of terms 2 is tested by code at line 558 ~ 560. Then condition in line 584 ~ 597 fullfils terms 3.
Further clause 4.11 “Pointer to member conversion” is shown in below.
1. A null pointer constant (4.10) can be converted to a pointer to member type; the result is the null member pointer value of that type and is distinguishable from any pointer to member not created from a null pointer constant. Two null member pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to member of cv-qualified type is a single conversion, and not the sequence of a pointer to member conversion followed by a qualification conversion (4.4). 2. An rvalue of type “pointer to member of B of type cv T,” where B is a class type, can be converted to an rvalue of type “pointer to member of D of type cv T,” where D is a derived class (clause 10) of B. If B is an inaccessible (clause 11), ambiguous (10.2) or virtual (10.1) base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion refers to the same member as the pointer to member before the conversion took place, but it refers to the base class member as if it were a member of the derived class. The result refers to the member in D’s instance of B. Since the result has type “pointer to member of D of type cv T,” it can be dereferenced with a D object. The result is the same as if the pointer to member of B were dereferenced with the B sub-object of D. The null member pointer value is converted to the null member pointer value of the destination type. [The rule for conversion of pointers to members (from pointer to member of base to pointer to member of derived) appears inverted compared to the rule for pointers to objects (from pointer to derived to pointer to base) (4.10, clause 10). This inversion is necessary to ensure type safety. Note that a pointer to member is not a pointer to object or a pointer to function and the rules for conversions of such pointers do not apply to pointers to members. In particular, a pointer to member cannot be converted to a void*.] |
Terms 1 is also covered by line 526 above. And terms 2 is handled by block at line 567. Arriving at line 617, with above conversion sequence, from and to should be either of same type, or just with different cv-qualifiers; otherwise, no conversion sequence is applicable.
Below conversion between pointer-to-method is similar with that of pointer-to-member. Note that fromfn and tofn are functions pointed respectively; fbase and tbase are the implicit this pointer each. So conversion can be carried out is: “an rvalue of type “pointer to method of B of type cv T,” where B is a class type, can be converted to an rvalue of type “pointer to the same method of D of type cv T,” where D is a derived class of B.” And see that “same” here is a little stricter than the that meaning among overloads.
standard_conversion (continue)
634 else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from))
635 {
636 tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from));
637 tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
638 tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));
639 tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));
640
641 if (!DERIVED_FROM_P (fbase, tbase)
642 || !same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
643 || !compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
644 TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
645 || cp_type_quals (fbase) != cp_type_quals (tbase))
646 return 0;
647
648 from = cp_build_qualified_type (tbase, cp_type_quals (fbase));
649 from = build_method_type_directly (from,
650 TREE_TYPE (fromfn),
651 TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
652 from = build_ptrmemfunc_type (build_pointer_type (from));
653 conv = build_conv (PMEM_CONV, from, conv);
654 }
[3], clause 4.12 “Boolean conversions” gives guideline how to do the conversion as below.
1. An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. |
However, conversion from pointer to boolean is alittle bit inferior to those of integer types.
standard_conversion (continue)
655 else if (tcode == BOOLEAN_TYPE)
656 {
657 /* [conv.bool]
658
659 An rvalue of arithmetic, enumeration, pointer, or pointer to
660 member type can be converted to an rvalue of type bool. */
661 if (ARITHMETIC_TYPE_P (from)
662 || fcode == ENUMERAL_TYPE
663 || fcode == POINTER_TYPE
664 || TYPE_PTR_TO_MEMBER_P (from))
665 {
666 conv = build_conv (STD_CONV, to, conv);
667 if (fcode == POINTER_TYPE
668 || TYPE_PTRMEM_P (from)
669 || (TYPE_PTRMEMFUNC_P (from)
670 && ICS_STD_RANK (conv) < PBOOL_RANK))
671 ICS_STD_RANK (conv) = PBOOL_RANK;
672 return conv;
673 }
674
675 return NULL_TREE;
676 }
Then below code handles coversions described by [3], clause 4.5 “Integeral promotions”, 4.6 “Floating point promotion”, 4.7 “Integral conversions”, 4.8 “Floating point conversions”, and 4.9 “Floating-integral conversions”. And below paragraphes give the detail.
1. An rvalue of type char , signed char , unsigned char , short int , or unsigned short int can be converted to an rvalue of type int if int can represent all the values of the source type; otherwise, the source rvalue can be converted to an rvalue of type unsigned int . 2. An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2) can be converted to an rvalue of the first of the following types that can represent all the values of its underlying type: int , unsigned int , long , or unsigned long . 3. An rvalue for an integral bit-field (9.6) can be converted to an rvalue of type int if int can represent all the values of the bit-field; otherwise, it can be converted to unsigned int if unsigned int can represent all the values of the bit-field. If the bit-field is larger yet, no integral promotion applies to it. If the bit-field has an enumerated type, it is treated as any other value of that type for promotion purposes. 4. An rvalue of type bool can be converted to an rvalue of type int , with false becoming zero and true becoming one. 5. These conversions are called integral promotions. |
1. An rvalue of type float can be converted to an rvalue of type double . The value is unchanged. 2. This conversion is called floating point promotion. |
1. An rvalue of an integer type can be converted to an rvalue of another integer type. An rvalue of an enumeration type can be converted to an rvalue of an integer type. 2. If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation).] 3. If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined. 4. If the destination type is bool , see 4.12. If the source type is bool , the value false is converted to zero and the value true is converted to one. 5. The conversions allowed as integral promotions are excluded from the set of integral conversions. |
1. An rvalue of floating point type can be converted to an rvalue of another floating point type. If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation. If the source value is between two adjacent destination values, the result of the conversion is an implementation-defined choice of either of those values. Otherwise, the behavior is undefined. 2. The conversions allowed as floating point promotions are excluded from the set of floating point conversions. |
1. An rvalue of a floating point type can be converted to an rvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be represented in the destination type. [Note:If the destination type is bool, see 4.12.] 2. An rvalue of an integer type or of an enumeration type can be converted to an rvalue of a floating point type. The result is exact if possible. Otherwise, it is an implementation-defined choice of either the next lower or higher representable value. [Note: loss of precision occurs if the integral value cannot be represented exactly as a value of the floating type.] If the source type is bool, the value false is converted to zero and the value true is converted to one. |
Code from line 679 to 690 covers all cases mentioned above. As PROMO_RANK is preferred to STD_RANK, it always uses PROMO_RANK as possible.
standard_conversion (continue)
677 /* We don't check for ENUMERAL_TYPE here because there are no standard
678 conversions to enum type. */
679 else if (tcode == INTEGER_TYPE || tcode == BOOLEAN_TYPE
680 || tcode == REAL_TYPE)
681 {
682 if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE))
683 return 0;
684 conv = build_conv (STD_CONV, to, conv);
685
686 /* Give this a better rank if it's a promotion. */
687 if (same_type_p (to, type_promotes_to (from))
688 && ICS_STD_RANK (TREE_OPERAND (conv, 0)) <= PROMO_RANK)
689 ICS_STD_RANK (conv) = PROMO_RANK;
690 }
691 else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
692 && ((*targetm .vector_opaque_p) (from)
693 || (*targetm .vector_opaque_p) (to)))
694 return build_conv (STD_CONV, to, conv);
695 else if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE)
696 && IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
697 && is_properly_derived_from (from, to))
698 {
699 if (TREE_CODE (conv) == RVALUE_CONV)
700 conv = TREE_OPERAND (conv, 0);
701 conv = build_conv (BASE_CONV, to, conv);
702 /* The derived-to-base conversion indicates the initialization
703 of a parameter with base type from an object of a derived
704 type. A temporary object is created to hold the result of
705 the conversion. */
706 NEED_TEMPORARY_P (conv) = 1;
707 }
708 else
709 return 0;
710
711 return conv;
712 }
Code between line 695 to 707 handles the case of derived-to-base conversion, which is defined by terms 6 of the clause “Implicit conversion sequeunces”.