https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/179230
tryEvaluateString was returning an std::optional, but the other try* API was not. Update tryEvaluateObjectSize and tryEvaluateStrLen to return an std::optional<uint64_t>. >From bce4db97d78fac40031802dfbe37de7370ee39fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Mon, 2 Feb 2026 14:29:05 +0100 Subject: [PATCH] [clang] Return std::optional from all Expr::tryEvaluate* API tryEvaluateString was returning an std::optional, but the other try* API was not. Update tryEvaluateObjectSize and tryEvaluateStrLen to return an std::optional<uint64_t>. --- clang/include/clang/AST/Expr.h | 6 ++--- clang/lib/AST/ExprConstant.cpp | 35 +++++++++++++++++-------- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 9 ++++--- clang/lib/CodeGen/CGBuiltin.cpp | 9 ++++--- clang/lib/Sema/SemaChecking.cpp | 24 +++++++++-------- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 3e30a8b420f19..4bea35015827a 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -774,14 +774,14 @@ class Expr : public ValueStmt { /// /// \param Type - How to evaluate the size of the Expr, as defined by the /// "type" parameter of __builtin_object_size - bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, - unsigned Type) const; + std::optional<uint64_t> tryEvaluateObjectSize(const ASTContext &Ctx, + unsigned Type) const; /// If the current Expr is a pointer, this will try to statically /// determine the strlen of the string pointed to. /// Returns true if all of the above holds and we were able to figure out the /// strlen, false otherwise. - bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const; + std::optional<uint64_t> tryEvaluateStrLen(const ASTContext &Ctx) const; bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 8f4907e6db01e..d1f061d610b1a 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -21659,18 +21659,25 @@ bool Expr::isPotentialConstantExprUnevaluated(Expr *E, return Diags.empty(); } -bool Expr::tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, - unsigned Type) const { +std::optional<uint64_t> Expr::tryEvaluateObjectSize(const ASTContext &Ctx, + unsigned Type) const { if (!getType()->isPointerType()) return false; Expr::EvalStatus Status; EvalInfo Info(Ctx, Status, EvaluationMode::ConstantFold); - if (Info.EnableNewConstInterp) { - return Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info, this, Type, - Result); - } - return tryEvaluateBuiltinObjectSize(this, Type, Info, Result); + uint64_t Result = ~0u; + bool Success; + if (Info.EnableNewConstInterp) + Success = Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info, this, + Type, Result); + else + Success = tryEvaluateBuiltinObjectSize(this, Type, Info, Result); + + if (!Success) + return std::nullopt; + + return Result; } static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result, @@ -21814,14 +21821,20 @@ bool Expr::EvaluateCharRangeAsString(APValue &Result, PtrExpression, Ctx, Status); } -bool Expr::tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const { +std::optional<uint64_t> Expr::tryEvaluateStrLen(const ASTContext &Ctx) const { Expr::EvalStatus Status; EvalInfo Info(Ctx, Status, EvaluationMode::ConstantFold); - if (Info.EnableNewConstInterp) - return Info.Ctx.getInterpContext().evaluateStrlen(Info, this, Result); + uint64_t Result = ~0u; + if (Info.EnableNewConstInterp) { + if (!Info.Ctx.getInterpContext().evaluateStrlen(Info, this, Result)) + return std::nullopt; + } else { + if (!EvaluateBuiltinStrLen(this, Result, Info)) + return std::nullopt; + } - return EvaluateBuiltinStrLen(this, Result, Info); + return Result; } namespace { diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 580ada8901cbb..da0c3f1caf3a0 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -2033,8 +2033,9 @@ mlir::Value CIRGenFunction::emitBuiltinObjectSize(const Expr *e, unsigned type, mlir::Value CIRGenFunction::evaluateOrEmitBuiltinObjectSize( const Expr *e, unsigned type, cir::IntType resType, mlir::Value emittedE, bool isDynamic) { - uint64_t objectSize; - if (!e->tryEvaluateObjectSize(objectSize, getContext(), type)) - return emitBuiltinObjectSize(e, type, resType, emittedE, isDynamic); - return builder.getConstInt(getLoc(e->getSourceRange()), resType, objectSize); + if (std::optional<uint64_t> objectSize = + E->tryEvaluateObjectSize(getContext(), type)) + return builder.getConstInt(getLoc(e->getSourceRange()), resType, + *objectSize); + return emitBuiltinObjectSize(e, type, resType, emittedE, isDynamic); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 339d6cff0a386..2624096e7ddc0 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -924,10 +924,11 @@ CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, llvm::IntegerType *ResType, llvm::Value *EmittedE, bool IsDynamic) { - uint64_t ObjectSize; - if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type)) - return emitBuiltinObjectSize(E, Type, ResType, EmittedE, IsDynamic); - return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true); + + if (std::optional<uint64_t> ObjectSize = + E->tryEvaluateObjectSize(getContext(), Type)) + return ConstantInt::get(ResType, *ObjectSize, /*isSigned=*/true); + return emitBuiltinObjectSize(E, Type, ResType, EmittedE, IsDynamic); } namespace { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e2e1b37572364..c0e1f019363f8 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1217,12 +1217,12 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, return std::nullopt; const Expr *ObjArg = TheCall->getArg(NewIndex); - uint64_t Result; - if (!ObjArg->tryEvaluateObjectSize(Result, getASTContext(), BOSType)) - return std::nullopt; - - // Get the object size in the target's size_t width. - return llvm::APSInt::getUnsigned(Result).extOrTrunc(SizeTypeWidth); + if (std::optional<uint64_t> ObjSize = + ObjArg->tryEvaluateObjectSize(getASTContext(), BOSType)) { + // Get the object size in the target's size_t width. + return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth); + } + return std::nullopt; }; auto ComputeStrLenArgument = @@ -1233,11 +1233,13 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, unsigned NewIndex = *IndexOptional; const Expr *ObjArg = TheCall->getArg(NewIndex); - uint64_t Result; - if (!ObjArg->tryEvaluateStrLen(Result, getASTContext())) - return std::nullopt; - // Add 1 for null byte. - return llvm::APSInt::getUnsigned(Result + 1).extOrTrunc(SizeTypeWidth); + + if (std::optional<uint64_t> Result = + ObjArg->tryEvaluateStrLen(getASTContext())) { + // Add 1 for null byte. + return llvm::APSInt::getUnsigned(*Result + 1).extOrTrunc(SizeTypeWidth); + } + return std::nullopt; }; std::optional<llvm::APSInt> SourceSize; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
