Studying note of GCC-3.4.6 source (148 continue)

 

Read below comment carefully before going ahead. In fact there is another possibility that we will drop in below. Considering below exampe:

void f (unsigned short i) {}

void f(unsigned char i) {}

int main () {

   f (5);

}

The standard conversion sequences of both functions’ argument are not subsequence to each other; it needs below code to do further judgement.

 

compare_ics (continue)

 

5417    /* Otherwise, one sequence cannot be a subsequence of the other; they

5418      don't start with the same type. This can happen when comparing the

5419      second standard conversion sequence in two user-defined conversion

5420      sequences.  */

 

Recall that in build_conv , ICS_STD_RANK of the first node in the sequence is the lowest rank seen in the standard conversion sequence (as it is built in canonical order reversely). Different standard conversion sequences can be ordered by ICS_STD_RANK of their first node.

Note that in front-end, it deliberately adds PBOOL_RANK between STD_RANK and USER_RANK, and which still is regarded as one of STD_CONV, so comparison between ICS_STD_RANKs can handle case “A conversion that is not a conversion of a pointer, or pointer to member, to bool is better than another conversion that is such a conversion.” automatically.

 

compare_ics (continue)

 

5422    /* [over.ics.rank]

5423

5424      Or, if not that,

5425

5426      --the rank of S1 is better than the rank of S2 (by the rules

5427        defined below):

5428

5429      Standard conversion sequences are ordered by their ranks: an Exact

5430      Match is a better conversion than a Promotion, which is a better

5431      conversion than a Conversion.

5432

5433      Two conversion sequences with the same rank are indistinguishable

5434      unless one of the following rules applies:

5435

5436      --A conversion that is not a conversion of a pointer, or pointer

5437       to member, to bool is better than another conversion that is such

5438       a conversion. 

5439

5440      The ICS_STD_RANK automatically handles the pointer-to-bool rule,

5441      so that we do not have to check it explicitly.  */

5442    if (ICS_STD_RANK (ics1) < ICS_STD_RANK (ics2))

5443      return 1;

5444    else if (ICS_STD_RANK (ics2) < ICS_STD_RANK (ics1))

5445      return -1;

5446

5447    to_type1 = TREE_TYPE (ics1);

5448    to_type2 = TREE_TYPE (ics2);

5449

5450    if (TYPE_PTR_P (from_type1)

5451        && TYPE_PTR_P (from_type2)

5452        && TYPE_PTR_P (to_type1)

5453        && TYPE_PTR_P (to_type2))

5454    {

5455      deref_from_type1 = TREE_TYPE (from_type1);

5456      deref_from_type2 = TREE_TYPE (from_type2);

5457      deref_to_type1 = TREE_TYPE (to_type1);

5458      deref_to_type2 = TREE_TYPE (to_type2);

5459    }

5460    /* The rules for pointers to members A::* are just like the rules

5461      for pointers A*, except opposite: if B is derived from A then

5462      A ::* converts to B::*, not vice versa. For that reason, we

5463      switch the from_ and to_ variables here.  */

5464    else if ((TYPE_PTRMEM_P (from_type1) && TYPE_PTRMEM_P (from_type2)

5465             && TYPE_PTRMEM_P (to_type1) && TYPE_PTRMEM_P (to_type2))

5466           || (TYPE_PTRMEMFUNC_P (from_type1)

5467             && TYPE_PTRMEMFUNC_P (from_type2)

5468             && TYPE_PTRMEMFUNC_P (to_type1)

5469             && TYPE_PTRMEMFUNC_P (to_type2)))

5470    {

5471      deref_to_type1 = TYPE_PTRMEM_CLASS_TYPE (from_type1);

5472      deref_to_type2 = TYPE_PTRMEM_CLASS_TYPE (from_type2);

5473      deref_from_type1 = TYPE_PTRMEM_CLASS_TYPE (to_type1);

5474      deref_from_type2 = TYPE_PTRMEM_CLASS_TYPE (to_type2);

5475    }

5476

