Hi, the straightforward fix per the audit trail. Tested x86_64-linux.
Ok for Stage 1? Thanks, Paolo. ////////////////////////
/cp 2012-01-26 Paolo Carlini <paolo.carl...@oracle.com> PR c++/51989 * typeck2.c (build_x_arrow): Take a tsubst_flags_t argument and propagate it. * cp-tree.h (build_x_arrow): Adjust prototype. * pt.c (tsubst_copy_and_build): Adjust call. * parser.c (cp_parser_postfix_dot_deref_expression): Likewise. /testsuite 2012-01-26 Paolo Carlini <paolo.carl...@oracle.com> PR c++/51989 * g++.dg/cpp0x/sfinae32.C: New.
Index: testsuite/g++.dg/cpp0x/sfinae32.C =================================================================== --- testsuite/g++.dg/cpp0x/sfinae32.C (revision 0) +++ testsuite/g++.dg/cpp0x/sfinae32.C (revision 0) @@ -0,0 +1,18 @@ +// PR c++/51989 +// { dg-options -std=c++0x } + +template <typename T> +struct is_container +{ + template <typename U, typename V = decltype(((U*)0)->begin())> + static char test(U* u); + + template <typename U> static long test(...); + + enum { value = sizeof test<T>(0) == 1 }; +}; + +int main() +{ + return is_container<void>::value; +} Index: cp/typeck2.c =================================================================== --- cp/typeck2.c (revision 183555) +++ cp/typeck2.c (working copy) @@ -1462,7 +1462,7 @@ build_scoped_ref (tree datum, tree basetype, tree* delegation is detected. */ tree -build_x_arrow (tree expr) +build_x_arrow (tree expr, tsubst_flags_t complain) { tree orig_expr = expr; tree type = TREE_TYPE (expr); @@ -1486,7 +1486,7 @@ tree while ((expr = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, expr, NULL_TREE, NULL_TREE, - &fn, tf_warning_or_error))) + &fn, complain))) { if (expr == error_mark_node) return error_mark_node; @@ -1497,7 +1497,8 @@ tree if (vec_member (TREE_TYPE (expr), types_memoized)) { - error ("circular pointer delegation detected"); + if (complain & tf_error) + error ("circular pointer delegation detected"); return error_mark_node; } @@ -1510,7 +1511,8 @@ tree if (last_rval == NULL_TREE) { - error ("base operand of %<->%> has non-pointer type %qT", type); + if (complain & tf_error) + error ("base operand of %<->%> has non-pointer type %qT", type); return error_mark_node; } @@ -1530,13 +1532,16 @@ tree return expr; } - return cp_build_indirect_ref (last_rval, RO_NULL, tf_warning_or_error); + return cp_build_indirect_ref (last_rval, RO_NULL, complain); } - if (types_memoized) - error ("result of %<operator->()%> yields non-pointer result"); - else - error ("base operand of %<->%> is not a pointer"); + if (complain & tf_error) + { + if (types_memoized) + error ("result of %<operator->()%> yields non-pointer result"); + else + error ("base operand of %<->%> is not a pointer"); + } return error_mark_node; } Index: cp/pt.c =================================================================== --- cp/pt.c (revision 183555) +++ cp/pt.c (working copy) @@ -13678,7 +13678,7 @@ tsubst_copy_and_build (tree t, /* Remember that there was a reference to this entity. */ if (DECL_P (op1)) mark_used (op1); - return build_x_arrow (op1); + return build_x_arrow (op1, complain); case NEW_EXPR: { Index: cp/parser.c =================================================================== --- cp/parser.c (revision 183555) +++ cp/parser.c (working copy) @@ -5910,7 +5910,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser /* If this is a `->' operator, dereference the pointer. */ if (token_type == CPP_DEREF) - postfix_expression = build_x_arrow (postfix_expression); + postfix_expression = build_x_arrow (postfix_expression, + tf_warning_or_error); /* Check to see whether or not the expression is type-dependent. */ dependent_p = type_dependent_expression_p (postfix_expression); /* The identifier following the `->' or `.' is not qualified. */ Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 183555) +++ cp/cp-tree.h (working copy) @@ -5876,7 +5876,7 @@ extern void check_narrowing (tree, tree); extern tree digest_init (tree, tree, tsubst_flags_t); extern tree digest_init_flags (tree, tree, int); extern tree build_scoped_ref (tree, tree, tree *); -extern tree build_x_arrow (tree); +extern tree build_x_arrow (tree, tsubst_flags_t); extern tree build_m_component_ref (tree, tree); extern tree build_functional_cast (tree, tree, tsubst_flags_t); extern tree add_exception_specifier (tree, tree, int);