[Clang][Sema] Expression in assumption attribute should be full expression (#150814)

Add missing `ActOnFinishFullExpr` to `BuildCXXAssumeExpr`. We did it
during template instantiation but forgot non-template case.
This commit is contained in:
Yanzuo Liu 2025-07-29 11:53:02 +08:00 committed by GitHub
parent 7c14c5380a
commit b39160ddfb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 15 additions and 6 deletions

View File

@ -149,6 +149,8 @@ Bug Fixes to C++ Support
- Diagnose binding a reference to ``*nullptr`` during constant evaluation. (#GH48665) - Diagnose binding a reference to ``*nullptr`` during constant evaluation. (#GH48665)
- Suppress ``-Wdeprecated-declarations`` in implicitly generated functions. (#GH147293) - Suppress ``-Wdeprecated-declarations`` in implicitly generated functions. (#GH147293)
- Fix a crash when deleting a pointer to an incomplete array (#GH150359). - Fix a crash when deleting a pointer to an incomplete array (#GH150359).
- Fix an assertion failure when expression in assumption attribute
(``[[assume(expr)]]``) creates temporary objects.
Bug Fixes to AST Handling Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -795,6 +795,10 @@ ExprResult Sema::BuildCXXAssumeExpr(Expr *Assumption,
if (Res.isInvalid()) if (Res.isInvalid())
return ExprError(); return ExprError();
Res = ActOnFinishFullExpr(Res.get(), /*DiscardedValue=*/false);
if (Res.isInvalid())
return ExprError();
Assumption = Res.get(); Assumption = Res.get();
if (Assumption->HasSideEffects(Context)) if (Assumption->HasSideEffects(Context))
Diag(Assumption->getBeginLoc(), diag::warn_assume_side_effects) Diag(Assumption->getBeginLoc(), diag::warn_assume_side_effects)

View File

@ -2270,11 +2270,6 @@ TemplateInstantiator::TransformCXXAssumeAttr(const CXXAssumeAttr *AA) {
if (!Res.isUsable()) if (!Res.isUsable())
return AA; return AA;
Res = getSema().ActOnFinishFullExpr(Res.get(),
/*DiscardedValue=*/false);
if (!Res.isUsable())
return AA;
if (!(Res.get()->getDependence() & ExprDependence::TypeValueInstantiation)) { if (!(Res.get()->getDependence() & ExprDependence::TypeValueInstantiation)) {
Res = getSema().BuildCXXAssumeExpr(Res.get(), AA->getAttrName(), Res = getSema().BuildCXXAssumeExpr(Res.get(), AA->getAttrName(),
AA->getRange()); AA->getRange());

View File

@ -5,7 +5,7 @@ void f(int x, int y) {
[[assume(1)]]; [[assume(1)]];
[[assume(1.0)]]; [[assume(1.0)]];
[[assume(1 + 2 == 3)]]; [[assume(1 + 2 == 3)]];
[[assume(x ? 1 : 2)]]; [[assume(x ? 1 : 2)]]; // expected-warning {{converting the result of '?:' with integer constants to a boolean always evaluates to 'true'}}
[[assume(x && y)]]; [[assume(x && y)]];
[[assume(true)]] [[assume(true)]]; [[assume(true)]] [[assume(true)]];

View File

@ -8,6 +8,14 @@
struct A{}; struct A{};
struct B{ explicit operator bool() { return true; } }; struct B{ explicit operator bool() { return true; } };
// This should be the first test case of this file.
void IsActOnFinishFullExprCalled() {
// Do not add other test cases to this function.
// Make sure `ActOnFinishFullExpr` is called and creates `ExprWithCleanups`
// to avoid assertion failure.
[[assume(B{})]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}}
}
template <bool cond> template <bool cond>
void f() { void f() {
[[assume(cond)]]; // ext-warning {{C++23 extension}} [[assume(cond)]]; // ext-warning {{C++23 extension}}