re PR c++/48665 (type of const member function)
authorJason Merrill <jason@redhat.com>
Mon, 22 Apr 2013 20:35:58 +0000 (16:35 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 22 Apr 2013 20:35:58 +0000 (16:35 -0400)
PR c++/48665
* rtti.c (get_typeid): Diagnose qualified function type.
* pt.c (tsubst) [POINTER_TYPE]: Likewise.

From-SVN: r198160

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/testsuite/g++.dg/cpp0x/decltype40.C
gcc/testsuite/g++.dg/rtti/fn-quals.C [new file with mode: 0644]
libstdc++-v3/ChangeLog
libstdc++-v3/testsuite/20_util/is_assignable/value.cc
libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc
libstdc++-v3/testsuite/20_util/reference_wrapper/result_type.cc
libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs-2.cc

index c91f3ec68d9b5ca803c4ef6aa59c05975e439352..cb27315c6b9412336f11e4e455ddba0ebbab8202 100644 (file)
@@ -1,5 +1,9 @@
 2013-04-22  Jason Merrill  <jason@redhat.com>
 
+       PR c++/48665
+       * rtti.c (get_typeid): Diagnose qualified function type.
+       * pt.c (tsubst) [POINTER_TYPE]: Likewise.
+
        * error.c (dump_aggr_type): Fix lambda detection.
        (dump_simple_decl): Pretty-print capture field.
 
index 77329a45b0652f748bc75dc72294e50e186e9385..6ce2770c1c603ca71a57f408124f444276f77f03 100644 (file)
@@ -11521,6 +11521,21 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
            return error_mark_node;
          }
