83 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s2// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s -falloc-token-max=03// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter4// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s -falloc-token-mode=typehash -DMODE_TYPEHASH5// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s -falloc-token-max=2 -DTOKEN_MAX=26// RUN: %clang_cc1 -triple arm-linux-androideabi -std=c++23 -fsyntax-only -verify %s -falloc-token-max=2 -DTOKEN_MAX=27// RUN: %clang_cc1 -triple arm-linux-androideabi -std=c++23 -fsyntax-only -verify %s -falloc-token-max=2 -DTOKEN_MAX=2 -fexperimental-new-constant-interpreter8 9#if !__has_builtin(__builtin_infer_alloc_token)10#error "missing __builtin_infer_alloc_token"11#endif12 13struct NoPtr {14 int x;15 long y;16};17 18struct WithPtr {19 int a;20 char *buf;21};22 23// Check specific known values; these are guaranteed to be stable.24#ifdef MODE_TYPEHASH25static_assert(__builtin_infer_alloc_token(sizeof(int)) == 2689373973731826898ULL);26static_assert(__builtin_infer_alloc_token(sizeof(char*)) == 2250492667400517147ULL);27static_assert(__builtin_infer_alloc_token(sizeof(NoPtr)) == 7465259095297095368ULL);28static_assert(__builtin_infer_alloc_token(sizeof(WithPtr)) == 11898882936532569145ULL);29#elif defined(TOKEN_MAX)30# if TOKEN_MAX == 231static_assert(__builtin_infer_alloc_token(sizeof(int)) == 0);32static_assert(__builtin_infer_alloc_token(sizeof(char*)) == 1);33static_assert(__builtin_infer_alloc_token(sizeof(NoPtr)) == 0);34static_assert(__builtin_infer_alloc_token(sizeof(WithPtr)) == 1);35# else36# error "unhandled TOKEN_MAX case"37# endif38#else39static_assert(__builtin_infer_alloc_token(sizeof(int)) == 2689373973731826898ULL);40static_assert(__builtin_infer_alloc_token(sizeof(char*)) == 11473864704255292954ULL);41static_assert(__builtin_infer_alloc_token(sizeof(NoPtr)) == 7465259095297095368ULL);42static_assert(__builtin_infer_alloc_token(sizeof(WithPtr)) == 11898882936532569145ULL);43#endif44 45// Template function.46template <typename T>47constexpr unsigned long get_token() {48 return __builtin_infer_alloc_token(sizeof(T));49}50static_assert(__builtin_infer_alloc_token(sizeof(int)) == get_token<int>());51 52// Test complex expressions.53static_assert(__builtin_constant_p(__builtin_infer_alloc_token(sizeof(int))));54static_assert(__builtin_infer_alloc_token(sizeof(NoPtr) * 2, 1) == get_token<NoPtr>());55static_assert(__builtin_infer_alloc_token(1, 4 + sizeof(NoPtr)) == get_token<NoPtr>());56static_assert(__builtin_infer_alloc_token(sizeof(NoPtr) << 8) == get_token<NoPtr>());57 58// Test usable as a template param.59template <unsigned long ID, typename T>60struct token_for_type {61 static_assert(ID == get_token<T>());62 static constexpr unsigned long value = ID;63};64static_assert(token_for_type<__builtin_infer_alloc_token(sizeof(int)), int>::value == get_token<int>());65 66template <typename T = void>67void template_test() {68 __builtin_infer_alloc_token(T()); // no error if not instantiated69}70 71template <typename T>72void negative_template_test() {73 __builtin_infer_alloc_token(T()); // expected-error {{argument may not have 'void' type}}74}75 76void negative_tests() {77 __builtin_infer_alloc_token(); // expected-error {{too few arguments to function call}}78 __builtin_infer_alloc_token((void)0); // expected-error {{argument may not have 'void' type}}79 negative_template_test<void>(); // expected-note {{in instantiation of function template specialization 'negative_template_test<void>' requested here}}80 constexpr auto inference_fail = __builtin_infer_alloc_token(123); // expected-error {{must be initialized by a constant expression}} \81 // expected-note {{could not infer allocation type for __builtin_infer_alloc_token}}82}83