Skip to content

Commit 2660114

Browse files
committed
[Clang] Fix dependent expression handling for assumptions
1 parent 10b80ff commit 2660114

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,8 @@ Bug Fixes to C++ Support
652652
an implicitly instantiated class template specialization. (#GH51051)
653653
- Fixed an assertion failure caused by invalid enum forward declarations. (#GH112208)
654654
- Name independent data members were not correctly initialized from default member initializers. (#GH114069)
655+
- Fixed expression transformation for ``[[assume(...)]]``, allowing using pack indexing expressions within the
656+
assumption if they also occur inside of a dependent lambda. (#GH114787)
655657

656658
Bug Fixes to AST Handling
657659
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,11 +2196,18 @@ TemplateInstantiator::TransformCXXAssumeAttr(const CXXAssumeAttr *AA) {
21962196
if (!Res.isUsable())
21972197
return AA;
21982198

2199-
Res = getSema().BuildCXXAssumeExpr(Res.get(), AA->getAttrName(),
2200-
AA->getRange());
2199+
Res = getSema().ActOnFinishFullExpr(Res.get(),
2200+
/*DiscardedValue=*/false);
22012201
if (!Res.isUsable())
22022202
return AA;
22032203

2204+
if (!(Res.get()->getDependence() & ExprDependence::TypeValueInstantiation)) {
2205+
Res = getSema().BuildCXXAssumeExpr(Res.get(), AA->getAttrName(),
2206+
AA->getRange());
2207+
if (!Res.isUsable())
2208+
return AA;
2209+
}
2210+
22042211
return CXXAssumeAttr::CreateImplicit(getSema().Context, Res.get(),
22052212
AA->getRange());
22062213
}

clang/test/SemaCXX/cxx23-assume.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected
33
// RUN: %clang_cc1 -std=c++23 -x c++ %s -verify -fexperimental-new-constant-interpreter
44
// RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected -fexperimental-new-constant-interpreter
5+
// RUN: %clang_cc1 -std=c++26 -x c++ %s -verify
6+
// RUN: %clang_cc1 -std=c++26 -x c++ %s -verify -fexperimental-new-constant-interpreter
57

68
struct A{};
79
struct B{ explicit operator bool() { return true; } };
@@ -167,3 +169,29 @@ int foo () {
167169
__attribute__((assume (a < b)));
168170
}
169171
}
172+
173+
namespace GH114787 {
174+
175+
// FIXME: Correct the C++26 value
176+
#if __cplusplus >= 202400L
177+
178+
constexpr int test(auto... xs) {
179+
// FIXME: Investigate why addresses of PackIndexingExprs are printed for the next
180+
// 'in call to' note.
181+
return [&]<int I>() { // expected-note {{in call to}}
182+
[[assume(
183+
xs...[I] == 2
184+
)]];
185+
[[assume(
186+
xs...[I + 1] == 0 // expected-note {{assumption evaluated to false}}
187+
)]];
188+
return xs...[I];
189+
}.template operator()<1>();
190+
}
191+
192+
static_assert(test(1, 2, 3, 5, 6) == 2); // expected-error {{not an integral constant expression}} \
193+
// expected-note {{in call to}}
194+
195+
#endif
196+
197+
} // namespace GH114787

0 commit comments

Comments
 (0)