5477    if (deref_from_type1 != NULL_TREE

5478        && IS_AGGR_TYPE_CODE (TREE_CODE (deref_from_type1))

5479        && IS_AGGR_TYPE_CODE (TREE_CODE (deref_from_type2)))

5480    {

5481      /* This was one of the pointer or pointer-like conversions. 

5482

5483        [over.ics.rank]

5484   

5485        --If class B is derived directly or indirectly from class A,

5486         conversion of B* to A* is better than conversion of B* to

5487         void*, and conversion of A* to void* is better than

5488         conversion of B* to void*.  */

5489      if (TREE_CODE (deref_to_type1) == VOID_TYPE

5490         && TREE_CODE (deref_to_type2) == VOID_TYPE)

5491      {

5492        if (is_properly_derived_from (deref_from_type1,

5493                                 deref_from_type2))

5494          return -1;

5495        else if (is_properly_derived_from (deref_from_type2,

5496                                     deref_from_type1))

5497          return 1;

5498      }

5499      else if (TREE_CODE (deref_to_type1) == VOID_TYPE

5500             || TREE_CODE (deref_to_type2) == VOID_TYPE)

5501      {

5502        if (same_type_p (deref_from_type1, deref_from_type2))

5503        {

5504          if (TREE_CODE (deref_to_type2) == VOID_TYPE)

5505          {

5506            if (is_properly_derived_from (deref_from_type1,

5507                                      deref_to_type1))

5508              return 1;

5509          }

5510          /* We know that DEREF_TO_TYPE1 is `void' here.  */

5511          else if (is_properly_derived_from (deref_from_type1,

5512                                        deref_to_type2))

5513            return -1;

5514        }

5515      }

5516      else if (IS_AGGR_TYPE_CODE (TREE_CODE (deref_to_type1))

5517             && IS_AGGR_TYPE_CODE (TREE_CODE (deref_to_type2)))

5518      {

5519        /* [over.ics.rank]

5520

5521          --If class B is derived directly or indirectly from class A

5522           and class C is derived directly or indirectly from B,

5523        

5524          --conversion of C* to B* is better than conversion of C* to

5525            A *,

5526        

5527          --conversion of B* to A* is better than conversion of C* to

5528            A *  */

5529        if (same_type_p (deref_from_type1, deref_from_type2))

5530        {

5531          if (is_properly_derived_from (deref_to_type1,

5532                                   deref_to_type2))

5533            return 1;

5534          else if (is_properly_derived_from (deref_to_type2,

5535                                       deref_to_type1))

5536            return -1;

5537        }

5538        else if (same_type_p (deref_to_type1, deref_to_type2))

5539        {

5540          if (is_properly_derived_from (deref_from_type2,

5541                                   deref_from_type1))

5542            return 1;

5543          else if (is_properly_derived_from (deref_from_type1,

5544                                      deref_from_type2))

5545             return -1;

5546        }

5547      }

5548    }

 

Note ELES IF block at line 5464. If the code switches the ‘from’ and ‘to’ types (more precisely, ‘from’ type always refers to the derived class, and ‘to’ type refers to the base class), then it can combine 4 cases below ([3], clause 13.3.3.2):

conversion of C* to B* is better than conversion of C* to A*

conversion of B* to A* is better than conversion of C* to A*

conversion of B::* to C::* is better than conversion of A::* to C::*

conversion of A::* to B::* is better than conversion of A::* to C::*

into 2 cases:

conversion of C* to B* is better than conversion of C* to A*

conversion of B* to A* is better than conversion of C* to A*

 

5216 bool

5217 is_properly_derived_from (tree derived, tree base)                                              in call.c

5218 {

5219    if (!IS_AGGR_TYPE_CODE (TREE_CODE (derived))

5220        || !IS_AGGR_TYPE_CODE (TREE_CODE (base)))

5221      return false;

5222

5223    /* We only allow proper derivation here. The DERIVED_FROM_P macro

5224      considers every class derived from itself.  */

5225    return (!same_type_ignoring_top_level_qualifiers_p (derived, base)

5226           && DERIVED_FROM_P (base, derived));

5227 }

 

