aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorcor3ntin <corentinjabot@gmail.com>2025-05-06 14:13:32 +0200
committerGitHub <noreply@github.com>2025-05-06 14:13:32 +0200
commit300d4026f77683aae490361d250a51904dd19ed2 (patch)
tree0356047d81febbd3ddce6ada2429b128b29cafbe /clang/lib/Sema/SemaChecking.cpp
parent3b4f9c544274392198de084b84a5f2e5506e4703 (diff)
downloadllvm-300d4026f77683aae490361d250a51904dd19ed2.zip
llvm-300d4026f77683aae490361d250a51904dd19ed2.tar.gz
llvm-300d4026f77683aae490361d250a51904dd19ed2.tar.bz2
[Clang] Implement the core language parts of P2786 - Trivial relocation (#127636)
This adds - The parsing of `trivially_relocatable_if_eligible`, `replaceable_if_eligible` keywords - `__builtin_trivially_relocate`, implemented in terms of memmove. In the future this should - Add the appropriate start/end lifetime markers that llvm does not have (`start_lifetime_as`) - Add support for ptrauth when that's upstreamed - the `__builtin_is_cpp_trivially_relocatable` and `__builtin_is_replaceable` traits Fixes #127609
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 97f623f..7f45533 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -1919,6 +1919,54 @@ static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall) {
<< 0;
return ExprError();
}
+ return TheCall;
+}
+
+static ExprResult BuiltinTriviallyRelocate(Sema &S, CallExpr *TheCall) {
+ if (S.checkArgCount(TheCall, 3))
+ return ExprError();
+
+ QualType Dest = TheCall->getArg(0)->getType();
+ if (!Dest->isPointerType() || Dest.getCVRQualifiers() != 0) {
+ S.Diag(TheCall->getArg(0)->getExprLoc(),
+ diag::err_builtin_trivially_relocate_invalid_arg_type)
+ << /*a pointer*/ 0;
+ return ExprError();
+ }
+
+ QualType T = Dest->getPointeeType();
+ if (S.RequireCompleteType(TheCall->getBeginLoc(), T,
+ diag::err_incomplete_type))
+ return ExprError();
+
+ if (T.isConstQualified() || !S.IsCXXTriviallyRelocatableType(T) ||
+ T->isIncompleteArrayType()) {
+ S.Diag(TheCall->getArg(0)->getExprLoc(),
+ diag::err_builtin_trivially_relocate_invalid_arg_type)
+ << (T.isConstQualified() ? /*non-const*/ 1 : /*relocatable*/ 2);
+ return ExprError();
+ }
+
+ TheCall->setType(Dest);
+
+ QualType Src = TheCall->getArg(1)->getType();
+ if (Src.getCanonicalType() != Dest.getCanonicalType()) {
+ S.Diag(TheCall->getArg(1)->getExprLoc(),
+ diag::err_builtin_trivially_relocate_invalid_arg_type)
+ << /*the same*/ 3;
+ return ExprError();
+ }
+
+ Expr *SizeExpr = TheCall->getArg(2);
+ ExprResult Size = S.DefaultLvalueConversion(SizeExpr);
+ if (Size.isInvalid())
+ return ExprError();
+
+ Size = S.tryConvertExprToType(Size.get(), S.getASTContext().getSizeType());
+ if (Size.isInvalid())
+ return ExprError();
+ SizeExpr = Size.get();
+ TheCall->setArg(2, SizeExpr);
return TheCall;
}
@@ -2384,6 +2432,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
return BuiltinLaunder(*this, TheCall);
case Builtin::BI__builtin_is_within_lifetime:
return BuiltinIsWithinLifetime(*this, TheCall);
+ case Builtin::BI__builtin_trivially_relocate:
+ return BuiltinTriviallyRelocate(*this, TheCall);
+
case Builtin::BI__sync_fetch_and_add:
case Builtin::BI__sync_fetch_and_add_1:
case Builtin::BI__sync_fetch_and_add_2: