Author: Timm Bäder Date: 2023-08-17T10:20:58+02:00 New Revision: 8a25145058d29fe0fa06cd3cdb90fea7e21228bb
URL: https://github.com/llvm/llvm-project/commit/8a25145058d29fe0fa06cd3cdb90fea7e21228bb DIFF: https://github.com/llvm/llvm-project/commit/8a25145058d29fe0fa06cd3cdb90fea7e21228bb.diff LOG: [clang][Interp] Pass CallExpr to builtin functions For some builtins, we need to do quite a bit of type checking ourselves, so pass the call expression along. This way we can inspect arguments, expected return value, etc. Differential Revision: https://reviews.llvm.org/D155545 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/InterpBuiltin.cpp clang/lib/AST/Interp/Opcodes.td Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 8a756e4fc2db42..1d528f642e10be 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1824,7 +1824,7 @@ bool ByteCodeExprGen<Emitter>::VisitBuiltinCallExpr(const CallExpr *E) { return false; } - if (!this->emitCallBI(Func, E)) + if (!this->emitCallBI(Func, E, E)) return false; QualType ReturnType = E->getCallReturnType(Ctx.getASTContext()); diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index c278144a387130..560daca1de6eda 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -174,7 +174,8 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, APFloat::opStatus Status); bool Interpret(InterpState &S, APValue &Result); /// Interpret a builtin function. -bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F); +bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, + const CallExpr *Call); enum class ArithOp { Add, Sub }; @@ -1741,13 +1742,14 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func) { return Call(S, OpPC, Func); } -inline bool CallBI(InterpState &S, CodePtr &PC, const Function *Func) { +inline bool CallBI(InterpState &S, CodePtr &PC, const Function *Func, + const CallExpr *CE) { auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC); InterpFrame *FrameBefore = S.Current; S.Current = NewFrame.get(); - if (InterpretBuiltin(S, PC, Func)) { + if (InterpretBuiltin(S, PC, Func, CE)) { NewFrame.release(); return true; } diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 2632ec7224379e..5277d05c82adfb 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -240,10 +240,9 @@ static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, /// second one is an integral value. static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, - const Function *Func) { - const Expr *E = S.Current->getExpr(OpPC); - const CallExpr *CE = cast<CallExpr>(E); - PrimType FPClassArgT = *S.getContext().classify(CE->getArgs()[1]->getType()); + const Function *Func, + const CallExpr *Call) { + PrimType FPClassArgT = *S.getContext().classify(Call->getArg(1)->getType()); APSInt FPClassArg = peekToAPSInt(S.Stk, FPClassArgT); const Floating &F = S.Stk.peek<Floating>(align(primSize(FPClassArgT) + primSize(PT_Float))); @@ -300,7 +299,8 @@ static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, return true; } -bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) { +bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, + const CallExpr *Call) { InterpFrame *Frame = S.Current; APValue Dummy; @@ -394,7 +394,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) { return Ret<PT_Sint32>(S, OpPC, Dummy); break; case Builtin::BI__builtin_isfpclass: - if (interp__builtin_isfpclass(S, OpPC, Frame, F)) + if (interp__builtin_isfpclass(S, OpPC, Frame, F, Call)) return Ret<PT_Sint32>(S, OpPC, Dummy); break; case Builtin::BI__builtin_fpclassify: diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 0f494c530b2568..a990d1ed976600 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -52,6 +52,7 @@ def ArgFltSemantics : ArgType { let Name = "const llvm::fltSemantics *"; } def ArgRoundingMode : ArgType { let Name = "llvm::RoundingMode"; } def ArgLETD: ArgType { let Name = "const LifetimeExtendedTemporaryDecl *"; } def ArgCastKind : ArgType { let Name = "CastKind"; } +def ArgCallExpr : ArgType { let Name = "const CallExpr *"; } //===----------------------------------------------------------------------===// // Classes of types instructions operate on. @@ -188,7 +189,7 @@ def CallVirt : Opcode { } def CallBI : Opcode { - let Args = [ArgFunction]; + let Args = [ArgFunction, ArgCallExpr]; let Types = []; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits