[clang] 5ef5eb6 - [clang][Interp] Implement C++23 [[assume]] support
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 22 06:28:44 PDT 2024
Author: Timm Bäder
Date: 2024-04-22T15:28:00+02:00
New Revision: 5ef5eb66fb428aaf61fb51b709f065c069c11242
URL: https://github.com/llvm/llvm-project/commit/5ef5eb66fb428aaf61fb51b709f065c069c11242
DIFF: https://github.com/llvm/llvm-project/commit/5ef5eb66fb428aaf61fb51b709f065c069c11242.diff
LOG: [clang][Interp] Implement C++23 [[assume]] support
Added:
Modified:
clang/lib/AST/Interp/ByteCodeStmtGen.cpp
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Opcodes.td
clang/test/SemaCXX/cxx23-assume.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index 55a06f37a0c3de..36dab6252ece67 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -675,7 +675,30 @@ bool ByteCodeStmtGen<Emitter>::visitDefaultStmt(const DefaultStmt *S) {
template <class Emitter>
bool ByteCodeStmtGen<Emitter>::visitAttributedStmt(const AttributedStmt *S) {
- // Ignore all attributes.
+
+ for (const Attr *A : S->getAttrs()) {
+ auto *AA = dyn_cast<CXXAssumeAttr>(A);
+ if (!AA)
+ continue;
+
+ assert(isa<NullStmt>(S->getSubStmt()));
+
+ const Expr *Assumption = AA->getAssumption();
+ if (Assumption->isValueDependent())
+ return false;
+
+ if (Assumption->HasSideEffects(this->Ctx.getASTContext()))
+ continue;
+
+ // Evaluate assumption.
+ if (!this->visitBool(Assumption))
+ return false;
+
+ if (!this->emitAssume(Assumption))
+ return false;
+ }
+
+ // Ignore other attributes.
return this->visitStmt(S->getSubStmt());
}
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index d593d764d85a49..9283f697c00709 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -2327,6 +2327,18 @@ inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC,
return CheckDeclRef(S, OpPC, DR);
}
+inline bool Assume(InterpState &S, CodePtr OpPC) {
+ const auto Val = S.Stk.pop<Boolean>();
+
+ if (Val)
+ return true;
+
+ // Else, diagnose.
+ const SourceLocation &Loc = S.Current->getLocation(OpPC);
+ S.CCEDiag(Loc, diag::note_constexpr_assumption_failed);
+ return false;
+}
+
template <PrimType Name, class T = typename PrimConv<Name>::T>
inline bool OffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E) {
llvm::SmallVector<int64_t> ArrayIndices;
diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 0a6c976f9b5b76..742785b28eb4d7 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -736,6 +736,8 @@ def InvalidDeclRef : Opcode {
let Args = [ArgDeclRef];
}
+def Assume : Opcode;
+
def ArrayDecay : Opcode;
def CheckNonNullArg : Opcode {
diff --git a/clang/test/SemaCXX/cxx23-assume.cpp b/clang/test/SemaCXX/cxx23-assume.cpp
index 478da092471aff..8676970de14f61 100644
--- a/clang/test/SemaCXX/cxx23-assume.cpp
+++ b/clang/test/SemaCXX/cxx23-assume.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 -std=c++23 -x c++ %s -verify
// RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected
+// RUN: %clang_cc1 -std=c++23 -x c++ %s -verify -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected -fexperimental-new-constant-interpreter
struct A{};
struct B{ explicit operator bool() { return true; } };
More information about the cfe-commits
mailing list