re PR c++/49369 (typeof() strips const from member when used in const method)
authorJason Merrill <jason@redhat.com>
Tue, 14 Jun 2011 18:15:51 +0000 (14:15 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 14 Jun 2011 18:15:51 +0000 (14:15 -0400)
PR c++/49369
* class.c (build_base_path): Fix cv-quals in unevaluated context.

From-SVN: r175042

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/decltype30.C [new file with mode: 0644]

index 5ae5d2d91ce08e1f6389e5104dcfcbadd1c0bc41..a6c866567b82b0dff4dde32efd3adb07df8cf79a 100644 (file)
@@ -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.
index 69627cb6cb5bd9b0547ad278c2536e5bd0bbadb0..09444fb49ec454292e26dca8c8e47641cca379e0 100644 (file)
@@ -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;
 
index 8b324e3524faca3e10ecee6e9a949793e2d4e79a..7d5e46ae7c8b2342fc02706aabe7aac0f966e21e 100644 (file)
@@ -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 (file)
index 0000000..b23c9a9
--- /dev/null
@@ -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;
+}