diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6550e16c654..376cbf671fb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2012-09-29 Paolo Carlini + + PR c++/54738 + * decl2.c (build_offset_ref_call_from_tree): Add tsubst_flags_t + parameter. + * pt.c (tsubst_copy_and_build): Adjust. + * parser.c (cp_parser_postfix_expression): Likewise. + * cp-tree.h: Adjust declaration. + 2012-09-28 Dodji Seketeli PR c++/54372 - unused attribute inactive on dependant entities diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ded247d93d1..f4370224dd3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5149,7 +5149,8 @@ extern void determine_visibility (tree); extern void constrain_class_visibility (tree); extern void import_export_decl (tree); extern tree build_cleanup (tree); -extern tree build_offset_ref_call_from_tree (tree, VEC(tree,gc) **); +extern tree build_offset_ref_call_from_tree (tree, VEC(tree,gc) **, + tsubst_flags_t); extern bool decl_constant_var_p (tree); extern bool decl_maybe_constant_var_p (tree); extern void check_default_args (tree); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a590d178156..4cff0516d77 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4087,7 +4087,8 @@ cp_write_global_declarations (void) ARGS. */ tree -build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args) +build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args, + tsubst_flags_t complain) { tree orig_fn; VEC(tree,gc) *orig_args = NULL; @@ -4115,7 +4116,7 @@ build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args) if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) { if (TREE_CODE (fn) == DOTSTAR_EXPR) - object = cp_build_addr_expr (object, tf_warning_or_error); + object = cp_build_addr_expr (object, complain); VEC_safe_insert (tree, gc, *args, 0, object); } /* Now that the arguments are done, transform FN. */ @@ -4130,17 +4131,17 @@ build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args) void B::g() { (this->*p)(); } */ if (TREE_CODE (fn) == OFFSET_REF) { - tree object_addr = cp_build_addr_expr (object, tf_warning_or_error); + tree object_addr = cp_build_addr_expr (object, complain); fn = TREE_OPERAND (fn, 1); fn = get_member_function_from_ptrfunc (&object_addr, fn, - tf_warning_or_error); + complain); VEC_safe_insert (tree, gc, *args, 0, object_addr); } if (CLASS_TYPE_P (TREE_TYPE (fn))) - expr = build_op_call (fn, args, tf_warning_or_error); + expr = build_op_call (fn, args, complain); else - expr = cp_build_function_call_vec (fn, args, tf_warning_or_error); + expr = cp_build_function_call_vec (fn, args, complain); if (processing_template_decl && expr != error_mark_node) expr = build_min_non_dep_call_vec (expr, orig_fn, orig_args); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 40aa3061c01..155b51a180d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -5749,7 +5749,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, || TREE_CODE (postfix_expression) == MEMBER_REF || TREE_CODE (postfix_expression) == DOTSTAR_EXPR) postfix_expression = (build_offset_ref_call_from_tree - (postfix_expression, &args)); + (postfix_expression, &args, + tf_warning_or_error)); else if (idk == CP_ID_KIND_QUALIFIED) /* A call to a static class member, or a namespace-scope function. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d00470eec18..104d4dd6898 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13783,7 +13783,8 @@ tsubst_copy_and_build (tree t, mark_used (function); if (TREE_CODE (function) == OFFSET_REF) - ret = build_offset_ref_call_from_tree (function, &call_args); + ret = build_offset_ref_call_from_tree (function, &call_args, + complain); else if (TREE_CODE (function) == COMPONENT_REF) { tree instance = TREE_OPERAND (function, 0); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c7ef179b906..8578075ec2d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-09-29 Paolo Carlini + + PR c++/54738 + * g++.dg/cpp0x/sfinae42.C: New. + 2012-09-29 David Edelsohn * gcc.target/powerpc/405-dlmzb-strlen-1.c: Skip on AIX. diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae42.C b/gcc/testsuite/g++.dg/cpp0x/sfinae42.C new file mode 100644 index 00000000000..a7a23a31722 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae42.C @@ -0,0 +1,46 @@ +// PR c++/54738 +// { dg-do compile { target c++11 } } + +template +T&& declval(); + +template +decltype(((*declval()).*declval())(declval()...)) +test1(int); + +template +void test1(...); + +template +decltype((declval().*declval())(declval()...)) +test2(int); + +template +void test2(...); + +struct S {}; + +typedef void (S::*Func)(int) const; +typedef void (S::*Func2)(int); + +typedef decltype(test1(0)) type1a; +typedef decltype(test1(0)) type1b; +typedef decltype(test1(0)) type1c; +typedef decltype(test1(0)) type1d; + +typedef decltype(test2(0)) type2a; +typedef decltype(test2(0)) type2b; +typedef decltype(test2(0)) type2c; +typedef decltype(test2(0)) type2d; + +typedef decltype(test1(0)) type3a; +typedef decltype(test1(0)) type3b; + +typedef decltype(test2(0)) type4a; +typedef decltype(test2(0)) type4b; + +typedef decltype(test1(0)) type5a; +typedef decltype(test1(0)) type5b; + +typedef decltype(test2(0)) type6a; +typedef decltype(test2(0)) type6b;