aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-07-20 09:00:22 +0200
committerGitHub <noreply@github.com>2025-07-20 09:00:22 +0200
commit51af47e53c32d29c0e29cbdcd66d8bbd41b673f3 (patch)
treed06c54023e43fa4c28b5949426a275b96a90dbd8 /clang/lib/AST/ByteCode
parent58c3affdaa732fd6f8c7e6640396e7c6366bac9d (diff)
downloadllvm-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.cpp37
-rw-r--r--clang/lib/AST/ByteCode/Context.h4
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.