[clang] 51af47e - [clang][bytecode] Use in Expr::tryEvaluateStrLen() (#149677)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 20 00:00:26 PDT 2025
Author: Timm Baeder
Date: 2025-07-20T09:00:22+02:00
New Revision: 51af47e53c32d29c0e29cbdcd66d8bbd41b673f3
URL: https://github.com/llvm/llvm-project/commit/51af47e53c32d29c0e29cbdcd66d8bbd41b673f3
DIFF: https://github.com/llvm/llvm-project/commit/51af47e53c32d29c0e29cbdcd66d8bbd41b673f3.diff
LOG: [clang][bytecode] Use in Expr::tryEvaluateStrLen() (#149677)
Fixes #138475
Added:
Modified:
clang/lib/AST/ByteCode/Context.cpp
clang/lib/AST/ByteCode/Context.h
clang/lib/AST/ExprConstant.cpp
clang/test/Sema/warn-fortify-source.c
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp
index ead6e4af5d403..9e683d71f83bc 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 acf750421f8af..6065d3e53f230 100644
--- a/clang/lib/AST/ByteCode/Context.h
+++ b/clang/lib/AST/ByteCode/Context.h
@@ -66,6 +66,10 @@ class Context final {
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.
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index e57540511a9de..0d12161756467 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -18184,6 +18184,10 @@ bool Expr::EvaluateCharRangeAsString(APValue &Result,
bool Expr::tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const {
Expr::EvalStatus Status;
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
+
+ if (Info.EnableNewConstInterp)
+ return Info.Ctx.getInterpContext().evaluateStrlen(Info, this, Result);
+
return EvaluateBuiltinStrLen(this, Result, Info);
}
diff --git a/clang/test/Sema/warn-fortify-source.c b/clang/test/Sema/warn-fortify-source.c
index f48ea0907c657..216878c0836d8 100644
--- a/clang/test/Sema/warn-fortify-source.c
+++ b/clang/test/Sema/warn-fortify-source.c
@@ -3,6 +3,11 @@
// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify
// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS -fexperimental-new-constant-interpreter
+
typedef unsigned long size_t;
#ifdef __cplusplus
More information about the cfe-commits
mailing list