aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-06-14 14:15:51 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-06-14 14:15:51 -0400
commit2bbf86a46bdece05107c54d94c4c8d41a2d17023 (patch)
tree1f39a784eab7c00be8e20e81adf42b87e4acf284
parent11f449abc6fc745486699f2f7079497d4c582d40 (diff)
downloadgcc-2bbf86a46bdece05107c54d94c4c8d41a2d17023.zip
gcc-2bbf86a46bdece05107c54d94c4c8d41a2d17023.tar.gz
gcc-2bbf86a46bdece05107c54d94c4c8d41a2d17023.tar.bz2
re PR c++/49369 (typeof() strips const from member when used in const method)
PR c++/49369 * class.c (build_base_path): Fix cv-quals in unevaluated context. From-SVN: r175042
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/class.c24
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype30.C17
4 files changed, 31 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5ae5d2d..a6c8665 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2011-06-14 Jason Merrill <jason@redhat.com>
+ PR c++/49369
+ * class.c (build_base_path): Fix cv-quals in unevaluated context.
+
PR c++/49290
* semantics.c (cxx_fold_indirect_ref): Local, more permissive copy
of fold_indirect_ref_1.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 69627cb..09444fb 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -289,6 +289,12 @@ build_base_path (enum tree_code code,
offset = BINFO_OFFSET (binfo);
fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
+ /* TARGET_TYPE has been extracted from BINFO, and, is therefore always
+ cv-unqualified. Extract the cv-qualifiers from EXPR so that the
+ expression returned matches the input. */
+ target_type = cp_build_qualified_type
+ (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
+ ptr_target_type = build_pointer_type (target_type);
/* Do we need to look in the vtable for the real offset? */
virtual_access = (v_binfo && fixed_type_p <= 0);
@@ -297,7 +303,7 @@ build_base_path (enum tree_code code,
source type is incomplete and the pointer value doesn't matter. */
if (cp_unevaluated_operand != 0)
{
- expr = build_nop (build_pointer_type (target_type), expr);
+ expr = build_nop (ptr_target_type, expr);
if (!want_pointer)
expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
return expr;
@@ -312,18 +318,7 @@ build_base_path (enum tree_code code,
field, because other parts of the compiler know that such
expressions are always non-NULL. */
if (!virtual_access && integer_zerop (offset))
- {
- tree class_type;
- /* TARGET_TYPE has been extracted from BINFO, and, is
- therefore always cv-unqualified. Extract the
- cv-qualifiers from EXPR so that the expression returned
- matches the input. */
- class_type = TREE_TYPE (TREE_TYPE (expr));
- target_type
- = cp_build_qualified_type (target_type,
- cp_type_quals (class_type));
- return build_nop (build_pointer_type (target_type), expr);
- }
+ return build_nop (ptr_target_type, expr);
null_test = error_mark_node;
}
@@ -407,9 +402,6 @@ build_base_path (enum tree_code code,
offset = v_offset;
}
- target_type = cp_build_qualified_type
- (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
- ptr_target_type = build_pointer_type (target_type);
if (want_pointer)
target_type = ptr_target_type;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8b324e3..7d5e46a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2011-06-14 Jason Merrill <jason@redhat.com>
+ PR c++/49369
+ * g++.dg/cpp0x/decltype30.C: New.
+
* g++.dg/cpp0x/constexpr-array-ptr7.C: New.
2011-06-14 Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype30.C b/gcc/testsuite/g++.dg/cpp0x/decltype30.C
new file mode 100644
index 0000000..b23c9a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype30.C
@@ -0,0 +1,17 @@
+// PR c++/49369
+// { dg-options -std=c++0x }
+
+template <class,class> struct assert_same;
+template <class T> struct assert_same<T,T> {};
+
+struct B {
+ int member;
+};
+
+struct C: B {
+ void method() const;
+};
+
+void C::method() const {
+ assert_same<decltype((B::member)), const int&> a;
+}