aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-11-03 12:11:18 -0500
committerJason Merrill <jason@gcc.gnu.org>2009-11-03 12:11:18 -0500
commit60d21717a2dd6a4132b45c4dc8c3ad0548349bfb (patch)
treeb8ebe932e20c29318830ff29443737efd3e15adf
parent2e32c99e12b96854cccb5cf037718a6cb1df1e72 (diff)
downloadgcc-60d21717a2dd6a4132b45c4dc8c3ad0548349bfb.zip
gcc-60d21717a2dd6a4132b45c4dc8c3ad0548349bfb.tar.gz
gcc-60d21717a2dd6a4132b45c4dc8c3ad0548349bfb.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c26
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/template/sfinae15.C23
7 files changed, 50 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6c7bdc6..1b87b04 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
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
* pt.c (do_auto_deduction): Diagnose inconsistent deduction.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 463257c..674e59d 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 7965514..c4b088b 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 de29d0b..97f1ac1f 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 25c257f..5b8523d 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 ab594d7..8898d92 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2009-11-03 Jason Merrill <jason@redhat.com>
+ 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 0000000..27bce25
--- /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<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);
+}