aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorcor3ntin <corentinjabot@gmail.com>2025-03-17 20:10:46 +0100
committerGitHub <noreply@github.com>2025-03-17 20:10:46 +0100
commit911b200ce339ace2d55cd2827bb10ed6a494faae (patch)
tree7e6360734a4fcef3407b8fb8e3047288a270e690 /clang/lib/AST/ExprConstant.cpp
parent2443fe537f8bf7620c26586034b12a977d14e366 (diff)
downloadllvm-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.cpp51
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 {