diff mbox

[C++] PR 57466 (DR 1584)

Message ID 53BBF16C.2080403@oracle.com
State New
Headers show

Commit Message

Paolo Carlini July 8, 2014, 1:26 p.m. UTC
Hi,

the defect 
(http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584) is 
Ready and both clang and SolarisStudio already implement it. The below 
very simple tweak seems enough, testing is fine on x86_64-linux.

Thanks!
Paolo.

/////////////////////
/cp
2014-07-08  Paolo Carlini  <paolo.carlini@oracle.com>

	DR 1584
	PR c++/57466
	* pt.c (unify): Implement resolution, disregard cv-qualifiers of
	function types.

/testsuite
2014-07-08  Paolo Carlini  <paolo.carlini@oracle.com>

	DR 1584
	PR c++/57466
	* g++.dg/template/pr57466.C: New.
	* g++.dg/cpp0x/pr57466.C: Likewise.
	* g++.dg/template/unify6.C: Update.

Comments

Jason Merrill July 8, 2014, 10:26 p.m. UTC | #1
I'd rather handle this in check_cv_quals_for_unify.

Jason
diff mbox

Patch

Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 212347)
+++ cp/pt.c	(working copy)
@@ -17831,8 +17831,13 @@  unify (tree tparms, tree targs, tree parm, tree ar
 	     a match unless we are allowing additional qualification.
 	     If ARG is `const int' and PARM is just `T' that's OK;
 	     that binds `const int' to `T'.  */
-	  if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL,
-					 arg, parm))
+
+	  /* DR 1584: cv-qualification of a deduced function type is
+	     ignored; see 8.3.5 [dcl.fct].  */
+	  if (TREE_CODE (arg) != FUNCTION_TYPE
+	      && !check_cv_quals_for_unify (strict_in
+					    | UNIFY_ALLOW_LESS_CV_QUAL,
+					    arg, parm))
 	    return unify_cv_qual_mismatch (explain_p, parm, arg);
 
 	  /* Consider the case where ARG is `const volatile int' and
Index: testsuite/g++.dg/cpp0x/pr57466.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr57466.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/pr57466.C	(working copy)
@@ -0,0 +1,18 @@ 
+// PR c++/57466
+// { dg-do compile { target c++11 } }
+
+template<typename T>
+  constexpr bool
+  is_pointer(const T*)
+  { return true; }
+
+template<typename T>
+  constexpr bool
+  is_pointer(const T&)
+  { return false; }
+
+using F = void();
+
+constexpr F* f = nullptr;
+
+static_assert( is_pointer(f), "function pointer is a pointer" );
Index: testsuite/g++.dg/template/pr57466.C
===================================================================
--- testsuite/g++.dg/template/pr57466.C	(revision 0)
+++ testsuite/g++.dg/template/pr57466.C	(working copy)
@@ -0,0 +1,8 @@ 
+// DR 1584, PR c++/57466
+
+template<class T> void f2(const T*);
+void g2();
+
+void m() {
+  f2(g2);    // OK: cv-qualification of deduced function type ignored
+}
Index: testsuite/g++.dg/template/unify6.C
===================================================================
--- testsuite/g++.dg/template/unify6.C	(revision 212347)
+++ testsuite/g++.dg/template/unify6.C	(working copy)
@@ -3,21 +3,20 @@ 
 
 void Baz ();
 
-template <typename T> void Foo1 (T *); // #1
-template <typename T> void Foo1 (T const *a) {a (1);} // #2
+template <typename T> void Foo1 (T *);
+template <typename T> void Foo1 (T const *a) {a (1);} // { dg-error "too many arguments" }
 
 template <typename T> T const *Foo2 (T *);
 
-template <typename T> void Foo3 (T *, T const * = 0); // { dg-message "note" }
+template <typename T> void Foo3 (T *, T const * = 0);
 
 void Bar ()
 {
-  Foo1 (&Baz); // #1
+  Foo1 (&Baz); // { dg-message "required from here" }
 
   Foo2 (&Baz);
 
   Foo3 (&Baz);
 
-  Foo3 (&Baz, &Baz); // { dg-error "no matching function" "" }
-  // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 21 }
+  Foo3 (&Baz, &Baz);
 }