diff options
author | cor3ntin <corentinjabot@gmail.com> | 2025-05-06 14:13:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-06 14:13:32 +0200 |
commit | 300d4026f77683aae490361d250a51904dd19ed2 (patch) | |
tree | 0356047d81febbd3ddce6ada2429b128b29cafbe /clang/lib/Sema/SemaChecking.cpp | |
parent | 3b4f9c544274392198de084b84a5f2e5506e4703 (diff) | |
download | llvm-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.cpp | 51 |
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: |