[clang] [clang] Fix partial specialization matching for NTTPs of placeholder type (PR #225239)

Oliver Hunt via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 23 12:49:08 PDT 2026


================
@@ -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


More information about the cfe-commits mailing list