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; } }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits