This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/47851 (type mismatch between decltype and not)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 01 Mar 2011 17:42:44 -0500
- Subject: C++ PATCH for c++/47851 (type mismatch between decltype and not)
standard_conversion, when asked for a conversion from Type& to const
Type, was returning a conversion to non-const Type. So when fold
stripped the COND_EXPR, operand 1 had a different type from the
COND_EXPR as a whole, and so we got surprising results.
Tested x86_64-pc-linux-gnu, applied to trunk.
commit e8f22a9b647de51facd637a4b9798fb76ad527d1
Author: Jason Merrill <jason@redhat.com>
Date: Tue Mar 1 17:02:50 2011 -0500
PR c++/47851
* call.c (standard_conversion): Provide requested cv-quals on
class rvalue conversion.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8dccbbe..a297f53 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -850,6 +850,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
enum tree_code fcode, tcode;
conversion *conv;
bool fromref = false;
+ tree qualified_to;
to = non_reference (to);
if (TREE_CODE (from) == REFERENCE_TYPE)
@@ -857,6 +858,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
fromref = true;
from = TREE_TYPE (from);
}
+ qualified_to = to;
to = strip_top_quals (to);
from = strip_top_quals (from);
@@ -918,7 +920,11 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
}
if (same_type_p (from, to))
- return conv;
+ {
+ if (CLASS_TYPE_P (to) && conv->kind == ck_rvalue)
+ conv->type = qualified_to;
+ return conv;
+ }
/* [conv.ptr]
A null pointer constant can be converted to a pointer type; ... A
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype25.C b/gcc/testsuite/g++.dg/cpp0x/decltype25.C
new file mode 100644
index 0000000..c9559f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype25.C
@@ -0,0 +1,20 @@
+// PR c++/47851
+// { dg-options -std=c++0x }
+
+struct Type {
+ void display_type();
+ void display_type() const { }
+};
+
+typedef Type const ConstType;
+
+struct ConvertibleToType {
+ operator Type&() { return *reinterpret_cast<Type*>(this); }
+};
+
+int main ()
+{
+ // Both lines should call the const variant.
+ (true ? ConvertibleToType() : ConstType()).display_type();
+ decltype((true ? ConvertibleToType() : ConstType()))().display_type();
+}