Hi,
On 08/02/2012 05:33 PM, Jason Merrill wrote:
On 08/01/2012 02:57 PM, Paolo Carlini wrote:
So, it is possible that when spec != NULL_TREE and we are once more in a
SFINAE context, we have to actually call perform_deferred_access_checks
(complain) and either return error_mark_node or the spec depending on
the return value?
I don't think we need to redo the access check in SFINAE context; we
know that there's an error, so we can just return error_mark_node in
that case. I guess we should change the name of
FNDECL_RECHECK_ACCESS_P to something like FNDECL_HAS_ACCESS_ERRORS to
make it clearer.
Ah, very well, everything makes sense now. Thus I'm finishing testing
the below (already past the C++ testsuite), Ok if it passes?
Thanks,
Paolo.
///////////////////////
/cp
2012-08-02 Jason Merrill <ja...@redhat.com>
Paolo Carlini <paolo.carl...@oracle.com>
PR c++/51213 (again)
* pt.c (type_unification_real): Call push_deferring_access_checks /
pop_deferring_access_checks around the substitution of default
template args.
(instantiate_template_1): When the specialization returned by
retrieve_specialization has FNDECL_HAS_ACCESS_ERRORS set and we
are in a SFINAE context, simply return error_mark_node.
* cp-tree.h (FNDECL_RECHECK_ACCESS_P): Rename FNDECL_HAS_ACCESS_ERRORS.
/testsuite
2012-08-02 Jason Merrill <ja...@redhat.com>
Paolo Carlini <paolo.carl...@oracle.com>
PR c++/51213 (again)
* g++.dg/cpp0x/sfinae37.C: Extend.
Index: testsuite/g++.dg/cpp0x/sfinae37.C
===================================================================
--- testsuite/g++.dg/cpp0x/sfinae37.C (revision 190071)
+++ testsuite/g++.dg/cpp0x/sfinae37.C (working copy)
@@ -5,6 +5,12 @@ class C {
typedef int type;
};
+template<int>
+struct I;
+
+template<>
+struct I<2> { };
+
template<class T, class = typename T::type>
auto f(int) -> char;
@@ -13,6 +19,10 @@ auto f(...) -> char (&)[2];
static_assert(sizeof(f<C>(0)) == 2, "Ouch");
+typedef int testf[sizeof(f<C>(0)) == 2 ? 1 : -1];
+
+I<sizeof(f<C>(0))> vf;
+
template<class T>
auto g(int) -> decltype(typename T::type(), char());
@@ -20,3 +30,7 @@ template<class>
auto g(...) -> char (&)[2];
static_assert(sizeof(g<C>(0)) == 2, "Ouch");
+
+typedef int testg[sizeof(g<C>(0)) == 2 ? 1 : -1];
+
+I<sizeof(g<C>(0))> vg;
Index: cp/pt.c
===================================================================
--- cp/pt.c (revision 190071)
+++ cp/pt.c (working copy)
@@ -14363,8 +14363,13 @@ instantiate_template_1 (tree tmpl, tree orig_args,
if (spec != NULL_TREE)
{
- if (FNDECL_RECHECK_ACCESS_P (spec) && (complain & tf_error))
- recheck_decl_substitution (spec, gen_tmpl, targ_ptr);
+ if (FNDECL_HAS_ACCESS_ERRORS (spec))
+ {
+ if (complain & tf_error)
+ recheck_decl_substitution (spec, gen_tmpl, targ_ptr);
+ else
+ return error_mark_node;
+ }
return spec;
}
@@ -14426,7 +14431,7 @@ instantiate_template_1 (tree tmpl, tree orig_args,
{
/* Remember to reinstantiate when we're out of SFINAE so the user
can see the errors. */
- FNDECL_RECHECK_ACCESS_P (fndecl) = true;
+ FNDECL_HAS_ACCESS_ERRORS (fndecl) = true;
}
return error_mark_node;
}
@@ -15122,9 +15127,11 @@ type_unification_real (tree tparms,
location_t save_loc = input_location;
if (DECL_P (parm))
input_location = DECL_SOURCE_LOCATION (parm);
+ push_deferring_access_checks (dk_no_deferred);
arg = tsubst_template_arg (arg, targs, complain, NULL_TREE);
arg = convert_template_argument (parm, arg, targs, complain,
i, NULL_TREE);
+ pop_deferring_access_checks ();
input_location = save_loc;
if (arg == error_mark_node)
return 1;
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 190071)
+++ cp/cp-tree.h (working copy)
@@ -729,10 +729,10 @@ DEF_VEC_ALLOC_O (qualified_typedef_usage_t,gc);
/* Non-zero if this template specialization has access violations that
should be rechecked when the function is instantiated outside argument
deduction. */
-#define TINFO_RECHECK_ACCESS_P(NODE) \
+#define TINFO_HAS_ACCESS_ERRORS(NODE) \
(TREE_LANG_FLAG_0 (TEMPLATE_INFO_CHECK (NODE)))
-#define FNDECL_RECHECK_ACCESS_P(NODE) \
- (TINFO_RECHECK_ACCESS_P (DECL_TEMPLATE_INFO (NODE)))
+#define FNDECL_HAS_ACCESS_ERRORS(NODE) \
+ (TINFO_HAS_ACCESS_ERRORS (DECL_TEMPLATE_INFO (NODE)))
struct GTY(()) tree_template_info {
struct tree_common common;