-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[Clang] Fix concept checking for VLA types with sugared constraint substitution #163167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…bstitution Our concept-evaluation-on-normalized-constraint patch relies on sugared constraint substitution to properly work. However, it turns out that the sugar also includes non-dependent VLA types, leading to unnecessary/incorrect non-dependent Decl transform. We avoid this by skipping substitution into non-dependent SubstTTP types. This also removes a leftover debugging artifact in TransformTemplateArguments from that large patch.
@llvm/pr-subscribers-clang Author: Younan Zhang (zyn0217) ChangesOur concept-evaluation-on-normalized-constraint patch relies on sugared constraint substitution to properly work. However, it turns out that the sugar also includes non-dependent VLA types, leading to unnecessary/incorrect non-dependent Decl transform. We avoid this by skipping substitution into non-dependent SubstTTP types. This also removes a leftover debugging artifact in TransformTemplateArguments from that large patch. Fixes #102353 This is a regression on trunk so there's no release note. Full diff: https://github.com/llvm/llvm-project/pull/163167.diff 2 Files Affected:
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 940324bbc5e4d..bd21f35178b3b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -5107,12 +5107,9 @@ bool TreeTransform<Derived>::TransformTemplateArguments(
TemplateArgument::pack_iterator>
PackLocIterator;
- TemplateArgumentListInfo *PackOutput = &Outputs;
- TemplateArgumentListInfo New;
-
if (TransformTemplateArguments(
PackLocIterator(*this, In.getArgument().pack_begin()),
- PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,
+ PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
Uneval))
return true;
@@ -7220,7 +7217,10 @@ QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
// that needs to be transformed. This only tends to occur with default
// template arguments of template template parameters.
TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
- QualType Replacement = getDerived().TransformType(T->getReplacementType());
+ QualType Replacement =
+ T->getReplacementType()->isDependentType()
+ ? getDerived().TransformType(T->getReplacementType())
+ : T->getReplacementType();
if (Replacement.isNull())
return QualType();
diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index 3fbe7c0ac650f..d68b8fa432453 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1505,3 +1505,37 @@ namespace GH162770 {
template<typename... Ts> auto comma = (..., Ts());
auto b = comma<check<e{}>>;
} // namespace GH162770
+
+namespace GH102353 {
+
+template <typename _Tp, typename>
+concept same_as = true;
+
+template <typename _Lhs>
+concept assignable_from = requires {
+ { 0 } -> same_as<_Lhs>;
+};
+
+template <typename _Iter>
+struct span {
+ _Iter iter;
+};
+
+template <assignable_from _Iter>
+span(_Iter) -> span<_Iter>;
+
+template <class T, T value>
+void doHQScale() {
+ int srcWidth = value; // expected-note 2{{declared here}}
+ // We shouldn't crash with VLA types, which would appear when
+ // substituting constraint expressions, as they are part of the sugars now.
+ int edgeBuf_storage[srcWidth]; // expected-warning 2{{variable length arrays}} \
+ // expected-note 2{{read of non-const variable 'srcWidth'}}
+ span s(edgeBuf_storage);
+}
+
+void foo() {
+ doHQScale<int, 42>(); // expected-note {{requested here}}
+}
+
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is the way to go, it would be only adding another hack, but in this case for a very minor benefit.
Better to revert the original patch.
The assert this hits is wrong, but this needs #107942 in order to be able to improve that assertion.
TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName()); | ||
QualType Replacement = getDerived().TransformType(T->getReplacementType()); | ||
QualType Replacement = | ||
T->getReplacementType()->isDependentType() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to transform types even if they are only instantiation dependent.
Reverts #162991 That patch breaks certain uses of VLAs when combined with constrained types. This is a pre-existing issue that occurs when concepts are instantiated with sugar. See also #102353 and related PRs. I tried to fix it on top of the status quo in #163167, but that approach turned out to be unfeasible, and our maintainer was clearly unhappy with it, hence this revert. Even after this patch, some VLA uses remain broken on trunk (see the example below), because our normalization patch depends on sugar to correctly compile libc++, due to a very subtle underlying bug. Still, this is the best attempt to mitigate the problem for now. We discussed this and agreed that the long-term solution is to remove the sugar dependencies from concepts, before the VLA issue is properly resolved through a larger refactoring. I'll add a related test (which passes with partially applied sugar) after this revert, since I don't have a reduced example yet.
…163322) Reverts llvm#162991 That patch breaks certain uses of VLAs when combined with constrained types. This is a pre-existing issue that occurs when concepts are instantiated with sugar. See also llvm#102353 and related PRs. I tried to fix it on top of the status quo in llvm#163167, but that approach turned out to be unfeasible, and our maintainer was clearly unhappy with it, hence this revert. Even after this patch, some VLA uses remain broken on trunk (see the example below), because our normalization patch depends on sugar to correctly compile libc++, due to a very subtle underlying bug. Still, this is the best attempt to mitigate the problem for now. We discussed this and agreed that the long-term solution is to remove the sugar dependencies from concepts, before the VLA issue is properly resolved through a larger refactoring. I'll add a related test (which passes with partially applied sugar) after this revert, since I don't have a reduced example yet.
Our concept-evaluation-on-normalized-constraint patch relies on sugared constraint substitution to properly work. However, it turns out that the sugar also includes non-dependent VLA types, leading to unnecessary/incorrect non-dependent Decl transform.
We avoid this by skipping substitution into non-dependent SubstTTP types.
This also removes a leftover debugging artifact in TransformTemplateArguments from that large patch.
Fixes #102353
This is a regression on trunk so there's no release note.