Note that if derived is the same type of base , is_properly_derived_from will return false, as DERIVED_FROM_P uses lookup_base for the looking up, which will only search bases of derived . And below non_reference takes TREE_TYPE from REFERENCE_TYPE, and doesn’t touch other nodes.

 

compare_ics (continue)

 

5549    else if (CLASS_TYPE_P (non_reference (from_type1))

5550          && same_type_p (from_type1, from_type2))

5551    {

5552      tree from = non_reference (from_type1);

5553

5554      /* [over.ics.rank]

5555  

5556        --binding of an expression of type C to a reference of type

5557         B& is better than binding an expression of type C to a

5558         reference of type A&

5559

5560        --conversion of C to B is better than conversion of C to A,  */

5561      if (is_properly_derived_from (from, to_type1)

5562          && is_properly_derived_from (from, to_type2))

5563      {

5564        if (is_properly_derived_from (to_type1, to_type2))

5565          return 1;

5566        else if (is_properly_derived_from (to_type2, to_type1))

5567          return -1;

5568      }

5569    }

5570    else if (CLASS_TYPE_P (non_reference (to_type1))

5571          && same_type_p (to_type1, to_type2))

5572    {

5573      tree to = non_reference (to_type1);

5574

5575      /* [over.ics.rank]

5576

5577        --binding of an expression of type B to a reference of type

5578         A & is better than binding an expression of type C to a

5579         reference of type A&,

5580

5581        --conversion of B to A is better than conversion of C to A  */

5582      if (is_properly_derived_from (from_type1, to)

5583         && is_properly_derived_from (from_type2, to))

5584      {

5585        if (is_properly_derived_from (from_type2, from_type1))

5586          return 1;

5587        else if (is_properly_derived_from (from_type1, from_type2))

5588          return -1;

5589      }

5590    }

5591

5592    /* [over.ics.rank]

5593

5594       --S1 and S2 differ only in their qualification conversion and yield

5595        similar types T1 and T2 (_conv.qual_), respectively, and the cv-

5596        qualification signature of type T1 is a proper subset of the cv-

5597        qualification signature of type T2  */

5598    if (TREE_CODE (ics1) == QUAL_CONV

5599        && TREE_CODE (ics2) == QUAL_CONV

5600        && same_type_p (from_type1, from_type2))

5601      return comp_cv_qual_signature (to_type1, to_type2);

5602

5603    /* [over.ics.rank]

5604      

5605       --S1 and S2 are reference bindings (_dcl.init.ref_), and the

5606       types to which the references refer are the same type except for

5607       top-level cv-qualifiers, and the type to which the reference

5608       initialized by S2 refers is more cv-qualified than the type to

5609       which the reference initialized by S1 refers */

5610       

5611    if (target_type1 && target_type2

5612        && same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2))

5613      return comp_cv_qualification (target_type2, target_type1);

5614

5615    /* Neither conversion sequence is better than the other.  */

5616    return 0;

5617 }

 

At line 5704 in joust , compare_ics returns the result into comp which if nonzero, means we have known who is better. Then at line 5708, warn_sign_promo if nonzero, means warn where overload resolution chooses a promotion from unsigned to signed over a conversion to an unsigned of the same size.

And note that compare_ics here is invoked for every pair of arguments, so the winner found every time must be the same; otherwise it needs use extension rule to do the judgement. Arriving at below code and with winner nonzero, it indicates the better has been found.

 

joust (continue)

 

5749    /* warn about confusing overload resolution for user-defined conversions,

5750      either between a constructor and a conversion op, or between two

5751      conversion ops.  */

5752    if (winner && warn_conversion && cand1->second_conv

5753       && (!DECL_CONSTRUCTOR_P (cand1->fn) || !DECL_CONSTRUCTOR_P (cand2->fn))

5754       && winner != compare_ics (cand1->second_conv, cand2->second_conv))

