aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-02-26 11:48:22 -0500
committerJason Merrill <jason@gcc.gnu.org>2014-02-26 11:48:22 -0500
commit2f75f5154f05bd9ebc4e582ec5b4aca9f1d8bbac (patch)
tree6580ad7a572058722048aa42eec885cb6b9a146f /gcc
parentbb750f4f526edb782277f89a8b2a6ebeb0c60f95 (diff)
downloadgcc-2f75f5154f05bd9ebc4e582ec5b4aca9f1d8bbac.zip
gcc-2f75f5154f05bd9ebc4e582ec5b4aca9f1d8bbac.tar.gz
gcc-2f75f5154f05bd9ebc4e582ec5b4aca9f1d8bbac.tar.bz2
re PR c++/60345 (r208159 causes Firefox build error)
PR c++/60345 Revert: DR 1571 * call.c (reference_binding): Recurse on user-defined conversion. (convert_like_real) [ck_ref_bind]: Explain cv-qual mismatch. From-SVN: r208175
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/call.c64
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/overload3.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/rv-init1.C26
4 files changed, 26 insertions, 74 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a27643e..ce6085d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2014-02-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/60345
+ Revert:
+ DR 1571
+ * call.c (reference_binding): Recurse on user-defined conversion.
+ (convert_like_real) [ck_ref_bind]: Explain cv-qual mismatch.
+
2014-02-25 Jason Merrill <jason@redhat.com>
DR 1571
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 32767ec..700099d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1677,37 +1677,20 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
if (!conv)
return NULL;
- /* Limit this to C++11 mode for GCC 4.9, to be safe. */
- if (cxx_dialect >= cxx11 && conv->user_conv_p)
- {
- /* If initializing the temporary used a conversion function,
- recalculate the second conversion sequence. */
- for (conversion *t = conv; t; t = next_conversion (t))
- if (t->kind == ck_user
- && DECL_CONV_FN_P (t->cand->fn))
- {
- tree ftype = TREE_TYPE (TREE_TYPE (t->cand->fn));
- if (TREE_CODE (ftype) != REFERENCE_TYPE)
- /* Pretend we start from an xvalue to avoid trouble from
- LOOKUP_NO_TEMP_BIND. */
- ftype = cp_build_reference_type (ftype, true);
- conversion *new_second
- = reference_binding (rto, ftype, NULL_TREE, c_cast_p,
- flags|LOOKUP_NO_CONVERSION, complain);
- if (!new_second)
- return NULL;
- conv = merge_conversion_sequences (t, new_second);
- break;
- }
- }
-
- if (conv->kind != ck_ref_bind)
- conv = build_conv (ck_ref_bind, rto, conv);
-
+ conv = build_conv (ck_ref_bind, rto, conv);
/* This reference binding, unlike those above, requires the
creation of a temporary. */
conv->need_temporary_p = true;
- conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
+ if (TYPE_REF_IS_RVALUE (rto))
+ {
+ conv->rvaluedness_matches_p = 1;
+ /* In the second case, if the reference is an rvalue reference and
+ the second standard conversion sequence of the user-defined
+ conversion sequence includes an lvalue-to-rvalue conversion, the
+ program is ill-formed. */
+ if (conv->user_conv_p && next_conversion (conv)->kind == ck_rvalue)
+ conv->bad_p = 1;
+ }
return conv;
}
@@ -6230,25 +6213,12 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
if (convs->bad_p && !next_conversion (convs)->bad_p)
{
- gcc_assert (TYPE_REF_IS_RVALUE (ref_type));
-
- if (real_lvalue_p (expr)
- || next_conversion(convs)->kind == ck_rvalue)
- error_at (loc, "cannot bind %qT lvalue to %qT",
- TREE_TYPE (expr), totype);
- else if (!reference_compatible_p (totype, TREE_TYPE (expr)))
- error_at (loc, "binding %qT to reference of type %qT "
- "discards qualifiers", TREE_TYPE (expr),totype);
- else
- gcc_unreachable ();
- if (convs->user_conv_p)
- for (conversion *t = convs; t; t = next_conversion (t))
- if (t->kind == ck_user)
- {
- print_z_candidate (loc, "after user-defined conversion:",
- t->cand);
- break;
- }
+ gcc_assert (TYPE_REF_IS_RVALUE (ref_type)
+ && (real_lvalue_p (expr)
+ || next_conversion(convs)->kind == ck_rvalue));
+
+ error_at (loc, "cannot bind %qT lvalue to %qT",
+ TREE_TYPE (expr), totype);
if (fn)
inform (input_location,
"initializing argument %P of %q+D", argnum, fn);
diff --git a/gcc/testsuite/g++.dg/cpp0x/overload3.C b/gcc/testsuite/g++.dg/cpp0x/overload3.C
index b8f781a..e521b35 100644
--- a/gcc/testsuite/g++.dg/cpp0x/overload3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/overload3.C
@@ -13,5 +13,5 @@ struct wrap
int main()
{
wrap w;
- f(w); // { dg-error "" }
+ f(w); // { dg-error "lvalue" }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-init1.C b/gcc/testsuite/g++.dg/cpp0x/rv-init1.C
deleted file mode 100644
index 2e8d4f7..0000000
--- a/gcc/testsuite/g++.dg/cpp0x/rv-init1.C
+++ /dev/null
@@ -1,26 +0,0 @@
-// Core DR 1604/1571/1572
-// { dg-require-effective-target c++11 }
-
-struct Banana { };
-struct Enigma { operator const Banana(); };
-struct Doof { operator Banana&(); };
-void enigmatic() {
- typedef const Banana ConstBanana;
- Banana &&banana1 = ConstBanana(); // { dg-error "" }
- Banana &&banana2 = Enigma(); // { dg-error "" }
- Banana &&banana3 = Doof(); // { dg-error "" }
-}
-
-class A {
-public:
- operator volatile int &();
-};
-A a;
-
-const int & ir1a = a.operator volatile int&(); // { dg-error "" }
-const int & ir2a = a; // { dg-error "" }
-
-struct X {
- operator int&();
-} x;
-int&& rri2 = X(); // { dg-error "" }