Commit 60d21717 by Jason Merrill Committed by Jason Merrill

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
parent 2e32c99e
2009-11-03 Jason Merrill <jason@redhat.com> 2009-11-03 Jason Merrill <jason@redhat.com>
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 PR c++/40687
* pt.c (do_auto_deduction): Diagnose inconsistent deduction. * pt.c (do_auto_deduction): Diagnose inconsistent deduction.
......
...@@ -7617,7 +7617,8 @@ set_up_extended_ref_temp (tree decl, tree expr, tree *cleanup, tree *initp) ...@@ -7617,7 +7617,8 @@ set_up_extended_ref_temp (tree decl, tree expr, tree *cleanup, tree *initp)
Return the converted expression. */ Return the converted expression. */
tree 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; conversion *conv;
void *p; void *p;
...@@ -7632,16 +7633,19 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) ...@@ -7632,16 +7633,19 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
LOOKUP_NORMAL); LOOKUP_NORMAL);
if (!conv || conv->bad_p) if (!conv || conv->bad_p)
{ {
if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST) if (complain & tf_error)
&& !TYPE_REF_IS_RVALUE (type) {
&& !real_lvalue_p (expr)) if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
error ("invalid initialization of non-const reference of " && !TYPE_REF_IS_RVALUE (type)
"type %qT from an rvalue of type %qT", && !real_lvalue_p (expr))
type, TREE_TYPE (expr)); error ("invalid initialization of non-const reference of "
else "type %qT from an rvalue of type %qT",
error ("invalid initialization of reference of type " type, TREE_TYPE (expr));
"%qT from expression of type %qT", type, else
TREE_TYPE (expr)); error ("invalid initialization of reference of type "
"%qT from expression of type %qT", type,
TREE_TYPE (expr));
}
return error_mark_node; return error_mark_node;
} }
......
...@@ -4429,7 +4429,7 @@ extern tree type_passed_as (tree); ...@@ -4429,7 +4429,7 @@ extern tree type_passed_as (tree);
extern tree convert_for_arg_passing (tree, tree); extern tree convert_for_arg_passing (tree, tree);
extern bool is_properly_derived_from (tree, tree); extern bool is_properly_derived_from (tree, tree);
extern tree set_up_extended_ref_temp (tree, tree, 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 make_temporary_var_for_ref_to_temp (tree, tree);
extern tree strip_top_quals (tree); extern tree strip_top_quals (tree);
extern bool reference_related_p (tree, tree); extern bool reference_related_p (tree, tree);
......
...@@ -4390,7 +4390,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup) ...@@ -4390,7 +4390,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
DECL_INITIAL for local references (instead assigning to them DECL_INITIAL for local references (instead assigning to them
explicitly); we need to allow the temporary to be initialized explicitly); we need to allow the temporary to be initialized
first. */ first. */
tmp = initialize_reference (type, init, decl, cleanup); tmp = initialize_reference (type, init, decl, cleanup, tf_warning_or_error);
if (tmp == error_mark_node) if (tmp == error_mark_node)
return NULL_TREE; return NULL_TREE;
......
...@@ -6879,7 +6879,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags, ...@@ -6879,7 +6879,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
if (fndecl) if (fndecl)
savew = warningcount, savee = errorcount; savew = warningcount, savee = errorcount;
rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE, rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE,
/*cleanup=*/NULL); /*cleanup=*/NULL, complain);
if (fndecl) if (fndecl)
{ {
if (warningcount > savew) if (warningcount > savew)
......
2009-11-03 Jason Merrill <jason@redhat.com> 2009-11-03 Jason Merrill <jason@redhat.com>
PR c++/40944
* g++.dg/template/sfinae15.C: New.
PR c++/40687 PR c++/40687
* g++.dg/cpp0x/auto3.C: Remove xfail. * g++.dg/cpp0x/auto3.C: Remove xfail.
......
// PR c++/40944
// { dg-options -std=c++0x }
// { dg-do run }
template<typename T>
struct make { static T&& it(); };
void (*pf)(int&) = 0;
template< typename T >
int bar(T const& x,
decltype( pf(make<T const&>::it()) )* = 0 // SFINAE!
) {
return 1;
}
int bar(...) {
return 0;
}
int main() {
return bar(42);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment