1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/base/internal/throw_delegate.h"
16
17 #include <functional>
18 #include <new>
19 #include <stdexcept>
20
21 #include "absl/base/config.h"
22 #include "gtest/gtest.h"
23
24 namespace {
25
26 using absl::base_internal::ThrowStdLogicError;
27 using absl::base_internal::ThrowStdInvalidArgument;
28 using absl::base_internal::ThrowStdDomainError;
29 using absl::base_internal::ThrowStdLengthError;
30 using absl::base_internal::ThrowStdOutOfRange;
31 using absl::base_internal::ThrowStdRuntimeError;
32 using absl::base_internal::ThrowStdRangeError;
33 using absl::base_internal::ThrowStdOverflowError;
34 using absl::base_internal::ThrowStdUnderflowError;
35 using absl::base_internal::ThrowStdBadFunctionCall;
36 using absl::base_internal::ThrowStdBadAlloc;
37
38 constexpr const char* what_arg = "The quick brown fox jumps over the lazy dog";
39
40 template <typename E>
ExpectThrowChar(void (* f)(const char *))41 void ExpectThrowChar(void (*f)(const char*)) {
42 #ifdef ABSL_HAVE_EXCEPTIONS
43 try {
44 f(what_arg);
45 FAIL() << "Didn't throw";
46 } catch (const E& e) {
47 EXPECT_STREQ(e.what(), what_arg);
48 }
49 #else
50 EXPECT_DEATH_IF_SUPPORTED(f(what_arg), what_arg);
51 #endif
52 }
53
54 template <typename E>
ExpectThrowString(void (* f)(const std::string &))55 void ExpectThrowString(void (*f)(const std::string&)) {
56 #ifdef ABSL_HAVE_EXCEPTIONS
57 try {
58 f(what_arg);
59 FAIL() << "Didn't throw";
60 } catch (const E& e) {
61 EXPECT_STREQ(e.what(), what_arg);
62 }
63 #else
64 EXPECT_DEATH_IF_SUPPORTED(f(what_arg), what_arg);
65 #endif
66 }
67
68 template <typename E>
ExpectThrowNoWhat(void (* f)())69 void ExpectThrowNoWhat(void (*f)()) {
70 #ifdef ABSL_HAVE_EXCEPTIONS
71 try {
72 f();
73 FAIL() << "Didn't throw";
74 } catch (const E& e) {
75 }
76 #else
77 EXPECT_DEATH_IF_SUPPORTED(f(), "");
78 #endif
79 }
80
TEST(ThrowDelegate,ThrowStdLogicErrorChar)81 TEST(ThrowDelegate, ThrowStdLogicErrorChar) {
82 ExpectThrowChar<std::logic_error>(ThrowStdLogicError);
83 }
84
TEST(ThrowDelegate,ThrowStdInvalidArgumentChar)85 TEST(ThrowDelegate, ThrowStdInvalidArgumentChar) {
86 ExpectThrowChar<std::invalid_argument>(ThrowStdInvalidArgument);
87 }
88
TEST(ThrowDelegate,ThrowStdDomainErrorChar)89 TEST(ThrowDelegate, ThrowStdDomainErrorChar) {
90 ExpectThrowChar<std::domain_error>(ThrowStdDomainError);
91 }
92
TEST(ThrowDelegate,ThrowStdLengthErrorChar)93 TEST(ThrowDelegate, ThrowStdLengthErrorChar) {
94 ExpectThrowChar<std::length_error>(ThrowStdLengthError);
95 }
96
TEST(ThrowDelegate,ThrowStdOutOfRangeChar)97 TEST(ThrowDelegate, ThrowStdOutOfRangeChar) {
98 ExpectThrowChar<std::out_of_range>(ThrowStdOutOfRange);
99 }
100
TEST(ThrowDelegate,ThrowStdRuntimeErrorChar)101 TEST(ThrowDelegate, ThrowStdRuntimeErrorChar) {
102 ExpectThrowChar<std::runtime_error>(ThrowStdRuntimeError);
103 }
104
TEST(ThrowDelegate,ThrowStdRangeErrorChar)105 TEST(ThrowDelegate, ThrowStdRangeErrorChar) {
106 ExpectThrowChar<std::range_error>(ThrowStdRangeError);
107 }
108
TEST(ThrowDelegate,ThrowStdOverflowErrorChar)109 TEST(ThrowDelegate, ThrowStdOverflowErrorChar) {
110 ExpectThrowChar<std::overflow_error>(ThrowStdOverflowError);
111 }
112
TEST(ThrowDelegate,ThrowStdUnderflowErrorChar)113 TEST(ThrowDelegate, ThrowStdUnderflowErrorChar) {
114 ExpectThrowChar<std::underflow_error>(ThrowStdUnderflowError);
115 }
116
TEST(ThrowDelegate,ThrowStdLogicErrorString)117 TEST(ThrowDelegate, ThrowStdLogicErrorString) {
118 ExpectThrowString<std::logic_error>(ThrowStdLogicError);
119 }
120
TEST(ThrowDelegate,ThrowStdInvalidArgumentString)121 TEST(ThrowDelegate, ThrowStdInvalidArgumentString) {
122 ExpectThrowString<std::invalid_argument>(ThrowStdInvalidArgument);
123 }
124
TEST(ThrowDelegate,ThrowStdDomainErrorString)125 TEST(ThrowDelegate, ThrowStdDomainErrorString) {
126 ExpectThrowString<std::domain_error>(ThrowStdDomainError);
127 }
128
TEST(ThrowDelegate,ThrowStdLengthErrorString)129 TEST(ThrowDelegate, ThrowStdLengthErrorString) {
130 ExpectThrowString<std::length_error>(ThrowStdLengthError);
131 }
132
TEST(ThrowDelegate,ThrowStdOutOfRangeString)133 TEST(ThrowDelegate, ThrowStdOutOfRangeString) {
134 ExpectThrowString<std::out_of_range>(ThrowStdOutOfRange);
135 }
136
TEST(ThrowDelegate,ThrowStdRuntimeErrorString)137 TEST(ThrowDelegate, ThrowStdRuntimeErrorString) {
138 ExpectThrowString<std::runtime_error>(ThrowStdRuntimeError);
139 }
140
TEST(ThrowDelegate,ThrowStdRangeErrorString)141 TEST(ThrowDelegate, ThrowStdRangeErrorString) {
142 ExpectThrowString<std::range_error>(ThrowStdRangeError);
143 }
144
TEST(ThrowDelegate,ThrowStdOverflowErrorString)145 TEST(ThrowDelegate, ThrowStdOverflowErrorString) {
146 ExpectThrowString<std::overflow_error>(ThrowStdOverflowError);
147 }
148
TEST(ThrowDelegate,ThrowStdUnderflowErrorString)149 TEST(ThrowDelegate, ThrowStdUnderflowErrorString) {
150 ExpectThrowString<std::underflow_error>(ThrowStdUnderflowError);
151 }
152
TEST(ThrowDelegate,ThrowStdBadFunctionCallNoWhat)153 TEST(ThrowDelegate, ThrowStdBadFunctionCallNoWhat) {
154 #ifdef ABSL_HAVE_EXCEPTIONS
155 try {
156 ThrowStdBadFunctionCall();
157 FAIL() << "Didn't throw";
158 } catch (const std::bad_function_call&) {
159 }
160 #ifdef _LIBCPP_VERSION
161 catch (const std::exception&) {
162 // https://reviews.llvm.org/D92397 causes issues with the vtable for
163 // std::bad_function_call when using libc++ as a shared library.
164 }
165 #endif
166 #else
167 EXPECT_DEATH_IF_SUPPORTED(ThrowStdBadFunctionCall(), "");
168 #endif
169 }
170
TEST(ThrowDelegate,ThrowStdBadAllocNoWhat)171 TEST(ThrowDelegate, ThrowStdBadAllocNoWhat) {
172 ExpectThrowNoWhat<std::bad_alloc>(ThrowStdBadAlloc);
173 }
174
175 } // namespace
176