diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-07-20 09:00:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-20 09:00:22 +0200 |
commit | 51af47e53c32d29c0e29cbdcd66d8bbd41b673f3 (patch) | |
tree | d06c54023e43fa4c28b5949426a275b96a90dbd8 /clang/lib/AST/ByteCode | |
parent | 58c3affdaa732fd6f8c7e6640396e7c6366bac9d (diff) | |
download | llvm-51af47e53c32d29c0e29cbdcd66d8bbd41b673f3.zip llvm-51af47e53c32d29c0e29cbdcd66d8bbd41b673f3.tar.gz llvm-51af47e53c32d29c0e29cbdcd66d8bbd41b673f3.tar.bz2 |
[clang][bytecode] Use in Expr::tryEvaluateStrLen() (#149677)
Fixes #138475
Diffstat (limited to 'clang/lib/AST/ByteCode')
-rw-r--r-- | clang/lib/AST/ByteCode/Context.cpp | 37 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/Context.h | 4 |
2 files changed, 41 insertions, 0 deletions
diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp index ead6e4a..9e683d7 100644 --- a/clang/lib/AST/ByteCode/Context.cpp +++ b/clang/lib/AST/ByteCode/Context.cpp @@ -235,6 +235,43 @@ bool Context::evaluateCharRange(State &Parent, const Expr *SizeExpr, return evaluateStringRepr(Parent, SizeExpr, PtrExpr, Result); } +bool Context::evaluateStrlen(State &Parent, const Expr *E, uint64_t &Result) { + assert(Stk.empty()); + Compiler<EvalEmitter> C(*this, *P, Parent, Stk); + + auto PtrRes = C.interpretAsPointer(E, [&](const Pointer &Ptr) { + const Descriptor *FieldDesc = Ptr.getFieldDesc(); + if (!FieldDesc->isPrimitiveArray()) + return false; + + unsigned N = Ptr.getNumElems(); + if (Ptr.elemSize() == 1) { + Result = strnlen(reinterpret_cast<const char *>(Ptr.getRawAddress()), N); + return Result != N; + } + + PrimType ElemT = FieldDesc->getPrimType(); + Result = 0; + for (unsigned I = Ptr.getIndex(); I != N; ++I) { + INT_TYPE_SWITCH(ElemT, { + auto Elem = Ptr.atIndex(I).deref<T>(); + if (Elem.isZero()) + return true; + ++Result; + }); + } + // We didn't find a 0 byte. + return false; + }); + + if (PtrRes.isInvalid()) { + C.cleanup(); + Stk.clear(); + return false; + } + return true; +} + const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); } static PrimType integralTypeToPrimTypeS(unsigned BitWidth) { diff --git a/clang/lib/AST/ByteCode/Context.h b/clang/lib/AST/ByteCode/Context.h index acf7504..6065d3e 100644 --- a/clang/lib/AST/ByteCode/Context.h +++ b/clang/lib/AST/ByteCode/Context.h @@ -66,6 +66,10 @@ public: bool evaluateCharRange(State &Parent, const Expr *SizeExpr, const Expr *PtrExpr, std::string &Result); + /// Evalute \param E and if it can be evaluated to a string literal, + /// run strlen() on it. + bool evaluateStrlen(State &Parent, const Expr *E, uint64_t &Result); + /// Returns the AST context. ASTContext &getASTContext() const { return Ctx; } /// Returns the language options. |