================
@@ -406,39 +406,41 @@ namespace PR42362 {
 namespace QualConv {
   int *X;
   template<const int *const *P> void f() {
-    using T = decltype(P);
-    using T = const int* const*;
+    using T = decltype(P);       // expected-note  {{previous definition}}
+    using T = const int* const*; // expected-error {{redefinition with 
different types ('const int *const *' vs 'decltype(P)' (aka 'const int *const 
*'))}}
   }
   template void f<&X>();
 
   template<const int *const &R> void g() {
-    using T = decltype(R);
-    using T = const int *const &;
+    using T = decltype(R);        // expected-note  {{previous definition}}
+    using T = const int *const &; // expected-error {{redefinition with 
different types ('const int *const &' vs 'decltype(R)' (aka 'const int *const 
&'))}}
   }
   template void g<(const int *const&)X>();
 }
 
 namespace FunctionConversion {
   struct a { void c(char *) noexcept; };
   template<void (a::*f)(char*)> void g() {
-    using T = decltype(f);
+    using T = decltype(f);        // expected-note  {{previous definition}}
     using T = void (a::*)(char*); // (not 'noexcept')
+    // expected-error@-1 {{redefinition with different types ('void 
(a::*)(char *)' vs 'decltype(f)' (aka 'void (a::*)(char *)'))}}
   }
   template void g<&a::c>();
 
   void c() noexcept;
   template<void (*p)()> void h() {
-    using T = decltype(p);
+    using T = decltype(p);// expected-note  {{previous definition}}
     using T = void (*)(); // (not 'noexcept')
+    // expected-error@-1 {{redefinition with different types ('void (*)()' vs 
'decltype(p)' (aka 'void (*)()'))}}
   }
   template void h<&c>();
 }
 
 namespace VoidPtr {
   // Note, this is an extension in C++17 but valid in C++20.
   template<void *P> void f() {
-    using T = decltype(P);
-    using T = void*;
+    using T = decltype(P); // expected-note  {{previous definition}}
+    using T = void*;       // expected-error {{redefinition with different 
types ('void *' vs 'decltype(P)' (aka 'void *'))}}
----------------
mizvekov wrote:

> I'm aware of this being preexisting, but that's why I'm pushing back -- 
> that's been the reason to not address the issue previously.

The issue why this has not been addressed before is that nobody had come up 
with a solution, as far as I know.

I have never seen an attempt to solve CWG1980 in Clang.

There was an attempt to solve CWG2064 in isolation, but then it was concluded 
we couldn't go forward with it without solving CWG1980.

Can you link to any previous discussion around this?

> No other implementation implements these DRs.

No, that's not true, every other compiler implements a solution to CWG1980.

Clang is the only compiler in which void_t is useless because you can't do 
SFINAE with it.

And CWG2064 is at least mitigated in GCC.

And CWG3179 is a minor issue I come up recently during the investigation for 
this patch, it's perfectly reasonable no one implements it yet.

> , so there's not really anything on fire justifying why we need to land this 
> in a state where the diagnostics are incomprehensible to users

Even if we disregard that the issue is unlikely to be seen by users, there is 
at least the problem that the patch is large already, and this is a reasonable 
cutting point to be implemented and reviewed separately.

https://github.com/llvm/llvm-project/pull/190495
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to