Re: [C++ Patch] PR 54191
On 08/28/2012 01:49 AM, Jason Merrill wrote: OK. Thanks Jason. I have now committed the patch together with the three additional tests which depended on instantiation_dependent_p. Thanks again, Paolo.
Re: [C++ Patch] PR 54191
Let's do away with ba_quiet entirely and instead pass tf_none in cases where we would have set ba_quiet. #define DERIVED_FROM_P(PARENT, TYPE) \ - (lookup_base ((TYPE), (PARENT), ba_any, NULL) != NULL_TREE) + (lookup_base ((TYPE), (PARENT), ba_any, NULL, tf_warning_or_error) \ + != NULL_TREE) /* Nonzero iff TYPE is uniquely derived from PARENT. Ignores accessibility. */ #define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) \ - (lookup_base ((TYPE), (PARENT), ba_unique | ba_quiet, NULL) != NULL_TREE) + (lookup_base ((TYPE), (PARENT), ba_unique | ba_quiet, NULL, \ + tf_warning_or_error) != NULL_TREE) /* Nonzero iff TYPE is publicly uniquely derived from PARENT. */ #define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \ (lookup_base ((TYPE), (PARENT), ba_ignore_scope | ba_check | ba_quiet, \ - NULL) != NULL_TREE) + NULL, tf_warning_or_error) != NULL_TREE) I think anything that's just checking whether a base is there/usable should use tf_none. Jason
Re: [C++ Patch] PR 54191
On 08/27/2012 06:28 PM, Jason Merrill wrote: Let's do away with ba_quiet entirely and instead pass tf_none in cases where we would have set ba_quiet. Thanks for the feedback. Indeed, as I tried to explain in an older message, that was also my understanding. The practical difficulty with the mapping (which you can also guess from the current structure of get_delta_difference_1, the if (kind == bk_inaccessible || kind == bk_ambig) check) is that ba_quiet, as used by lookup_base, doesn't just control the error calls - like normally tf_error does - it *also* changes the return value, error_mark_node or NULL_TREE. I'm still not sure about the correct (and concise! see get_delta_difference_1, again) way to handle this... Paolo.
Re: [C++ Patch] PR 54191
On 08/27/2012 01:36 PM, Paolo Carlini wrote: Thanks for the feedback. Indeed, as I tried to explain in an older message, that was also my understanding. The practical difficulty with the mapping (which you can also guess from the current structure of get_delta_difference_1, the if (kind == bk_inaccessible || kind == bk_ambig) check) is that ba_quiet, as used by lookup_base, doesn't just control the error calls - like normally tf_error does - it *also* changes the return value, error_mark_node or NULL_TREE. I'm still not sure about the correct (and concise! see get_delta_difference_1, again) way to handle this... I think the right way is to adjust the callers to handle error_mark_node return properly. Macros may need to become functions. Jason
Re: [C++ Patch] PR 54191
On 08/27/2012 08:04 PM, Jason Merrill wrote: On 08/27/2012 01:36 PM, Paolo Carlini wrote: Thanks for the feedback. Indeed, as I tried to explain in an older message, that was also my understanding. The practical difficulty with the mapping (which you can also guess from the current structure of get_delta_difference_1, the if (kind == bk_inaccessible || kind == bk_ambig) check) is that ba_quiet, as used by lookup_base, doesn't just control the error calls - like normally tf_error does - it *also* changes the return value, error_mark_node or NULL_TREE. I'm still not sure about the correct (and concise! see get_delta_difference_1, again) way to handle this... I think the right way is to adjust the callers to handle error_mark_node return properly. Macros may need to become functions. Ah, ok. I guess the prospect of touching those macros was somehow psychologically blocking me., eh ;) But actually, all in all, the code doesn't become more complex, because only the cases where we are now passing tf_none require checking for error_mark_node too where we were simply checking != NULL_TREE as return value of lookup_base and most of the calls are otherwise already Ok, or even become simpler, where we were, on a case by case basis, tweaking to | ba_quiet basing on complain (note: I left DERIVED_FROM_P alone, because we weren't passing ba_quiet to it) The below passes testing on x86_64-linux. Thanks! Paolo. // Index: testsuite/g++.dg/cpp0x/sfinae39.C === --- testsuite/g++.dg/cpp0x/sfinae39.C (revision 0) +++ testsuite/g++.dg/cpp0x/sfinae39.C (revision 0) @@ -0,0 +1,98 @@ +// PR c++/54191 +// { dg-do compile { target c++11 } } + +struct B +{}; + +struct D + : private B +{}; + +templatetypename T +T declval(); + + +templatetypename From, typename To, + typename = decltype(static_castTo(declvalFrom())) +constexpr bool test_static_cast(int) +{ return true; } + +templatetypename, typename +constexpr bool test_static_cast(bool) +{ return false; } + +static_assert(!test_static_castB , D (0), ); +static_assert(!test_static_castB *, D *(0), ); + + +templatetypename From, typename To, + typename = decltype(dynamic_castTo(declvalFrom())) +constexpr bool test_dynamic_cast(int) +{ return true; } + +templatetypename, typename +constexpr bool test_dynamic_cast(bool) +{ return false; } + +static_assert(!test_dynamic_castD , B (0), ); +static_assert(!test_dynamic_castD *, B *(0), ); + + +int B::*pm = 0; + +templatetypename T, typename = decltype(declvalT().*pm) +constexpr bool test_member_ptr_dot(int) +{ return true; } + +templatetypename +constexpr bool test_member_ptr_dot(bool) +{ return false; } + +static_assert(!test_member_ptr_dotD(0), ); + + +templatetypename T, typename = decltype(declvalT()-*pm) +constexpr bool test_member_ptr_arrow(int) +{ return true; } + +templatetypename +constexpr bool test_member_ptr_arrow(bool) +{ return false; } + +static_assert(!test_member_ptr_arrowD *(0), ); + + +templatetypename T, typename U, + typename = decltype(declvalT() declvalU()) +constexpr bool test_rel_op(int) +{ return true; } + +templatetypename, typename +constexpr bool test_rel_op(bool) +{ return false; } + +static_assert(!test_rel_opD *, B *(0), ); + + +templatetypename T, typename U, + typename = decltype(declvalT() == declvalU()) +constexpr bool test_eq(int) +{ return true; } + +templatetypename, typename +constexpr bool test_eq(bool) +{ return false; } + +static_assert(!test_eqD *, B *(0), ); + + +templatetypename T, typename U, + typename = decltype(false ? declvalT() : declvalU()) +constexpr bool test_cond_op(int) +{ return true; } + +templatetypename, typename +constexpr bool test_cond_op(bool) +{ return false; } + +static_assert(!test_cond_opB *, D *(0), ); Index: cp/typeck.c === --- cp/typeck.c (revision 190730) +++ cp/typeck.c (working copy) @@ -975,7 +975,7 @@ comp_except_types (tree a, tree b, bool exact) || TREE_CODE (b) != RECORD_TYPE) return false; - if (PUBLICLY_UNIQUELY_DERIVED_P (a, b)) + if (publicly_uniquely_derived_p (a, b)) return true; } return false; @@ -2247,7 +2247,7 @@ build_class_member_access_expr (tree object, tree base_kind kind; binfo = lookup_base (access_path ? access_path : object_type, - member_scope, ba_unique, kind); + member_scope, ba_unique, kind, complain); if (binfo == error_mark_node) return error_mark_node; @@ -2630,7 +2630,8 @@ finish_class_member_access_expr (tree object, tree } /* Find the base of OBJECT_TYPE corresponding to SCOPE. */ - access_path = lookup_base (object_type, scope, ba_check, NULL); + access_path = lookup_base (object_type, scope, ba_check, +
Re: [C++ Patch] PR 54191
OK. Jason
[C++ Patch] PR 54191
Hi, this is a booted and tested patch which handles all the tests submitted as part of the PR besides the first 4, which require finish_decltype_type to use an instantiation_dependent_p along the lines of the work done as part of c++/51222. As I mentioned, I already verified that the latter work is enough to fix those 4 tests, thus my idea would be resolving asap this PR and then adding the 4 tests to c++/51222 or opening a separate PR only for those, blocked by c++/51222, whichever option you like. Otherwise, as I already described, I'm simply adding a tsubst_flags_t parameter to lookup_base, and the rest is straightforward. Thanks, Paolo. /cp 2012-08-08 Paolo Carlini paolo.carl...@oracle.com PR c++/54191 * search.c (lookup_base): Add tsubst_flags_t parameter. (adjust_result_of_qualified_name_lookup, check_final_overrider): Adjust. * name-lookup.c (do_class_using_decl): Likewise. * typeck.c (build_class_member_access_expr, finish_class_member_access_expr, get_member_function_from_ptrfunc, build_static_cast_1, get_delta_difference_1): Likewise. * class.c (build_base_path, convert_to_base, build_vtbl_ref_1, warn_about_ambiguous_bases): Likewise. * rtti.c (build_dynamic_cast_1): Likewise. * tree.c (maybe_dummy_object): Likewise. * typeck2.c (error_not_base_type, build_scoped_ref, build_m_component_ref): Likewise. * cvt.c (cp_convert_to_pointer, convert_to_pointer_force, build_up_reference): Likewise. * call.c (build_over_call): Likewise. (build_conditional_expr_1): Check arg2 and arg3 for error_mark_node before the valid_operands label. * cp-tree.h: Update. /testsuite 2012-08-08 Paolo Carlini paolo.carl...@oracle.com PR c++/54191 * g++.dg/cpp0x/sfinae39.C: New. Index: testsuite/g++.dg/cpp0x/sfinae39.C === --- testsuite/g++.dg/cpp0x/sfinae39.C (revision 0) +++ testsuite/g++.dg/cpp0x/sfinae39.C (revision 0) @@ -0,0 +1,98 @@ +// PR c++/54191 +// { dg-do compile { target c++11 } } + +struct B +{}; + +struct D + : private B +{}; + +templatetypename T +T declval(); + + +templatetypename From, typename To, + typename = decltype(static_castTo(declvalFrom())) +constexpr bool test_static_cast(int) +{ return true; } + +templatetypename, typename +constexpr bool test_static_cast(bool) +{ return false; } + +static_assert(!test_static_castB , D (0), ); +static_assert(!test_static_castB *, D *(0), ); + + +templatetypename From, typename To, + typename = decltype(dynamic_castTo(declvalFrom())) +constexpr bool test_dynamic_cast(int) +{ return true; } + +templatetypename, typename +constexpr bool test_dynamic_cast(bool) +{ return false; } + +static_assert(!test_dynamic_castD , B (0), ); +static_assert(!test_dynamic_castD *, B *(0), ); + + +int B::*pm = 0; + +templatetypename T, typename = decltype(declvalT().*pm) +constexpr bool test_member_ptr_dot(int) +{ return true; } + +templatetypename +constexpr bool test_member_ptr_dot(bool) +{ return false; } + +static_assert(!test_member_ptr_dotD(0), ); + + +templatetypename T, typename = decltype(declvalT()-*pm) +constexpr bool test_member_ptr_arrow(int) +{ return true; } + +templatetypename +constexpr bool test_member_ptr_arrow(bool) +{ return false; } + +static_assert(!test_member_ptr_arrowD *(0), ); + + +templatetypename T, typename U, + typename = decltype(declvalT() declvalU()) +constexpr bool test_rel_op(int) +{ return true; } + +templatetypename, typename +constexpr bool test_rel_op(bool) +{ return false; } + +static_assert(!test_rel_opD *, B *(0), ); + + +templatetypename T, typename U, + typename = decltype(declvalT() == declvalU()) +constexpr bool test_eq(int) +{ return true; } + +templatetypename, typename +constexpr bool test_eq(bool) +{ return false; } + +static_assert(!test_eqD *, B *(0), ); + + +templatetypename T, typename U, + typename = decltype(false ? declvalT() : declvalU()) +constexpr bool test_cond_op(int) +{ return true; } + +templatetypename, typename +constexpr bool test_cond_op(bool) +{ return false; } + +static_assert(!test_cond_opB *, D *(0), ); Index: cp/typeck.c === --- cp/typeck.c (revision 190231) +++ cp/typeck.c (working copy) @@ -2247,7 +2247,7 @@ build_class_member_access_expr (tree object, tree base_kind kind; binfo = lookup_base (access_path ? access_path : object_type, - member_scope, ba_unique, kind); + member_scope, ba_unique, kind, complain); if (binfo == error_mark_node) return error_mark_node; @@ -2630,7 +2630,8 @@ finish_class_member_access_expr (tree object, tree } /* Find the base of OBJECT_TYPE corresponding to