1// Copyright 2018 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// This is a "No Compile Test" suite. 6// http://dev.chromium.org/developers/testing/no-compile-tests 7 8#include <type_traits> 9 10#include "base/optional.h" 11 12namespace base { 13 14#if defined(NCTEST_EXPLICIT_CONVERTING_COPY_CONSTRUCTOR) // [r"fatal error: no matching function for call to object of type"] 15 16// Optional<T>(const Optional<U>& arg) constructor is marked explicit if 17// T is not convertible from "const U&". 18void WontCompile() { 19 struct Test { 20 // Declares as explicit so that Test is still constructible from int, 21 // but not convertible. 22 explicit Test(int a) {} 23 }; 24 25 static_assert(!std::is_convertible<const int&, Test>::value, 26 "const int& to Test is convertible"); 27 const Optional<int> arg(in_place, 1); 28 ([](Optional<Test> param) {})(arg); 29} 30 31#elif defined(NCTEST_EXPLICIT_CONVERTING_MOVE_CONSTRUCTOR) // [r"fatal error: no matching function for call to object of type"] 32 33// Optional<T>(Optional<U>&& arg) constructor is marked explicit if 34// T is not convertible from "U&&". 35void WontCompile() { 36 struct Test { 37 // Declares as explicit so that Test is still constructible from int, 38 // but not convertible. 39 explicit Test(int a) {} 40 }; 41 42 static_assert(!std::is_convertible<int&&, Test>::value, 43 "int&& to Test is convertible"); 44 ([](Optional<Test> param) {})(Optional<int>(in_place, 1)); 45} 46 47#elif defined(NCTEST_EXPLICIT_VALUE_FORWARD_CONSTRUCTOR) // [r"fatal error: no matching function for call to object of type"] 48 49// Optional<T>(U&&) constructor is marked explicit if T is not convertible 50// from U&&. 51void WontCompile() { 52 struct Test { 53 // Declares as explicit so that Test is still constructible from int, 54 // but not convertible. 55 explicit Test(int a) {} 56 }; 57 58 static_assert(!std::is_convertible<int&&, Test>::value, 59 "int&& to Test is convertible"); 60 ([](Optional<Test> param) {})(1); 61} 62 63#elif defined(NCTEST_ILL_FORMED_IN_PLACET_T) // [r"instantiation of base::Optional with in_place_t is ill-formed"] 64 65// Optional<T> is ill-formed if T is `in_place_t`. 66void WontCompile() { 67 Optional<base::in_place_t> optional; 68 optional.has_value(); 69} 70 71#elif defined(NCTEST_ILL_FORMED_CONST_IN_PLACET_T) // [r"instantiation of base::Optional with in_place_t is ill-formed"] 72 73// Optional<T> is ill-formed if T is `const in_place_t`. 74void WontCompile() { 75 Optional<const base::in_place_t> optional; 76 optional.has_value(); 77} 78 79#elif defined(NCTEST_ILL_FORMED_NULLOPT_T) // [r"instantiation of base::Optional with nullopt_t is ill-formed"] 80 81// Optional<T> is ill-formed if T is `const nullopt_t`. 82void WontCompile() { 83 Optional<const base::nullopt_t> optional; 84 optional.has_value(); 85} 86 87#elif defined(NCTEST_ILL_FORMED_CONST_NULLOPT_T) // [r"instantiation of base::Optional with nullopt_t is ill-formed"] 88 89// Optional<T> is ill-formed if T is `const nullopt_t`. 90void WontCompile() { 91 Optional<const base::nullopt_t> optional; 92 optional.has_value(); 93} 94 95#elif defined(NCTEST_ILL_FORMED_NON_DESTRUCTIBLE) // [r"instantiation of base::Optional with a non-destructible type is ill-formed"] 96 97// Optional<T> is ill-formed if T is non-destructible. 98void WontCompile() { 99 struct T { 100 private: 101 ~T(); 102 }; 103 104 static_assert(!std::is_destructible<T>::value, "T is not destructible"); 105 106 Optional<T> optional; 107 optional.has_value(); 108} 109 110// TODO(crbug.com/967722): the error message should be about the instantiation of an 111// ill-formed base::Optional. 112#elif defined(NCTEST_ILL_FORMED_REFERENCE) // [r"fatal error: union member 'value_' has reference type 'int &'"] 113 114// Optional<T> is ill-formed if T is a reference. 115void WontCompile() { 116 using T = int&; 117 118 static_assert(std::is_reference<T>::value, "T is a reference"); 119 120 Optional<T> optional; 121 optional.has_value(); 122} 123 124// TODO(crbug.com/967722): the error message should be about the instantiation of an 125// ill-formed base::Optional. 126#elif defined(NCTEST_ILL_FORMED_CONST_REFERENCE) // [r"fatal error: union member 'value_' has reference type 'const int &'"] 127 128// Optional<T> is ill-formed if T is a const reference. 129void WontCompile() { 130 using T = const int&; 131 132 static_assert(std::is_reference<T>::value, "T is a reference"); 133 134 Optional<T> optional; 135 optional.has_value(); 136} 137 138#elif defined(NCTEST_ILL_FORMED_FIXED_LENGTH_ARRAY) // [r"instantiation of base::Optional with an array type is ill-formed"] 139 140// Optional<T> is ill-formed if T is a fixed length array. 141void WontCompile() { 142 using T = char[4]; 143 144 static_assert(std::is_array<T>::value, "T is an array"); 145 146 Optional<T> optional; 147 optional.has_value(); 148} 149 150// TODO(crbug.com/967722): the error message should be about the instantiation of an 151// ill-formed base::Optional. 152#elif defined(NCTEST_ILL_FORMED_UNDEFINED_LENGTH_ARRAY) // [r"fatal error: base class 'OptionalStorageBase' has a flexible array member"] 153 154// Optional<T> is ill-formed if T is a undefined length array. 155void WontCompile() { 156 using T = char[]; 157 158 static_assert(std::is_array<T>::value, "T is an array"); 159 160 Optional<T> optional; 161 optional.has_value(); 162} 163 164#endif 165 166} // namespace base 167