github-actions[bot] wrote: <!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning: <details> <summary> You can test this locally with the following command: </summary> ``````````bash git-clang-format --diff 17daa204feadf9c28fc13b7daa69c3cbe865b238 253f58f0e34bc6dedbbfe17f68cfe9baa3a9146f -- clang/test/SemaCXX/builtin-is-within-lifetime.cpp clang/include/clang/Basic/Builtins.h clang/lib/AST/ExprConstant.cpp clang/lib/AST/Interp/State.h clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExpr.cpp clang/test/Sema/builtin-redecl.cpp `````````` </details> <details> <summary> View the diff from clang-format here. </summary> ``````````diff diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f3b31d87dd..ffe2f172a9 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1507,7 +1507,8 @@ CallStackFrame::~CallStackFrame() { } static bool isRead(AccessKinds AK) { - return AK == AK_Read || AK == AK_ReadObjectRepresentation || AK == AK_IsWithinLifetime; + return AK == AK_Read || AK == AK_ReadObjectRepresentation || + AK == AK_IsWithinLifetime; } static bool isModification(AccessKinds AK) { @@ -1535,7 +1536,8 @@ static bool isAnyAccess(AccessKinds AK) { /// Is this an access per the C++ definition? static bool isFormalAccess(AccessKinds AK) { - return isAnyAccess(AK) && AK != AK_Construct && AK != AK_Destroy && AK != AK_IsWithinLifetime; + return isAnyAccess(AK) && AK != AK_Construct && AK != AK_Destroy && + AK != AK_IsWithinLifetime; } /// Is this kind of axcess valid on an indeterminate object value? @@ -3655,7 +3657,8 @@ struct CompleteObject { // In C++14 onwards, it is permitted to read a mutable member whose // lifetime began within the evaluation. // FIXME: Should we also allow this in C++11? - if (!Info.getLangOpts().CPlusPlus14 && AK != AccessKinds::AK_IsWithinLifetime) + if (!Info.getLangOpts().CPlusPlus14 && + AK != AccessKinds::AK_IsWithinLifetime) return false; return lifetimeStartedInEvaluation(Info, Base, /*MutableSubobject*/true); } @@ -4093,7 +4096,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, // started in the current evaluation. BaseVal = Info.EvaluatingDeclValue; if (AK == AccessKinds::AK_IsWithinLifetime) - return CompleteObject(); // Not within lifetime + return CompleteObject(); // Not within lifetime } else if (const ValueDecl *D = LVal.Base.dyn_cast<const ValueDecl *>()) { // Allow reading from a GUID declaration. if (auto *GD = dyn_cast<MSGuidDecl>(D)) { @@ -11508,7 +11511,8 @@ public: bool ZeroInitialization(const Expr *E) { return Success(0, E); } - friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &, const CallExpr *); + friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &, + const CallExpr *); //===--------------------------------------------------------------------===// // Visitor Methods @@ -17030,56 +17034,70 @@ bool Expr::tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const { } namespace { - struct IsWithinLifetimeHandler { - EvalInfo &Info; - static constexpr AccessKinds AccessKind = AccessKinds::AK_IsWithinLifetime; - using result_type = std::optional<bool>; - std::optional<bool> failed() { return std::nullopt; } - template<typename T> - std::optional<bool> found(T &Subobj, QualType SubobjType) { - return true; - } - }; +struct IsWithinLifetimeHandler { + EvalInfo &Info; + static constexpr AccessKinds AccessKind = AccessKinds::AK_IsWithinLifetime; + using result_type = std::optional<bool>; + std::optional<bool> failed() { return std::nullopt; } + template <typename T> + std::optional<bool> found(T &Subobj, QualType SubobjType) { + return true; + } +}; - std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE, const CallExpr *E) { - EvalInfo& Info = IEE.Info; - //assert(Info.InConstantContext && "Call to consteval builtin not in constant context?"); - assert(E->getBuiltinCallee() == Builtin::BI__builtin_is_within_lifetime); - const Expr *Arg = E->getArg(0); - if (Arg->isValueDependent()) - return std::nullopt; - LValue Val; - if (!EvaluatePointer(Arg, Val, Info)) - return std::nullopt; +std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE, + const CallExpr *E) { + EvalInfo &Info = IEE.Info; + // assert(Info.InConstantContext && "Call to consteval builtin not in constant + // context?"); + assert(E->getBuiltinCallee() == Builtin::BI__builtin_is_within_lifetime); + const Expr *Arg = E->getArg(0); + if (Arg->isValueDependent()) + return std::nullopt; + LValue Val; + if (!EvaluatePointer(Arg, Val, Info)) + return std::nullopt; - auto Error = [&](int Diag) { - const auto *Callee = Info.CurrentCall->getCallee(); - bool CalledFromStd = Callee && Callee->isInStdNamespace() && Callee->getIdentifier() && Callee->getIdentifier()->isStr("is_within_lifetime"); - Info.report(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin() : E->getExprLoc(), diag::err_invalid_is_within_lifetime) - << (CalledFromStd ? "std::is_within_lifetime" : "__builtin_is_within_lifetime") << Diag; - return std::nullopt; - }; - // C++2c [meta.const.eval]p4: - // During the evaluation of an expression E as a core constant expression, a call to this function is ill-formed unless p points to an object that is usable in constant expressions or whose complete object's lifetime began within E. - - // Make sure it points to an object - // nullptr does not point to an object - if (Val.isNullPointer() || Val.getLValueBase().isNull()) - return Error(0); - QualType T = Val.getLValueBase().getType(); - if (T->isFunctionType()) - return Error(1); - assert(T->isObjectType()); - // Hypothetical array element is not an object - if (Val.getLValueDesignator().isOnePastTheEnd()) - return Error(2); - assert(Val.getLValueDesignator().isValidSubobject() && "Unchecked case for valid subobject"); - // All other ill-formed values should have failed EvaluatePointer, so the object should be a pointer to an object - // that is usable in a constant expression or whose complete lifetime began within the expression - CompleteObject CO = findCompleteObject(Info, E, AccessKinds::AK_IsWithinLifetime, Val, T); - if (!CO) - return false; - IsWithinLifetimeHandler handler{ Info }; - return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler); - } + auto Error = [&](int Diag) { + const auto *Callee = Info.CurrentCall->getCallee(); + bool CalledFromStd = Callee && Callee->isInStdNamespace() && + Callee->getIdentifier() && + Callee->getIdentifier()->isStr("is_within_lifetime"); + Info.report(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin() + : E->getExprLoc(), + diag::err_invalid_is_within_lifetime) + << (CalledFromStd ? "std::is_within_lifetime" + : "__builtin_is_within_lifetime") + << Diag; + return std::nullopt; + }; + // C++2c [meta.const.eval]p4: + // During the evaluation of an expression E as a core constant expression, a + // call to this function is ill-formed unless p points to an object that is + // usable in constant expressions or whose complete object's lifetime began + // within E. + + // Make sure it points to an object + // nullptr does not point to an object + if (Val.isNullPointer() || Val.getLValueBase().isNull()) + return Error(0); + QualType T = Val.getLValueBase().getType(); + if (T->isFunctionType()) + return Error(1); + assert(T->isObjectType()); + // Hypothetical array element is not an object + if (Val.getLValueDesignator().isOnePastTheEnd()) + return Error(2); + assert(Val.getLValueDesignator().isValidSubobject() && + "Unchecked case for valid subobject"); + // All other ill-formed values should have failed EvaluatePointer, so the + // object should be a pointer to an object that is usable in a constant + // expression or whose complete lifetime began within the expression + CompleteObject CO = + findCompleteObject(Info, E, AccessKinds::AK_IsWithinLifetime, Val, T); + if (!CO) + return false; + IsWithinLifetimeHandler handler{Info}; + return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler); } +} // namespace diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 1ca1d34c58..868e9d0116 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2226,13 +2226,16 @@ static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall) { TheCall->setArg(0, Arg.get()); TheCall->setType(S.Context.BoolTy); - // A call to this function is always ill-formed if the type is not a pointer to - // an object type. There is no Mandates: to that effect, so we can only + // A call to this function is always ill-formed if the type is not a pointer + // to an object type. There is no Mandates: to that effect, so we can only // issue an error if it is actually evaluated as part of a constant evaluation - // (e.g., `false ? true : std::is_within_lifetime(static_cast<void(*)()>(nullptr));` is fine) - // However, `std::is_within_lifetime` will only take pointer types (allow non-const qualified too) + // (e.g., `false ? true : + // std::is_within_lifetime(static_cast<void(*)()>(nullptr));` is fine) + // However, `std::is_within_lifetime` will only take pointer types (allow + // non-const qualified too) if (!ParamTy->isPointerType()) { - S.Diag(TheCall->getArg(0)->getExprLoc(), diag::err_builtin_is_within_lifetime_invalid_arg); + S.Diag(TheCall->getArg(0)->getExprLoc(), + diag::err_builtin_is_within_lifetime_invalid_arg); return ExprError(); } `````````` </details> https://github.com/llvm/llvm-project/pull/91895 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits