diff options
author | cor3ntin <corentinjabot@gmail.com> | 2025-03-17 20:10:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-17 20:10:46 +0100 |
commit | 911b200ce339ace2d55cd2827bb10ed6a494faae (patch) | |
tree | 7e6360734a4fcef3407b8fb8e3047288a270e690 /clang/lib/AST/ExprConstant.cpp | |
parent | 2443fe537f8bf7620c26586034b12a977d14e366 (diff) | |
download | llvm-911b200ce339ace2d55cd2827bb10ed6a494faae.zip llvm-911b200ce339ace2d55cd2827bb10ed6a494faae.tar.gz llvm-911b200ce339ace2d55cd2827bb10ed6a494faae.tar.bz2 |
[Clang] Constant Expressions inside of GCC' asm strings (#131003)
Implements GCC's constexpr string ASM extension
https://gcc.gnu.org/onlinedocs/gcc/Asm-constexprs.html
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f8e8aad..7803b10 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -17928,10 +17928,12 @@ std::optional<std::string> Expr::tryEvaluateString(ASTContext &Ctx) const { return {}; } -bool Expr::EvaluateCharRangeAsString(std::string &Result, - const Expr *SizeExpression, - const Expr *PtrExpression, ASTContext &Ctx, - EvalResult &Status) const { +template <typename T> +static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, + const Expr *SizeExpression, + const Expr *PtrExpression, + ASTContext &Ctx, + Expr::EvalResult &Status) { LValue String; EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression); Info.InConstantContext = true; @@ -17943,6 +17945,13 @@ bool Expr::EvaluateCharRangeAsString(std::string &Result, uint64_t Size = SizeValue.getZExtValue(); + // FIXME: better protect against invalid or excessive sizes + if constexpr (std::is_same_v<APValue, T>) + Result = APValue(APValue::UninitArray{}, Size, Size); + else { + if (Size < Result.max_size()) + Result.reserve(Size); + } if (!::EvaluatePointer(PtrExpression, String, Info)) return false; @@ -17953,18 +17962,38 @@ bool Expr::EvaluateCharRangeAsString(std::string &Result, Char)) return false; - APSInt C = Char.getInt(); - Result.push_back(static_cast<char>(C.getExtValue())); + if constexpr (std::is_same_v<APValue, T>) { + Result.getArrayInitializedElt(I) = std::move(Char); + } else { + APSInt C = Char.getInt(); + + assert(C.getBitWidth() <= 8 && + "string element not representable in char"); + + Result.push_back(static_cast<char>(C.getExtValue())); + } + if (!HandleLValueArrayAdjustment(Info, PtrExpression, String, CharTy, 1)) return false; } - if (!Scope.destroy()) - return false; - if (!CheckMemoryLeaks(Info)) - return false; + return Scope.destroy() && CheckMemoryLeaks(Info); +} - return true; +bool Expr::EvaluateCharRangeAsString(std::string &Result, + const Expr *SizeExpression, + const Expr *PtrExpression, ASTContext &Ctx, + EvalResult &Status) const { + return EvaluateCharRangeAsStringImpl(this, Result, SizeExpression, + PtrExpression, Ctx, Status); +} + +bool Expr::EvaluateCharRangeAsString(APValue &Result, + const Expr *SizeExpression, + const Expr *PtrExpression, ASTContext &Ctx, + EvalResult &Status) const { + return EvaluateCharRangeAsStringImpl(this, Result, SizeExpression, + PtrExpression, Ctx, Status); } bool Expr::tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const { |