Message ID | 000001cbd902$c51c4f80$4f54ee80$@Zhang@arm.com |
---|---|
State | New |
Headers | show |
On 03/02/2011 12:53 PM, Yufeng Zhang wrote: > The calls to build_cplus_new in convert_like_real don't seem to be > redundant. Hmm, I guess you're right. I think rather that the problem is in build_conditional_expr; it should have a template case that just determines the appropriate type and then builds up a COND_EXPR with that type from the unconverted operands, like we do for calls in finish_call_expr. Jason
> On 03/03/2011 11:39 PM, Jason Merrill wrote: > I think rather that the problem is in build_conditional_expr; it > should have a template case that just determines the appropriate > type and then builds up a COND_EXPR with that type from the > unconverted operands, like we do for calls in finish_call_expr. Thanks for the suggestion. I spent some more time looking into the related code. If I understand it correctly, I think this is just what build_x_conditional_expr in ./cp/typeck.c does: If the conditional expression is type-dependent in the template, it builds and returns a COND_EXPR without TREE_TYPE. If the conditional expression is not type-dependent, it calls build_conditional_expr to determine its TREE_TYPE and then builds up a COND_EXPR with the unconverted/original operands. Different from CALL_EXPR, the TREE_TYPE of a COND_EXPR is determined by the TREE_TYPEs of its latter two operands. When the types of the two operands are different, a conversion is attempted on each operand type to match the type of the other operand; while for a CALL_EXPR, its TREE_TYPE is independent from the TREE_TYPE(s) of its arg(s). So I think it is necessary for build_conditional_expr to call convert_like_real to do the conversions. The parser should try its best to determine the type and check for any semantic error for expressions in a template declaration, especially for non-dependent expressions. I still feel the proposed patch in http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00076.html makes sense. But if you think anything is not appropriate or have any more question, please do let me know. Regards, Yufeng
On 03/07/2011 01:27 PM, Yufeng Zhang wrote: >> On 03/03/2011 11:39 PM, Jason Merrill wrote: >> I think rather that the problem is in build_conditional_expr; it >> should have a template case that just determines the appropriate >> type and then builds up a COND_EXPR with that type from the >> unconverted operands, like we do for calls in finish_call_expr. > > Thanks for the suggestion. I spent some more time looking into the > related code. If I understand it correctly, I think this is just what > build_x_conditional_expr in ./cp/typeck.c does: Yes. The problem is that build_conditional_expr is actually trying to do the conversions; it should just determine what the conversions would be and then stop there. That's what we do with calls--we determine all the desired conversions and pass them into build_over_call, which just ignores them. Actually performing the conversions can wait until instantiation tme. > Different from CALL_EXPR, the TREE_TYPE of a COND_EXPR is determined > by the TREE_TYPEs of its latter two operands. When the types of the > two operands are different, a conversion is attempted on each operand > type to match the type of the other operand; while for a CALL_EXPR, > its TREE_TYPE is independent from the TREE_TYPE(s) of its arg(s). I don't think the difference is significant; a call to an overloaded function also depends on the types of its arguments. We need to determine the conversions from argument to parameter types in order to select the right function, just as in a ?: expression we need to determine the conversions from the 2nd and 3rd operands to a result type. Jason
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 1a1f150..ae33e58 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -391,9 +391,12 @@ build_aggr_init_expr (tree type, tree init) else return convert (type, init); - is_ctor = (TREE_CODE (fn) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL - && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0))); + is_ctor = ((TREE_CODE (fn) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL + && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0))) + || (processing_template_decl + && is_overloaded_fn (fn) + && DECL_CONSTRUCTOR_P (get_first_fn (fn)))); /* We split the CALL_EXPR into its function and its arguments here. Then, in expand_expr, we put them back together. The reason for