================
@@ -8040,7 +8040,10 @@ bool ASTContext::isSameTemplateArgument(const 
TemplateArgument &Arg1,
            getCanonicalTemplateName(Arg2.getAsTemplateOrTemplatePattern());
 
   case TemplateArgument::Integral:
-    return llvm::APSInt::isSameValue(Arg1.getAsIntegral(),
+    // The types have to match as well as the values:
+    // C++ [temp.type]p2
+    return hasSameType(Arg1.getIntegralType(), Arg2.getIntegralType()) &&
+           llvm::APSInt::isSameValue(Arg1.getAsIntegral(),
                                      Arg2.getAsIntegral());
----------------
ojhunt wrote:

Ok, so I think maybe this would correct the issue I mentioned:

```suggestion
    return hasSameType(Arg1.getParamTypeForDecl(),
                       Arg2.getParamTypeForDecl()) &&
           Arg1.getAsDecl()->getUnderlyingDecl()->getCanonicalDecl() ==
               Arg2.getAsDecl()->getUnderlyingDecl()->getCanonicalDecl();
```

with this we get what I believe is correct behavior here:

```cpp
int x;
template <class T, auto P> struct S {
  static constexpr int value = 0;
};

template <class T> struct S<T, &x> {
  static constexpr int value = 1;
};

static_assert(S<void, &x>::value == 1);
static_assert(S<void, (const int *)&x>::value == 0);
```

Big _but_: I am basing this on the assumption that the behavior for this is 
correct:

```cpp
  template <auto P> struct Wibble {
    static constexpr int value = 0;
  };
  template <> struct Wibble<&x> {
    static constexpr int value = 1;
  };
  static_assert(Wibble<&x>::value == 1);
  static_assert(Wibble<(const int *)&x>::value == 0);
```


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

Reply via email to