5755    {

5756      struct z_candidate *w, *l;

5757      bool give_warning = false;

5758       

5759      if (winner == 1)

5760        w = cand1, l = cand2;

5761      else

5762        w = cand2, l = cand1;

5763       

5764      /* We don't want to complain about `X::operator T1 ()'

5765        beating `X::operator T2 () const', when T2 is a no less

5766        cv-qualified version of T1.  */

5767      if (DECL_CONTEXT (w->fn) == DECL_CONTEXT (l->fn)

5768         && !DECL_CONSTRUCTOR_P (w->fn) && !DECL_CONSTRUCTOR_P (l->fn))

5769      {

5770        tree t = TREE_TYPE (TREE_TYPE (l->fn));

5771        tree f = TREE_TYPE (TREE_TYPE (w->fn));

5772     

5773        if (TREE_CODE (t) == TREE_CODE (f) && POINTER_TYPE_P (t))

5774        {

5775          t = TREE_TYPE (t);

5776          f = TREE_TYPE (f);

5777        }

5778        if (!comp_ptr_ttypes (t, f))

5779          give_warning = true;

5780      }

5781      else

5782        give_warning = true;

5783       

5784      if (!give_warning)

5785        /*NOP*/ ;

5786      else if (warn)

5787      {

5788        tree source = source_type (TREE_VEC_ELT (w->convs, 0));

5789        if (! DECL_CONSTRUCTOR_P (w->fn))

5790          source = TREE_TYPE (source);

5791        warning ("choosing `%D' over `%D'", w->fn, l->fn);

5792         warning ("  for conversion from `%T' to `%T'",

5793                source, TREE_TYPE (w->second_conv));

5794        warning ("  because conversion sequence for the argument is better");

5795      }

5796      else

5797        add_warning (w, l);

5798    }

5799

5800    if (winner)

5801      return winner;

 

Above warn_conversion if nonzero, warns if a type conversion is done that might have confusing results. See if holds condtion at line 5754, it means compare_ics finds that the candidate found superior with conversions for arguments is inferior in conversion for the returned value; however, the finding will never change the selecting result.

If both candidates are found i ndistinguishable in arguments conversions, winner is 0 here, then goes ahead. First of all, non-template is always superior to template one; and more specialized template is superior to more generalized one. Except that, the better conversion sequence for the returned value tells the winner.

 

joust (continue)

 

5803    /* or, if not that,

5804      F 1 is a non-template function and F2 is a template function

5805      specialization.  */

5806          

5807    if (! cand1->template && cand2->template)

5808      return 1;

5809    else if (cand1->template && ! cand2->template)

5810      return -1;

5811   

5812    /* or, if not that,

5813      F 1 and F2 are template functions and the function template for F1 is

5814      more specialized than the template for F2 according to the partial

5815      ordering rules.  */

5816   

5817    if (cand1->template && cand2->template)

5818    {

5819      winner = more_specialized

5820           (TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),

5821            DEDUCE_ORDER,

5822            /* Tell the deduction code how many real function arguments

5823              we saw, not counting the implicit 'this' argument. But,

5824              add_function_candidate() suppresses the "this" argument

5825              for constructors.

5826

5827              [temp.func.order]: The presence of unused ellipsis and default

5828               arguments has no effect on the partial ordering of function

5829              templates.  */

5830            TREE_VEC_LENGTH (cand1->convs)

5831               - (DECL_NONSTATIC_MEMBER_FUNCTION_P (cand1->fn)

5832               - DECL_CONSTRUCTOR_P (cand1->fn)));

5833      if (winner)

5834        return winner;

5835    }

5836

5837    /* or, if not that,

5838      the context is an initialization by user-defined conversion (see

5839      _dcl.init_ and _over.match.user_) and the standard  conversion

5840      sequence from the return type of F1 to the destination type (i.e.,

5841      the type of the entity being initialized) is a better conversion

5842      sequence than the standard conversion sequence from the return type

5843      of F2 to the destination type.  */

5844

5845    if (cand1->second_conv)