+       else if (TREE_CODE (type) == FUNCTION_TYPE
+                && (type_memfn_quals (type) != TYPE_UNQUALIFIED
+                    || type_memfn_rqual (type) != REF_QUAL_NONE))
+         {
+           if (complain & tf_error)
+             {
+               if (code == POINTER_TYPE)
+                 error ("forming pointer to qualified function type %qT",
+                        type);
+               else
+                 error ("forming reference to qualified function type %qT",
+                        type);
+             }
+           return error_mark_node;
+         }
        else if (code == POINTER_TYPE)
          {
            r = build_pointer_type (type);
index b3c6687a75d95e65a95056a59ace6afd9bfd3b81..4e7316560ec9d4c936265148c346087a3930f392 100644 (file)
@@ -477,6 +477,16 @@ get_typeid (tree type, tsubst_flags_t complain)
      referenced type.  */
   type = non_reference (type);
 
+  /* This is not one of the uses of a qualified function type in 8.3.5.  */
+  if (TREE_CODE (type) == FUNCTION_TYPE
+      && (type_memfn_quals (type) != TYPE_UNQUALIFIED
+         || type_memfn_rqual (type) != REF_QUAL_NONE))
+    {
+      if (complain & tf_error)
+       error ("typeid of qualified function type %qT", type);
+      return error_mark_node;
+    }
+
   /* The top-level cv-qualifiers of the lvalue expression or the type-id
      that is the operand of typeid are always ignored.  */
   type = TYPE_MAIN_VARIANT (type);
index 7933c95b31f23708dd68272ebf005c38702a28c4..55258f4d88d6ec6afb0075c987b96a6ec0326026 100644 (file)
@@ -68,7 +68,7 @@ static_assert(sizeof(g<void(&)()>(0)) == 2, "Ouch");
 static_assert(sizeof(g<void(&&)()>(0)) == 2, "Ouch");
 static_assert(sizeof(f<void, void>(0)) == 2, "Ouch");
 static_assert(sizeof(f<void(), void()>(0)) == 2, "Ouch");
-static_assert(sizeof(f<void() const, void() const>(0)) == 2, "Ouch");
+//static_assert(sizeof(f<void() const, void() const>(0)) == 2, "Ouch");
 static_assert(sizeof(f<int, void>(0)) == 2, "Ouch");
 static_assert(sizeof(f<void, int>(0)) == 2, "Ouch");
 static_assert(sizeof(f<C, void>(0)) == 2, "Ouch");
@@ -90,7 +90,7 @@ static_assert(sizeof(g2<void(&)()>(0)) == 2, "Ouch");
 static_assert(sizeof(g2<void(&&)()>(0)) == 2, "Ouch");
 static_assert(sizeof(f2<void, void>(0)) == 2, "Ouch");
 static_assert(sizeof(f2<void(), void()>(0)) == 2, "Ouch");
-static_assert(sizeof(f2<void() const, void() const>(0)) == 2, "Ouch");
+//static_assert(sizeof(f2<void() const, void() const>(0)) == 2, "Ouch");
 static_assert(sizeof(f2<int, void>(0)) == 2, "Ouch");
 static_assert(sizeof(f2<void, int>(0)) == 2, "Ouch");
 static_assert(sizeof(f2<C, void>(0)) == 2, "Ouch");
diff --git a/gcc/testsuite/g++.dg/rtti/fn-quals.C b/gcc/testsuite/g++.dg/rtti/fn-quals.C
new file mode 100644 (file)
index 0000000..75d24f8
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/48665
+
+#include <typeinfo>
+extern "C" void abort();
+
+template<class A,class B> void f() {
+  if (typeid(A)==typeid(B)) abort(); // { dg-error "qualified function" }
+  if (typeid(A*)==typeid(B*)) abort(); // { dg-error "qualified function" }
+}
+int main() {
+  f<void()const,void()>();
+}
index a320fa7f527b3822543d8715e708f968ac579740..b44f584bfc26ab7186c62a925abf3a153f64c887 100644 (file)
@@ -1,3 +1,11 @@
+2013-04-22  Jason Merrill  <jason@redhat.com>
+
+       * testsuite/20_util/is_assignable/value.cc: Comment out tests involving
+       function-cv-quals.
+       * testsuite/20_util/is_constructible/value-2.cc: Likewise.
+       * testsuite/20_util/reference_wrapper/result_type.cc: Likewise.
+       * testsuite/20_util/reference_wrapper/typedefs-2.cc: Likewise.
+
 2013-04-22  François Dumont  <fdumont@gcc.gnu.org>
 
        * include/bits/hashtable_policy.h: Add C++11 allocator support.
index eade406593dbf2fbc61c6685787559b4ca4451dd..8d45671fd1dd3dc99ac2bd054b48156c3f5fded2 100644 (file)
@@ -277,8 +277,8 @@ static_assert(!std::is_assignable<DelAnyAssign&, int&>::value, "Error");
 static_assert(!std::is_assignable<DelAnyAssign&, const int&>::value, "Error");
 static_assert(!std::is_assignable<DelAnyAssign&, void>::value, "Error");
 static_assert(!std::is_assignable<DelAnyAssign&, void()>::value, "Error");
-static_assert(!std::is_assignable<DelAnyAssign&, void()
-const>::value, "Error");
+// static_assert(!std::is_assignable<DelAnyAssign&, void()
+// const>::value, "Error");
 static_assert(!std::is_assignable<DelAnyAssign&, void(&)()>::value, "Error");
 static_assert(!std::is_assignable<DelAnyAssign&, void(&&)()>::value, "Error");
 static_assert(!std::is_assignable<DelAnyAssign&,
@@ -600,7 +600,7 @@ static_assert(std::is_assignable<UAssignAll&,
 std::nullptr_t&>::value, "Error");
 static_assert(std::is_assignable<UAssignAll&, void()>::value, "Error");
 static_assert(std::is_assignable<UAssignAll&, void(&)()>::value, "Error");
-static_assert(std::is_assignable<UAssignAll&, void() const>::value, "Error");
+//static_assert(std::is_assignable<UAssignAll&, void() const>::value, "Error");
 static_assert(std::is_assignable<UAssignAll&, void(*)()>::value, "Error");
 static_assert(std::is_assignable<UAssignAll&, void(*&)()>::value, "Error");
 static_assert(std::is_assignable<UAssignAll&, int*>::value, "Error");
@@ -636,8 +636,8 @@ static_assert(!std::is_assignable<UDelAssignAll&,
 std::nullptr_t&>::value, "Error");
 static_assert(!std::is_assignable<UDelAssignAll&, void()>::value, "Error");
 static_assert(!std::is_assignable<UDelAssignAll&, void(&)()>::value, "Error");
-static_assert(!std::is_assignable<UDelAssignAll&, void()
-const>::value, "Error");
+// static_assert(!std::is_assignable<UDelAssignAll&, void()
+// const>::value, "Error");
 static_assert(!std::is_assignable<UDelAssignAll&, void(*)()>::value, "Error");
 static_assert(!std::is_assignable<UDelAssignAll&, void(*&)()>::value, "Error");
 static_assert(!std::is_assignable<UDelAssignAll&, int*>::value, "Error");
index ba6ffab77191947213843d92a56b4465fb956382..f3119111b0cb22e2792d5f2ca4fb1c3038a145b2 100644 (file)
@@ -72,8 +72,8 @@ static_assert(!std::is_constructible<DelEllipsis, SE>::value, "Error");
 static_assert(!std::is_constructible<DelEllipsis, OpE>::value, "Error");
 static_assert(!std::is_constructible<DelEllipsis, OpSE>::value, "Error");
 static_assert(!std::is_constructible<DelEllipsis, void()>::value, "Error");
-static_assert(!std::is_constructible<DelEllipsis, void() const>::value,
-             "Error");
+// static_assert(!std::is_constructible<DelEllipsis, void() const>::value,
+//           "Error");
 static_assert(!std::is_constructible<DelEllipsis, int[1]>::value, "Error");
 static_assert(!std::is_constructible<DelEllipsis, int[]>::value, "Error");
 static_assert(!std::is_constructible<DelEllipsis, int*>::value, "Error");
@@ -461,20 +461,20 @@ static_assert(!std::is_constructible<OpSE, void()>::value, "Error");
 static_assert(!std::is_constructible<int[], void()>::value, "Error");
 static_assert(!std::is_constructible<int[1], void()>::value, "Error");
 
-static_assert(!std::is_constructible<void(int) const,
-             void() const>::value, "Error");
-static_assert(!std::is_constructible<int, void() const>::value, "Error");
-static_assert(!std::is_constructible<Abstract, void() const>::value, "Error");
-static_assert(!std::is_constructible<std::nullptr_t, void() const>::value,
-             "Error");
-static_assert(!std::is_constructible<Empty, void() const>::value, "Error");
-static_assert(!std::is_constructible<U, void() const>::value, "Error");
-static_assert(!std::is_constructible<E, void() const>::value, "Error");
-static_assert(!std::is_constructible<SE, void() const>::value, "Error");
-static_assert(!std::is_constructible<OpE, void() const>::value, "Error");
-static_assert(!std::is_constructible<OpSE, void() const>::value, "Error");
-static_assert(!std::is_constructible<int[], void() const>::value, "Error");
-static_assert(!std::is_constructible<int[1], void() const>::value, "Error");
+// static_assert(!std::is_constructible<void(int) const,
+//           void() const>::value, "Error");
+// static_assert(!std::is_constructible<int, void() const>::value, "Error");
+// static_assert(!std::is_constructible<Abstract, void() const>::value, "Error");
+// static_assert(!std::is_constructible<std::nullptr_t, void() const>::value,
+//           "Error");
+// static_assert(!std::is_constructible<Empty, void() const>::value, "Error");
+// static_assert(!std::is_constructible<U, void() const>::value, "Error");
+// static_assert(!std::is_constructible<E, void() const>::value, "Error");
+// static_assert(!std::is_constructible<SE, void() const>::value, "Error");
+// static_assert(!std::is_constructible<OpE, void() const>::value, "Error");
+// static_assert(!std::is_constructible<OpSE, void() const>::value, "Error");
+// static_assert(!std::is_constructible<int[], void() const>::value, "Error");
+// static_assert(!std::is_constructible<int[1], void() const>::value, "Error");
 
 static_assert(!std::is_constructible<void, int, int>::value, "Error");
 static_assert(!std::is_constructible<void, Empty, B>::value, "Error");
@@ -488,8 +488,8 @@ static_assert(!std::is_constructible<void, int[], int[]>::value, "Error");
 static_assert(!std::is_constructible<void, void, int>::value, "Error");
 static_assert(!std::is_constructible<void, void, void>::value, "Error");
 static_assert(!std::is_constructible<void, void(), void()>::value, "Error");
-static_assert(!std::is_constructible<void, void() const,
-             void() volatile>::value, "Error");
+// static_assert(!std::is_constructible<void, void() const,
+//           void() volatile>::value, "Error");
 
 static_assert(!std::is_constructible<int, int, int>::value, "Error");
 static_assert(!std::is_constructible<const int, int, int>::value, "Error");
@@ -651,13 +651,13 @@ static_assert(!std::is_constructible<void(), void, void>::value, "Error");
 static_assert(!std::is_constructible<void(), void(), int>::value, "Error");
 static_assert(!std::is_constructible<void(), void(), void()>::value, "Error");
 
-static_assert(!std::is_constructible<void() const, int, int>::value, "Error");
-static_assert(!std::is_constructible<void() const, void, int>::value, "Error");
-static_assert(!std::is_constructible<void() const, void, void>::value, "Error");
-static_assert(!std::is_constructible<void() const, void() volatile,
-             int>::value, "Error");
-static_assert(!std::is_constructible<void() const, void() volatile const,
-             void() const>::value, "Error");
+// static_assert(!std::is_constructible<void() const, int, int>::value, "Error");
+// static_assert(!std::is_constructible<void() const, void, int>::value, "Error");
+// static_assert(!std::is_constructible<void() const, void, void>::value, "Error");
+// static_assert(!std::is_constructible<void() const, void() volatile,
+//           int>::value, "Error");
+// static_assert(!std::is_constructible<void() const, void() volatile const,
+//           void() const>::value, "Error");
 
 static_assert(!std::is_constructible<FromArgs<int>, int, int>::value, "Error");
 static_assert(!std::is_constructible<const FromArgs<int>, int, int>::value,
index 24cd6b911213fb1a66e4159472f2300c051c74ac..e849a5dc3b43978195bd8610c4de7b95b8b40e74 100644 (file)
@@ -27,9 +27,9 @@ using namespace std;
 struct T;
 
 reference_wrapper<int(float, ...)>::result_type                       i01;
-reference_wrapper<int(float, ...) const>::result_type                 i02;
-reference_wrapper<int(float, ...) volatile>::result_type              i03;
-reference_wrapper<int(float, ...) const volatile>::result_type        i04;
+// reference_wrapper<int(float, ...) const>::result_type                 i02;
+// reference_wrapper<int(float, ...) volatile>::result_type              i03;
+// reference_wrapper<int(float, ...) const volatile>::result_type        i04;
 
 reference_wrapper<int(*)(float, ...)>::result_type                    i05;
 reference_wrapper<int(* const)(float, ...)>::result_type              i06;
index 89dcd3bd70c7307f214ea82471af36b3be7f5af2..e0f7231ed929864aa3ae4b9c348e80666154c388 100644 (file)
 using namespace std;
 
 reference_wrapper<int(float)>::argument_type                               i01;
-reference_wrapper<int(float) const>::argument_type                         i02;
-reference_wrapper<int(float) volatile>::argument_type                      i03;
-reference_wrapper<int(float) const volatile>::argument_type                i04;
+// reference_wrapper<int(float) const>::argument_type                         i02;
+// reference_wrapper<int(float) volatile>::argument_type                      i03;
+// reference_wrapper<int(float) const volatile>::argument_type                i04;
 reference_wrapper<int(float)>::result_type                                 i05;
-reference_wrapper<int(float) const>::result_type                           i06;
-reference_wrapper<int(float) volatile>::result_type                        i07;
-reference_wrapper<int(float) const volatile>::result_type                  i08;
+// reference_wrapper<int(float) const>::result_type                           i06;
+// reference_wrapper<int(float) volatile>::result_type                        i07;
+// reference_wrapper<int(float) const volatile>::result_type                  i08;
 
 reference_wrapper<int(*)(float)>::argument_type                            i09;
 reference_wrapper<int(* const)(float)>::argument_type                      i10;
@@ -43,17 +43,17 @@ reference_wrapper<int(* volatile)(float)>::result_type                     i15;
 reference_wrapper<int(* const volatile)(float)>::result_type               i16;
 
 reference_wrapper<int(float, char)>::first_argument_type                   i17;
-reference_wrapper<int(float, char) const>::first_argument_type             i18;
-reference_wrapper<int(float, char) volatile>::first_argument_type          i19;
-reference_wrapper<int(float, char) const volatile>::first_argument_type    i20;
+// reference_wrapper<int(float, char) const>::first_argument_type             i18;
+// reference_wrapper<int(float, char) volatile>::first_argument_type          i19;
+// reference_wrapper<int(float, char) const volatile>::first_argument_type    i20;
 reference_wrapper<int(float, char)>::second_argument_type                  i21;
-reference_wrapper<int(float, char) const>::second_argument_type            i22;
-reference_wrapper<int(float, char) volatile>::second_argument_type         i23;
-reference_wrapper<int(float, char) const volatile>::second_argument_type   i24;
+// reference_wrapper<int(float, char) const>::second_argument_type            i22;
+// reference_wrapper<int(float, char) volatile>::second_argument_type         i23;
+// reference_wrapper<int(float, char) const volatile>::second_argument_type   i24;
 reference_wrapper<int(float, char)>::result_type                           i25;
-reference_wrapper<int(float, char) const>::result_type                     i26;
-reference_wrapper<int(float, char) volatile>::result_type                  i27;
-reference_wrapper<int(float, char) const volatile>::result_type            i28;
+// reference_wrapper<int(float, char) const>::result_type                     i26;
+// reference_wrapper<int(float, char) volatile>::result_type                  i27;
+// reference_wrapper<int(float, char) const volatile>::result_type            i28;
 
 reference_wrapper<int(*)(float, char)>::first_argument_type                i29;
 reference_wrapper<int(* const)(float, char)>::first_argument_type          i30;