diff options
author | Jason Merrill <jason@redhat.com> | 2011-06-14 14:15:51 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-06-14 14:15:51 -0400 |
commit | 2bbf86a46bdece05107c54d94c4c8d41a2d17023 (patch) | |
tree | 1f39a784eab7c00be8e20e81adf42b87e4acf284 | |
parent | 11f449abc6fc745486699f2f7079497d4c582d40 (diff) | |
download | gcc-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/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/class.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/decltype30.C | 17 |
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; +} |