brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 40c2273 Raw
149 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++2310// UNSUPPORTED: gcc-15, apple-clang-1711 12// <type_traits>13 14// template <class T>15//   consteval bool is_within_lifetime(const T*) noexcept; // C++2616 17#include <cassert>18#include <type_traits>19#include <utility>20 21#include "test_macros.h"22 23ASSERT_SAME_TYPE(decltype(std::is_within_lifetime(std::declval<int*>())), bool);24ASSERT_SAME_TYPE(decltype(std::is_within_lifetime(std::declval<const int*>())), bool);25ASSERT_SAME_TYPE(decltype(std::is_within_lifetime(std::declval<void*>())), bool);26ASSERT_SAME_TYPE(decltype(std::is_within_lifetime(std::declval<const void*>())), bool);27 28ASSERT_NOEXCEPT(std::is_within_lifetime(std::declval<int*>()));29ASSERT_NOEXCEPT(std::is_within_lifetime(std::declval<const int*>()));30ASSERT_NOEXCEPT(std::is_within_lifetime(std::declval<void*>()));31ASSERT_NOEXCEPT(std::is_within_lifetime(std::declval<const void*>()));32 33template <class T>34concept is_within_lifetime_exists = requires(T t) { std::is_within_lifetime(t); };35 36struct S {};37 38static_assert(is_within_lifetime_exists<int*>);39static_assert(is_within_lifetime_exists<const int*>);40static_assert(is_within_lifetime_exists<void*>);41static_assert(is_within_lifetime_exists<const void*>);42static_assert(!is_within_lifetime_exists<int>);               // Not a pointer43static_assert(!is_within_lifetime_exists<decltype(nullptr)>); // Not a pointer44static_assert(!is_within_lifetime_exists<void() const>);      // Not a pointer45static_assert(!is_within_lifetime_exists<int S::*>);          // Doesn't accept pointer-to-data-member46static_assert(!is_within_lifetime_exists<void (S::*)()>);     // Doesn't accept pointer-to-member-function47static_assert(!is_within_lifetime_exists<void (*)()>);        // Doesn't match `const T*`48 49consteval bool f() {50  // Test that it works with global variables whose lifetime is in a51  // different constant expression52  {53    static constexpr int i = 0;54    static_assert(std::is_within_lifetime(&i));55    // (Even when cast to a different type)56    static_assert(std::is_within_lifetime(const_cast<int*>(&i)));57    static_assert(std::is_within_lifetime(static_cast<const void*>(&i)));58    static_assert(std::is_within_lifetime(static_cast<void*>(const_cast<int*>(&i))));59    static_assert(std::is_within_lifetime<const int>(&i));60    static_assert(std::is_within_lifetime<int>(const_cast<int*>(&i)));61    static_assert(std::is_within_lifetime<const void>(static_cast<const void*>(&i)));62    static_assert(std::is_within_lifetime<void>(static_cast<void*>(const_cast<int*>(&i))));63  }64 65  {66    static constexpr union {67      int member1;68      int member2;69    } u{.member2 = 1};70    static_assert(!std::is_within_lifetime(&u.member1) && std::is_within_lifetime(&u.member2));71  }72 73  // Test that it works for varibles inside the same constant expression74  {75    int i = 0;76    assert(std::is_within_lifetime(&i));77    // (Even when cast to a different type)78    assert(std::is_within_lifetime(const_cast<int*>(&i)));79    assert(std::is_within_lifetime(static_cast<const void*>(&i)));80    assert(std::is_within_lifetime(static_cast<void*>(const_cast<int*>(&i))));81    assert(std::is_within_lifetime<const int>(&i));82    assert(std::is_within_lifetime<int>(const_cast<int*>(&i)));83    assert(std::is_within_lifetime<const void>(static_cast<const void*>(&i)));84    assert(std::is_within_lifetime<void>(static_cast<void*>(const_cast<int*>(&i))));85  }86  // Anonymous union87  {88    union {89      int member1;90      int member2;91    };92    assert(!std::is_within_lifetime(&member1) && !std::is_within_lifetime(&member2));93    member1 = 1;94    assert(std::is_within_lifetime(&member1) && !std::is_within_lifetime(&member2));95    member2 = 1;96    assert(!std::is_within_lifetime(&member1) && std::is_within_lifetime(&member2));97  }98  // Variant members99  {100    struct X {101      union {102        int member1;103        int member2;104      };105    } x;106    assert(!std::is_within_lifetime(&x.member1) && !std::is_within_lifetime(&x.member2));107    x.member1 = 1;108    assert(std::is_within_lifetime(&x.member1) && !std::is_within_lifetime(&x.member2));109    x.member2 = 1;110    assert(!std::is_within_lifetime(&x.member1) && std::is_within_lifetime(&x.member2));111  }112  // Unions113  {114    union X {115      int member1;116      int member2;117    } x;118    assert(!std::is_within_lifetime(&x.member1) && !std::is_within_lifetime(&x.member2));119    x.member1 = 1;120    assert(std::is_within_lifetime(&x.member1) && !std::is_within_lifetime(&x.member2));121    x.member2 = 1;122    assert(!std::is_within_lifetime(&x.member1) && std::is_within_lifetime(&x.member2));123  }124  {125    S s; // uninitialised126    assert(std::is_within_lifetime(&s));127  }128 129  return true;130}131static_assert(f());132 133// Check that it is a consteval (and consteval-propagating) function134// (i.e., taking the address of below will fail because it will be an immediate function)135template <typename T>136constexpr void does_escalate(T p) {137  std::is_within_lifetime(p);138}139template <typename T, void (*)(T) = &does_escalate<T>>140constexpr bool check_escalated(int) {141  return false;142}143template <typename T>144constexpr bool check_escalated(long) {145  return true;146}147static_assert(check_escalated<int*>(0), "");148static_assert(check_escalated<void*>(0), "");149