5846    {

5847      winner = compare_ics (cand1->second_conv, cand2->second_conv);

5848      if (winner)

5849        return winner;

5850    }

 

If above still can’t work, [3], clause 13.3.1.2 “Operators in expressions”, terms 3, says built-in operator is candidate when:

For the operator ,, the unary operator &, or the operator ->, the built-in candidates set is empty. For all other operators, the built-in candidates include all of the candidate operator functions defined in 13.6 that, compared to the given operator,

— have the same operator name, and

— accept the same number of operands, and

— accept operand types to which the given operand or operands can be converted according to 13.3.3.1, and

— do not have the same parameter type list as any non-template non-member candidate.

See the last condition, if the built-in operator have the same parameter type list as any non-template non-member candidate, it should be discarded. Remember in front-end, built-in is node of IDENTIFIER_NODE.

 

joust (continue)

 

5852 Check whether we can discard a builtin candidate, either because we

5853      have two identical ones or matching builtin and non-builtin candidates.

5854

5855      (Pedantically in the latter case the builtin which matched the user

5856      function should not be added to the overload set, but we spot it here.

5857      

5858      [over.match.oper]

5859      ... the builtin candidates include ...

5860      - do not have the same parameter type list as any non-template

5861        non-member candidate.  */

5862                             

5863    if (TREE_CODE (cand1->fn) == IDENTIFIER_NODE

5864        || TREE_CODE (cand2->fn) == IDENTIFIER_NODE)

5865    {

5866      for (i = 0; i < len; ++i)

5867        if (!same_type_p (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)),

5868                       TREE_TYPE (TREE_VEC_ELT (cand2->convs, i))))

5869          break ;

5870      if (i == TREE_VEC_LENGTH (cand1->convs))

5871      {

5872        if (cand1->fn == cand2->fn)

5873           /* Two built-in candidates; arbitrarily pick one.  */

5874          return 1;

5875        else if (TREE_CODE (cand1->fn) == IDENTIFIER_NODE)

5876          /* cand1 is built-in; prefer cand2.  */

5877          return -1;

5878        else

5879          /* cand2 is built-in; prefer cand1.  */

5880          return 1;

5881      }

5882    }

5883

5884    /* If the two functions are the same (this can happen with declarations

5885      in multiple scopes and arg-dependent lookup), arbitrarily choose one.  */

5886    if (DECL_P (cand1->fn) && DECL_P (cand2->fn)

5887        && equal_functions (cand1->fn, cand2->fn))

5888      return 1;

 

We arrive at here, either because the conversions for arguments can’t give a consistent anwser, or it still can’t tells out which is better so far. For the latter, it is no doubt an ambiguous case. While for the former one, now we just compare the worst conversions in these two candidates. The lesser wins. If same, it is a definite ambiguity.

 

joust (continue)

 

5890 tweak:

5891

5892    /* Extension: If the worst conversion for one candidate is worse than the

5893      worst conversion for the other, take the first.  */

5894    if (!pedantic )

5895    {

5896      int rank1 = IDENTITY_RANK, rank2 = IDENTITY_RANK;

5897      struct z_candidate *w = 0, *l = 0;

5898

5899      for (i = 0; i < len; ++i)

5900      {

5901        if (ICS_RANK (TREE_VEC_ELT (cand1->convs, i+off1)) > rank1)

5902          rank1 = ICS_RANK (TREE_VEC_ELT (cand1->convs, i+off1));

5903        if (ICS_RANK (TREE_VEC_ELT (cand2->convs, i+off2)) > rank2)

5904          rank2 = ICS_RANK (TREE_VEC_ELT (cand2->convs, i+off2));

5905      }

5906      if (rank1 < rank2)

5907        winner = 1, w = cand1, l = cand2;

5908      if (rank1 > rank2)

5909        winner = -1, w = cand2, l = cand1;

5910      if (winner)

5911      {

5912        if (warn)

5913        {

5914          pedwarn ("/

5915 ISO C++ says that these are ambiguous, even /

5916 though the worst conversion for the first is better than /

5917 the worst conversion for the second:");

5918                   print_z_candidate (_("candidate 1:"), w);

5919                   print_z_candidate (_("candidate 2:"), l);

5920        }

5921        else

5922          add_warning (w, l);

5923        return winner;

5924      }

5925    }

5926

5927    my_friendly_assert (!winner, 20010121);

5928    return 0;

5929 }

 

