Re: [C++ Patch] PR 54191

2012-09-05 Thread Paolo Carlini

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

2012-08-27 Thread Jason Merrill
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

2012-08-27 Thread Paolo Carlini

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

2012-08-27 Thread Jason Merrill

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

2012-08-27 Thread Paolo Carlini

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

2012-08-27 Thread Jason Merrill

OK.

Jason


[C++ Patch] PR 54191

2012-08-08 Thread Paolo Carlini

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