diff options
author | Krystian Stasiowski <sdkrystian@gmail.com> | 2024-05-16 14:10:46 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-16 14:10:46 -0400 |
commit | da928c6d6e0e2f619fdaef71cea8747d9aef188d (patch) | |
tree | 8a473ca68c7242780039e94fd01662f0aafcdc57 /clang | |
parent | 23f1047daac9702876ca99b53e8fe649fca569fa (diff) | |
download | llvm-da928c6d6e0e2f619fdaef71cea8747d9aef188d.zip llvm-da928c6d6e0e2f619fdaef71cea8747d9aef188d.tar.gz llvm-da928c6d6e0e2f619fdaef71cea8747d9aef188d.tar.bz2 |
[Clang][Sema] ASTContext::getUnconstrainedType propagates dependence (#92425)
When the argument passed to `ASTContext::getUnconstrainedType` is an
unconstrained `AutoType`, will return the argument unchanged. However,
when called with a constrained `AutoType`, an unconstrained,
non-dependent `AutoType` will be returned even if the argument was
dependent. Consider the following:
```
template<typename T>
concept C = sizeof(T) == sizeof(int);
template<auto N>
struct A;
template<C auto N>
struct A<N>; // error: class template partial specialization is not more specialized than the primary template
```
When comparing the template parameters for equivalence,
`ASTContext::getUnconstrainedType` is used to remove the constraints per
[temp.over.link] p6 sentence 2. For the template
parameter `N` of the class template, it returns a dependent `AutoType`.
For the template parameter `N` of the class template partial
specialization, it returns a non-dependent `AutoType`. We subsequently
compare the adjusted types and find they are not equivalent, thus we
consider the partial specialization to not be more specialized than the
primary template per [temp.func.order] p6.2.2.
This patch changes `ASTContext::getUnconstrainedType` such that the
dependence of a constrained `AutoType` will propagate to the returned
unconstrained `AutoType`. This causes the above example to be correctly
accepted, fixing #77377.
Diffstat (limited to 'clang')
-rw-r--r-- | clang/docs/ReleaseNotes.rst | 1 | ||||
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 3 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp | 13 |
3 files changed, 16 insertions, 1 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index be4cded..2d2928e 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -723,6 +723,7 @@ Bug Fixes to C++ Support - Clang now ignores template parameters only used within the exception specification of candidate function templates during partial ordering when deducing template arguments from a function declaration or when taking the address of a function template. +- Fix a bug with checking constrained non-type template parameters for equivalence. Fixes (#GH77377). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 4475f39..8fc2bb8 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5910,7 +5910,8 @@ QualType ASTContext::getUnconstrainedType(QualType T) const { if (auto *AT = CanonT->getAs<AutoType>()) { if (!AT->isConstrained()) return T; - return getQualifiedType(getAutoType(QualType(), AT->getKeyword(), false, + return getQualifiedType(getAutoType(QualType(), AT->getKeyword(), + AT->isDependentType(), AT->containsUnexpandedParameterPack()), T.getQualifiers()); } diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp new file mode 100644 index 0000000..df1bbd5 --- /dev/null +++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s +// expected-no-diagnostics + +namespace GH77377 { + template<typename T> + concept C = sizeof(T) == sizeof(int); + + template<auto N> + struct A; + + template<C auto N> + struct A<N>; +} |