Exitting from joust , and we have seen the whole tourney , which returns NON-NULL as long as the best candidate is found. Otherwise, build_user_type_conversion_1 returns at line 2501 a AMBIG_CONV.

 

build_user_type_conversion_1 (continue)

 

2483     if (cand == 0)

2484    {

2485      if (flags & LOOKUP_COMPLAIN)

2486      {

2487        error ("conversion from `%T' to `%T' is ambiguous",

2488             fromtype, totype);

2489        print_z_candidates (candidates);

2490      }

2491

2492      cand = candidates;       /* any one will do */

2493      cand->second_conv = build1 (AMBIG_CONV, totype, expr);

2494      ICS_USER_FLAG (cand->second_conv) = 1;

2495      if (!any_strictly_viable (candidates))

2496        ICS_BAD_FLAG (cand->second_conv) = 1;

2497      /* If there are viable candidates, don't set ICS_BAD_FLAG; an

2498        ambiguous conversion is no worse than another user-defined

2499        conversion.  */

2500

2501      return cand;

2502    }

2503

2504    /* Build the user conversion sequence.  */

2505    convs = build_conv

2506                 (USER_CONV,

2507                  (DECL_CONSTRUCTOR_P (cand->fn)

2508                    ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),

2509                      build1 (IDENTITY_CONV, TREE_TYPE (expr), expr));

2510    TREE_OPERAND (convs, 1) = build_zc_wrapper (cand);

2511

2512    /* Combine it with the second conversion sequence.  */

2513    cand->second_conv = merge_conversion_sequences (convs,

2514                                               cand->second_conv);

2515

2516    if (cand->viable == -1)

2517      ICS_BAD_FLAG (cand->second_conv) = 1;

2518

2519    return cand;

2520 }

 

See above at line 2510, build_zc_wrapper builds the first operand for convs by the best candidate found.

 

1645 tree

1646 build_zc_wrapper (struct z_candidate * ptr)                                                        in tree.c

1647 {

1648    tree t = make_node (WRAPPER);

1649    WRAPPER_ZC (t) = ptr;

1650    return t;

1651 }

 

The relevant data structures are defined as below. From here, we can see clearly that the first operand of convs records the best conversion function that achieves the conversion specified.

 

434    #define WRAPPER_ZC (NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->z_c)

435   

436    struct tree_wrapper GTY(())                                                                     in cp-tree.h

437    {

438      struct tree_common common;

439      struct z_candidate *z_c;

440    };

 

Then below function appends user_seq at the tail of std_seq , in which std_seq is the conversion sequence applied to the returned value and user_seq is a user-defined conversion sequence, beginning with a USER_CONV. Don’t confuse with the name of std_seq , it maybe a user-defined conversion sequence too.

 

2326 static tree

2327 merge_conversion_sequences (tree user_seq, tree std_seq)                                  in call.c

2328 {

2329    tree *t;

2330

2331    my_friendly_assert (TREE_CODE (user_seq) == USER_CONV,

2332              20030306);

2333

2334     /* Find the end of the second conversion sequence.  */

2335    t = &(std_seq);

2336    while (TREE_CODE (*t) != IDENTITY_CONV)

2337      t = &TREE_OPERAND (*t, 0);

2338

2339    /* Replace the identity conversion with the user conversion

2340      sequence.  */

2341    *t = user_seq;

2342

2343    /* The entire sequence is a user-conversion sequence.  */

2344    ICS_USER_FLAG (std_seq) = 1;

2345

2346    return std_seq;

2347 }

 

When cand returned back to implicit_conversion , the function returns the second_conv slot of cand prepared above as the implicit conversion sequence (sequence for returned value first, followed by sequence for arguments).

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值