From: Jason Merrill Date: Wed, 6 Feb 2013 03:33:45 +0000 (-0500) Subject: re PR c++/56208 (Some classic sfinae cases fail to work due to access problems) X-Git-Tag: upstream/12.2.0~71411 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=29ef6cd035bda26987bd4a69a91b66908654b01b;p=platform%2Fupstream%2Fgcc.git re PR c++/56208 (Some classic sfinae cases fail to work due to access problems) PR c++/56208 * pt.c (fn_type_unification): Discard any access checks from substituting explicit args. From-SVN: r195779 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7bd5402..ce0bfad 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-02-05 Jason Merrill + + PR c++/56208 + * pt.c (fn_type_unification): Discard any access checks from + substituting explicit args. + 2013-01-31 Jason Merrill PR c++/56162 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7430289..aa127ed 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14989,6 +14989,12 @@ fn_type_unification (tree fn, if (fntype == error_mark_node) goto fail; + /* Throw away these access checks; we'll see them again in + instantiate_template and they might have the wrong + access path at this point. */ + pop_deferring_access_checks (); + push_deferring_access_checks (dk_deferred); + /* Place the explicitly specified arguments in TARGS. */ for (i = NUM_TMPL_ARGS (explicit_targs); i--;) TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i); diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae43.C b/gcc/testsuite/g++.dg/cpp0x/sfinae43.C new file mode 100644 index 0000000..22efe65 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae43.C @@ -0,0 +1,31 @@ +// PR c++/56208 +// { dg-options -std=c++11 } + +struct ostream { + ostream& operator<<(int); +}; + +struct sfinae_base { + + typedef char one; + typedef char (&two)[2]; + + template + static T make(); + + template struct ok { typedef int type; }; + + template + static one test(decltype((make() << make()), 0)); + + template + static two test(...); +}; + +template +struct is_printable : private sfinae_base +{ + enum { value = sizeof(test(0)) == sizeof(one) }; +}; + +typedef int ok[is_printable::value ? 1 : -1];