[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:
parent
7c14c5380a
commit
b39160ddfb
@ -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
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -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)
|
||||||
|
@ -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());
|
||||||
|
@ -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)]];
|
||||||
|
|
||||||
|
@ -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}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user