Skip to content

Commit d11e8b4

Browse files
melveraokblast
authored andcommitted
[Clang][Sema] Add __builtin_infer_alloc_token() declaration and semantic checks (llvm#163638)
Introduce the `__builtin_infer_alloc_token()` builtin declaration and adds the necessary semantic checks in Sema.
1 parent 35ad6d9 commit d11e8b4

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4727,6 +4727,13 @@ def PtrauthStringDiscriminator : Builtin {
47274727
let Prototype = "size_t(char const*)";
47284728
}
47294729

4730+
// AllocToken builtins.
4731+
def InferAllocToken : Builtin {
4732+
let Spellings = ["__builtin_infer_alloc_token"];
4733+
let Attributes = [NoThrow, Const, Pure, CustomTypeChecking, Constexpr, UnevaluatedArguments];
4734+
let Prototype = "size_t(...)";
4735+
}
4736+
47304737
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
47314738
// We need the generic prototype, since the packet type could be anything.
47324739
def ReadPipe : OCLPipeLangBuiltin {

clang/lib/Sema/SemaChecking.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,24 @@ static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall) {
14981498
TheCall->setType(S.Context.getPointerType(RT));
14991499
}
15001500

1501+
static bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall) {
1502+
if (S.checkArgCountAtLeast(TheCall, 1))
1503+
return true;
1504+
1505+
for (Expr *Arg : TheCall->arguments()) {
1506+
// If argument is dependent on a template parameter, we can't resolve now.
1507+
if (Arg->isTypeDependent() || Arg->isValueDependent())
1508+
continue;
1509+
// Reject void types.
1510+
QualType ArgTy = Arg->IgnoreParenImpCasts()->getType();
1511+
if (ArgTy->isVoidType())
1512+
return S.Diag(Arg->getBeginLoc(), diag::err_param_with_void_type);
1513+
}
1514+
1515+
TheCall->setType(S.Context.UnsignedLongLongTy);
1516+
return false;
1517+
}
1518+
15011519
namespace {
15021520
enum PointerAuthOpKind {
15031521
PAO_Strip,
@@ -2779,6 +2797,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
27792797
builtinAllocaAddrSpace(*this, TheCall);
27802798
}
27812799
break;
2800+
case Builtin::BI__builtin_infer_alloc_token:
2801+
if (checkBuiltinInferAllocToken(*this, TheCall))
2802+
return ExprError();
2803+
break;
27822804
case Builtin::BI__arithmetic_fence:
27832805
if (BuiltinArithmeticFence(TheCall))
27842806
return ExprError();

clang/test/SemaCXX/alloc-token.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s
2+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter
3+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s -falloc-token-mode=typehash -DMODE_TYPEHASH
4+
5+
#if !__has_builtin(__builtin_infer_alloc_token)
6+
#error "missing __builtin_infer_alloc_token"
7+
#endif
8+
9+
template <typename T = void>
10+
void template_test() {
11+
__builtin_infer_alloc_token(T()); // no error if not instantiated
12+
}
13+
14+
template <typename T>
15+
void negative_template_test() {
16+
__builtin_infer_alloc_token(T()); // expected-error {{argument may not have 'void' type}}
17+
}
18+
19+
void negative_tests() {
20+
__builtin_infer_alloc_token(); // expected-error {{too few arguments to function call}}
21+
__builtin_infer_alloc_token((void)0); // expected-error {{argument may not have 'void' type}}
22+
negative_template_test<void>(); // expected-note {{in instantiation of function template specialization 'negative_template_test<void>' requested here}}
23+
}

0 commit comments

Comments
 (0)