Skip to content

Commit 5ef5eb6

Browse files
committed
[clang][Interp] Implement C++23 [[assume]] support
1 parent abca85b commit 5ef5eb6

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

clang/lib/AST/Interp/ByteCodeStmtGen.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,30 @@ bool ByteCodeStmtGen<Emitter>::visitDefaultStmt(const DefaultStmt *S) {
675675

676676
template <class Emitter>
677677
bool ByteCodeStmtGen<Emitter>::visitAttributedStmt(const AttributedStmt *S) {
678-
// Ignore all attributes.
678+
679+
for (const Attr *A : S->getAttrs()) {
680+
auto *AA = dyn_cast<CXXAssumeAttr>(A);
681+
if (!AA)
682+
continue;
683+
684+
assert(isa<NullStmt>(S->getSubStmt()));
685+
686+
const Expr *Assumption = AA->getAssumption();
687+
if (Assumption->isValueDependent())
688+
return false;
689+
690+
if (Assumption->HasSideEffects(this->Ctx.getASTContext()))
691+
continue;
692+
693+
// Evaluate assumption.
694+
if (!this->visitBool(Assumption))
695+
return false;
696+
697+
if (!this->emitAssume(Assumption))
698+
return false;
699+
}
700+
701+
// Ignore other attributes.
679702
return this->visitStmt(S->getSubStmt());
680703
}
681704

clang/lib/AST/Interp/Interp.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,6 +2327,18 @@ inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC,
23272327
return CheckDeclRef(S, OpPC, DR);
23282328
}
23292329

2330+
inline bool Assume(InterpState &S, CodePtr OpPC) {
2331+
const auto Val = S.Stk.pop<Boolean>();
2332+
2333+
if (Val)
2334+
return true;
2335+
2336+
// Else, diagnose.
2337+
const SourceLocation &Loc = S.Current->getLocation(OpPC);
2338+
S.CCEDiag(Loc, diag::note_constexpr_assumption_failed);
2339+
return false;
2340+
}
2341+
23302342
template <PrimType Name, class T = typename PrimConv<Name>::T>
23312343
inline bool OffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E) {
23322344
llvm::SmallVector<int64_t> ArrayIndices;

clang/lib/AST/Interp/Opcodes.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,8 @@ def InvalidDeclRef : Opcode {
736736
let Args = [ArgDeclRef];
737737
}
738738

739+
def Assume : Opcode;
740+
739741
def ArrayDecay : Opcode;
740742

741743
def CheckNonNullArg : Opcode {

clang/test/SemaCXX/cxx23-assume.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %clang_cc1 -std=c++23 -x c++ %s -verify
22
// RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected
3+
// RUN: %clang_cc1 -std=c++23 -x c++ %s -verify -fexperimental-new-constant-interpreter
4+
// RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected -fexperimental-new-constant-interpreter
35

46
struct A{};
57
struct B{ explicit operator bool() { return true; } };

0 commit comments

Comments
 (0)