From 60d21717a2dd6a4132b45c4dc8c3ad0548349bfb Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 3 Nov 2009 12:11:18 -0500 Subject: [PATCH] re PR c++/40944 ([C++0x] rejects well-formed code: SFINAE, decltype, function call) PR c++/40944 * call.c (initialize_reference): Add complain parm. * typeck.c (convert_for_initialization): Pass it. * decl.c (grok_reference_init): Likewise. * cp-tree.h: Declare it. From-SVN: r153856 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/call.c | 26 ++++++++++++++---------- gcc/cp/cp-tree.h | 2 +- gcc/cp/decl.c | 2 +- gcc/cp/typeck.c | 2 +- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/template/sfinae15.C | 23 +++++++++++++++++++++ 7 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/sfinae15.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6c7bdc66c97..1b87b0466b7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2009-11-03 Jason Merrill + PR c++/40944 + * call.c (initialize_reference): Add complain parm. + * typeck.c (convert_for_initialization): Pass it. + * decl.c (grok_reference_init): Likewise. + * cp-tree.h: Declare it. + PR c++/40687 * pt.c (do_auto_deduction): Diagnose inconsistent deduction. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 463257cd5af..674e59d686c 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7617,7 +7617,8 @@ set_up_extended_ref_temp (tree decl, tree expr, tree *cleanup, tree *initp) Return the converted expression. */ tree -initialize_reference (tree type, tree expr, tree decl, tree *cleanup) +initialize_reference (tree type, tree expr, tree decl, tree *cleanup, + tsubst_flags_t complain) { conversion *conv; void *p; @@ -7632,16 +7633,19 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) LOOKUP_NORMAL); if (!conv || conv->bad_p) { - if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST) - && !TYPE_REF_IS_RVALUE (type) - && !real_lvalue_p (expr)) - error ("invalid initialization of non-const reference of " - "type %qT from an rvalue of type %qT", - type, TREE_TYPE (expr)); - else - error ("invalid initialization of reference of type " - "%qT from expression of type %qT", type, - TREE_TYPE (expr)); + if (complain & tf_error) + { + if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST) + && !TYPE_REF_IS_RVALUE (type) + && !real_lvalue_p (expr)) + error ("invalid initialization of non-const reference of " + "type %qT from an rvalue of type %qT", + type, TREE_TYPE (expr)); + else + error ("invalid initialization of reference of type " + "%qT from expression of type %qT", type, + TREE_TYPE (expr)); + } return error_mark_node; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 79655142eeb..c4b088beb56 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4429,7 +4429,7 @@ extern tree type_passed_as (tree); extern tree convert_for_arg_passing (tree, tree); extern bool is_properly_derived_from (tree, tree); extern tree set_up_extended_ref_temp (tree, tree, tree *, tree *); -extern tree initialize_reference (tree, tree, tree, tree *); +extern tree initialize_reference (tree, tree, tree, tree *, tsubst_flags_t); extern tree make_temporary_var_for_ref_to_temp (tree, tree); extern tree strip_top_quals (tree); extern bool reference_related_p (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index de29d0bdb63..97f1ac1f4f3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4390,7 +4390,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup) DECL_INITIAL for local references (instead assigning to them explicitly); we need to allow the temporary to be initialized first. */ - tmp = initialize_reference (type, init, decl, cleanup); + tmp = initialize_reference (type, init, decl, cleanup, tf_warning_or_error); if (tmp == error_mark_node) return NULL_TREE; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 25c257f94a9..5b8523d8bd6 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6879,7 +6879,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags, if (fndecl) savew = warningcount, savee = errorcount; rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE, - /*cleanup=*/NULL); + /*cleanup=*/NULL, complain); if (fndecl) { if (warningcount > savew) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ab594d79516..8898d927560 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2009-11-03 Jason Merrill + PR c++/40944 + * g++.dg/template/sfinae15.C: New. + PR c++/40687 * g++.dg/cpp0x/auto3.C: Remove xfail. diff --git a/gcc/testsuite/g++.dg/template/sfinae15.C b/gcc/testsuite/g++.dg/template/sfinae15.C new file mode 100644 index 00000000000..27bce255db3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae15.C @@ -0,0 +1,23 @@ +// PR c++/40944 +// { dg-options -std=c++0x } +// { dg-do run } + +template +struct make { static T&& it(); }; + +void (*pf)(int&) = 0; + +template< typename T > +int bar(T const& x, + decltype( pf(make::it()) )* = 0 // SFINAE! + ) { + return 1; +} + +int bar(...) { + return 0; +} + +int main() { + return bar(42); +}