diff --git a/tests/integration_tests/src/exceptions_call_chain.cpp b/tests/integration_tests/src/exceptions_call_chain.cpp new file mode 100644 index 000000000..5deef795d --- /dev/null +++ b/tests/integration_tests/src/exceptions_call_chain.cpp @@ -0,0 +1,116 @@ +/* TAGS: min cpp exceptions */ +/* CC_OPTS: -std=c++14 */ +/* LIFT_OPTS: explicit +--explicit_args +--explicit_args_count 8 */ +/* LIFT_OPTS: default */ +/* + * Copyright (c) 2020 Trail of Bits, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +struct CustomException { + char inner_state[128] = "abcdefgh\0"; + + CustomException(char c) { + inner_state[0] = c; + } + + const char *what() { + puts("My inner state is:"); + puts(inner_state); + return inner_state; + } + + char state() const { + return inner_state[0]; + } +}; + +struct ThrowOnFirstCreation { + static int counter; + + ThrowOnFirstCreation() { + if (!counter) { + ++counter; + throw std::runtime_error("Counter was zero!"); + } + } +}; + +int ThrowOnFirstCreation::counter = 0; + +struct Empty {}; + +void ThrowRuntime() { + puts("Throwing runtime_error"); + throw std::runtime_error("runtime_error"); +} + +void ThrowOutOfRange() { + puts("Throwing out_of_range"); + throw std::out_of_range("out_of_range"); +} + +void ThrowInt(int a) { + puts("Throwing int"); + throw a; +} + +void ThrowCustom(char c) { + puts("Throwing custom"); + throw CustomException(c); +} + +void do_some_throwing(int val) { + int decider = val % 4; + switch (decider) { + case 0: ThrowRuntime(); + case 1: ThrowOutOfRange(); + case 2: ThrowInt(val); + case 3: ThrowCustom(val); + } +} + + +void MoreComplexExceptions_impl(int iter, int &val) { + puts("MoreComplexExceptions_impl\n"); + int arr[10] = { 0, iter - 2, 2, 3, iter + 3, 5, 6, 7, iter, 9 }; + for (int i = 0; i < iter; ++i) { + val += arr[i]; + } + try { + do_some_throwing(val); + } catch (...) { + puts("Caught something"); + printf("val is %i\n", val); + } + if (iter) { + MoreComplexExceptions_impl(iter - 1, val); + } +} + +void MoreComplexExceptions() { + int original_val_location = 0; + MoreComplexExceptions_impl(10, original_val_location); +} + +int main(int argc, char *argv[]) { + puts("More complex call chain\n"); + MoreComplexExceptions(); + puts("End of test"); + +} diff --git a/tests/integration_tests/src/exceptions_generated_seq.cpp b/tests/integration_tests/src/exceptions_generated_seq.cpp new file mode 100644 index 000000000..3094cd833 --- /dev/null +++ b/tests/integration_tests/src/exceptions_generated_seq.cpp @@ -0,0 +1,163 @@ +/* TAGS: min cpp exceptions */ +/* CC_OPTS: -std=c++14 */ +/* LIFT_OPTS: explicit +--explicit_args +--explicit_args_count 8 */ +/* LIFT_OPTS: default */ +/* + * Copyright (c) 2020 Trail of Bits, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include + +struct CustomException { + char inner_state[128] = "abcdefgh\0"; + + CustomException(char c) { + inner_state[0] = c; + } + + const char *what() { + puts("My inner state is:"); + puts(inner_state); + return inner_state; + } + + char state() const { + return inner_state[0]; + } +}; + +struct Empty {}; + +void ThrowRuntime() { + puts("Throwing runtime_error"); + throw std::runtime_error("runtime_error"); +} + +void ThrowOutOfRange() { + puts("Throwing out_of_range"); + throw std::out_of_range("out_of_range"); +} + +void ThrowInt(int a) { + puts("Throwing int"); + throw a; +} + +void ThrowCustom(char c) { + puts("Throwing custom"); + throw CustomException(c); +} + +void do_some_throwing(int val) { + int decider = val % 4; + switch (decider) { + case 0: ThrowRuntime(); + case 1: ThrowOutOfRange(); + case 2: ThrowInt(val); + case 3: ThrowCustom(val); + } +} + +void do_some_special_throwing(int val) { + if (val == 42) { + puts("Random float is thrown"); + throw 4.22f; + } + do_some_throwing(val); +} + + +#define Ook_def(type) void Ook(const type &err) { \ + puts("Ook " #type); \ +} + +#define Continue_def(type) void continue_print(const type &err) { \ + puts("Continue handler for " #type); \ +} + +#define Continue_branch(head, type) \ + if (std::is_same::value) { \ + puts("Continuing catcher of " #type); \ + } + +Ook_def(float) +Ook_def(std::runtime_error) +Ook_def(std::out_of_range) +Ook_def(CustomException) +Ook_def(int) +Ook_def(Empty) +Ook_def(std::exception) + +template +struct TestRunner { + static void run(int val) { + try { + TestRunner::run(val); + } catch (Head err) { + Ook(err); + } + + Continue_branch(Head, float) + else Continue_branch(Head, std::out_of_range) + else Continue_branch(Head, std::runtime_error) + else Continue_branch(Head, int) + else Continue_branch(Head, CustomException) + else Continue_branch(Head, std::exception) + else Continue_branch(Head, Empty) + } +}; + +template +struct TestRunner { + static void run(int val) { + try { + do_some_special_throwing(val); + } catch (T err) { + Ook(err); + } + } +}; + +template +void RunGeneratedSequences() { + for (int i = 40; i < 50; ++i) { + TestRunner::run(i); + puts("\n"); + } +} + +void GeneratedSequences() { + puts("*** Next sequence"); + RunGeneratedSequences< + std::out_of_range, std::runtime_error, int, CustomException, float>(); + + puts("*** Next sequence"); + RunGeneratedSequences< + std::out_of_range, std::runtime_error, int, float, CustomException>(); + + puts("*** Next sequence"); + RunGeneratedSequences< + std::runtime_error, std::out_of_range, std::exception, int, float, CustomException>(); +} + +int main(int argc, char *argv[]) { + puts("Generated sequences\n"); + GeneratedSequences(); + puts("End of test"); +} diff --git a/tests/integration_tests/src/exceptions_simple.cpp b/tests/integration_tests/src/exceptions_simple.cpp new file mode 100644 index 000000000..5c7bfa9ec --- /dev/null +++ b/tests/integration_tests/src/exceptions_simple.cpp @@ -0,0 +1,102 @@ +/* TAGS: min cpp exceptions */ +/* CC_OPTS: -std=c++14 */ +/* LIFT_OPTS: explicit +--explicit_args +--explicit_args_count 8 */ +/* LIFT_OPTS: default */ +/* + * Copyright (c) 2020 Trail of Bits, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#define CATCH(type, status) catch(type err) { \ + puts(#type" was caught " status); \ + } + +struct CustomException { + char inner_state[128] = "abcdefgh\0"; + + CustomException(char c) { + inner_state[0] = c; + } + + const char *what() { + puts("My inner state is:"); + puts(inner_state); + return inner_state; + } + + char state() const { + return inner_state[0]; + } +}; + +void ThrowRuntime() { + puts("Throwing runtime_error"); + throw std::runtime_error("runtime_error"); +} + +void ThrowOutOfRange() { + puts("Throwing out_of_range"); + throw std::out_of_range("out_of_range"); +} + +void ThrowInt(int a) { + puts("Throwing int"); + throw a; +} + +void ThrowCustom(char c) { + puts("Throwing custom"); + throw CustomException(c); +} + +void SimpleException() { + try { + ThrowRuntime(); + } CATCH(std::runtime_error, "OK") + + try { + ThrowOutOfRange(); + } CATCH(std::runtime_error, "NOK") + CATCH(std::out_of_range, "OK") + + try { + ThrowInt(42); + } CATCH(std::runtime_error, "NOK") + CATCH(std::out_of_range, "NOK") + catch (int a) { + if (a != 42) { + puts("Incorrect integer was caught!"); + } else { + puts("Correct in was caught!"); + } + } + + try { + ThrowCustom('m'); + } CATCH(std::runtime_error, "NOK") + CATCH(std::out_of_range, "NOK") + CATCH(int, "NOK") + CATCH(CustomException, "OK") +} + +int main(int argc, char *argv[]) { + puts("Simple exceptions being thrown\n"); + SimpleException(); + puts("End of test"); +} diff --git a/tests/integration_tests/src/exceptions_static_var.cpp b/tests/integration_tests/src/exceptions_static_var.cpp new file mode 100644 index 000000000..7f406ff9a --- /dev/null +++ b/tests/integration_tests/src/exceptions_static_var.cpp @@ -0,0 +1,80 @@ +/* TAGS: min cpp exceptions */ +/* CC_OPTS: -std=c++14 */ +/* LIFT_OPTS: explicit +--explicit_args +--explicit_args_count 8 */ +/* LIFT_OPTS: default */ +/* + * Copyright (c) 2020 Trail of Bits, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +struct ThrowOnFirstCreation { + static int counter; + + ThrowOnFirstCreation() { + if (!counter) { + ++counter; + throw std::runtime_error("Counter was zero!"); + } + } +}; + +int ThrowOnFirstCreation::counter = 0; + +void CreateStaticVar(ThrowOnFirstCreation **ptr) { + if (!*ptr) { + *ptr = new ThrowOnFirstCreation(); + return; + } + puts("Trying to create, ptr was not null."); +} + + +void StaticVarTest() { + static ThrowOnFirstCreation* ptr = NULL; + + // This should throw an exception and ptr should remain NULL + try { + CreateStaticVar(&ptr); + } catch(...) { + puts("It did not succeed on first try"); + } + + if (ptr) { + puts("Ptr is not NULL, error!"); + } + + // Allocates and constructs object at *ptr correctly + try { + CreateStaticVar(&ptr); + } catch(...) { + puts("It did not succeed on second try"); + } + + // Checks if it was allocated properly + if (ptr) { + puts("But it did succeed eventually"); + delete ptr; + } else { + puts("Ptr was null!"); + } +} + +int main(int argc, char *argv[]) { + puts("Throw while creating static variable\n"); + StaticVarTest(); + puts("End of test"); +} diff --git a/tests/test_suite_generator/src/linux/exceptions_call_chain/CMakeLists.txt b/tests/test_suite_generator/src/linux/exceptions_call_chain/CMakeLists.txt new file mode 100644 index 000000000..48279dfba --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_call_chain/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (c) 2019 Trail of Bits, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +project(exceptions_call_chain_test) +cmake_minimum_required(VERSION 3.2) + +set(PROJECT_CXXFLAGS -Wall -Werror -std=c++11) + +set(PROJECT_SOURCEFILES + main.cpp +) + +GenerateTest(${PROJECT_NAME} + SOURCES ${PROJECT_SOURCEFILES} + CXXFLAGS ${PROJECT_CXXFLAGS} +) diff --git a/tests/test_suite_generator/src/linux/exceptions_call_chain/exceptions_call_chain.txt b/tests/test_suite_generator/src/linux/exceptions_call_chain/exceptions_call_chain.txt new file mode 100644 index 000000000..869b45d97 --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_call_chain/exceptions_call_chain.txt @@ -0,0 +1 @@ +More complex call chain involving also some arithmetic and recursion. diff --git a/tests/test_suite_generator/src/linux/exceptions_call_chain/main.cpp b/tests/test_suite_generator/src/linux/exceptions_call_chain/main.cpp new file mode 100644 index 000000000..d4b5488e7 --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_call_chain/main.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2019 Trail of Bits, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +struct CustomException { + char inner_state[128] = "abcdefgh\0"; + + CustomException(char c) { + inner_state[0] = c; + } + + const char *what() { + puts("My inner state is:"); + puts(inner_state); + return inner_state; + } + + char state() const { + return inner_state[0]; + } +}; + +struct ThrowOnFirstCreation { + static int counter; + + ThrowOnFirstCreation() { + if (!counter) { + ++counter; + throw std::runtime_error("Counter was zero!"); + } + } +}; + +int ThrowOnFirstCreation::counter = 0; + +struct Empty {}; + +void ThrowRuntime() { + puts("Throwing runtime_error"); + throw std::runtime_error("runtime_error"); +} + +void ThrowOutOfRange() { + puts("Throwing out_of_range"); + throw std::out_of_range("out_of_range"); +} + +void ThrowInt(int a) { + puts("Throwing int"); + throw a; +} + +void ThrowCustom(char c) { + puts("Throwing custom"); + throw CustomException(c); +} + +void do_some_throwing(int val) { + int decider = val % 4; + switch (decider) { + case 0: ThrowRuntime(); + case 1: ThrowOutOfRange(); + case 2: ThrowInt(val); + case 3: ThrowCustom(val); + } +} + + +void MoreComplexExceptions_impl(int iter, int &val) { + puts("MoreComplexExceptions_impl\n"); + int arr[10] = { 0, iter - 2, 2, 3, iter + 3, 5, 6, 7, iter, 9 }; + for (int i = 0; i < iter; ++i) { + val += arr[i]; + } + try { + do_some_throwing(val); + } catch (...) { + puts("Caught something"); + printf("val is %i\n", val); + } + if (iter) { + MoreComplexExceptions_impl(iter - 1, val); + } +} + +void MoreComplexExceptions() { + int original_val_location = 0; + MoreComplexExceptions_impl(10, original_val_location); +} + +int main(int argc, char *argv[]) { + puts("More complex call chain\n"); + MoreComplexExceptions(); + puts("End of test"); + +} diff --git a/tests/test_suite_generator/src/linux/exceptions_generated_seq/CMakeLists.txt b/tests/test_suite_generator/src/linux/exceptions_generated_seq/CMakeLists.txt new file mode 100644 index 000000000..72c35ef2b --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_generated_seq/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (c) 2019 Trail of Bits, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +project(exceptions_generated_seq_test) +cmake_minimum_required(VERSION 3.2) + +set(PROJECT_CXXFLAGS -Wall -Werror -std=c++11) + +set(PROJECT_SOURCEFILES + main.cpp +) + +GenerateTest(${PROJECT_NAME} + SOURCES ${PROJECT_SOURCEFILES} + CXXFLAGS ${PROJECT_CXXFLAGS} +) diff --git a/tests/test_suite_generator/src/linux/exceptions_generated_seq/exceptions_generated_seq.txt b/tests/test_suite_generator/src/linux/exceptions_generated_seq/exceptions_generated_seq.txt new file mode 100644 index 000000000..6dd5e1ca9 --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_generated_seq/exceptions_generated_seq.txt @@ -0,0 +1 @@ +Chains of catch blocks, testing if the types are correctly caught. diff --git a/tests/test_suite_generator/src/linux/exceptions_generated_seq/main.cpp b/tests/test_suite_generator/src/linux/exceptions_generated_seq/main.cpp new file mode 100644 index 000000000..db1b6cff7 --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_generated_seq/main.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2019 Trail of Bits, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include + +struct CustomException { + char inner_state[128] = "abcdefgh\0"; + + CustomException(char c) { + inner_state[0] = c; + } + + const char *what() { + puts("My inner state is:"); + puts(inner_state); + return inner_state; + } + + char state() const { + return inner_state[0]; + } +}; + +struct Empty {}; + +void ThrowRuntime() { + puts("Throwing runtime_error"); + throw std::runtime_error("runtime_error"); +} + +void ThrowOutOfRange() { + puts("Throwing out_of_range"); + throw std::out_of_range("out_of_range"); +} + +void ThrowInt(int a) { + puts("Throwing int"); + throw a; +} + +void ThrowCustom(char c) { + puts("Throwing custom"); + throw CustomException(c); +} + +void do_some_throwing(int val) { + int decider = val % 4; + switch (decider) { + case 0: ThrowRuntime(); + case 1: ThrowOutOfRange(); + case 2: ThrowInt(val); + case 3: ThrowCustom(val); + } +} + +void do_some_special_throwing(int val) { + if (val == 42) { + puts("Random float is thrown"); + throw 4.22f; + } + do_some_throwing(val); +} + + +#define Ook_def(type) void Ook(const type &err) { \ + puts("Ook " #type); \ +} + +#define Continue_def(type) void continue_print(const type &err) { \ + puts("Continue handler for " #type); \ +} + +#define Continue_branch(head, type) \ + if (std::is_same::value) { \ + puts("Continuing catcher of " #type); \ + } + +Ook_def(float) +Ook_def(std::runtime_error) +Ook_def(std::out_of_range) +Ook_def(CustomException) +Ook_def(int) +Ook_def(Empty) +Ook_def(std::exception) + +template +struct TestRunner { + static void run(int val) { + try { + TestRunner::run(val); + } catch (Head err) { + Ook(err); + } + + Continue_branch(Head, float) + else Continue_branch(Head, std::out_of_range) + else Continue_branch(Head, std::runtime_error) + else Continue_branch(Head, int) + else Continue_branch(Head, CustomException) + else Continue_branch(Head, std::exception) + else Continue_branch(Head, Empty) + } +}; + +template +struct TestRunner { + static void run(int val) { + try { + do_some_special_throwing(val); + } catch (T err) { + Ook(err); + } + } +}; + +template +void RunGeneratedSequences() { + for (int i = 40; i < 50; ++i) { + TestRunner::run(i); + puts("\n"); + } +} + +void GeneratedSequences() { + puts("*** Next sequence"); + RunGeneratedSequences< + std::out_of_range, std::runtime_error, int, CustomException, float>(); + + puts("*** Next sequence"); + RunGeneratedSequences< + std::out_of_range, std::runtime_error, int, float, CustomException>(); + + puts("*** Next sequence"); + RunGeneratedSequences< + std::runtime_error, std::out_of_range, std::exception, int, float, CustomException>(); +} + +int main(int argc, char *argv[]) { + puts("Generated sequences\n"); + GeneratedSequences(); + puts("End of test"); +} diff --git a/tests/test_suite_generator/src/linux/exceptions_simple_exception/CMakeLists.txt b/tests/test_suite_generator/src/linux/exceptions_simple_exception/CMakeLists.txt new file mode 100644 index 000000000..38d70b654 --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_simple_exception/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (c) 2019 Trail of Bits, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +project(exceptions_simple_exception_test) +cmake_minimum_required(VERSION 3.2) + +set(PROJECT_CXXFLAGS -Wall -Werror -std=c++11) + +set(PROJECT_SOURCEFILES + main.cpp +) + +GenerateTest(${PROJECT_NAME} + SOURCES ${PROJECT_SOURCEFILES} + CXXFLAGS ${PROJECT_CXXFLAGS} +) diff --git a/tests/test_suite_generator/src/linux/exceptions_simple_exception/exceptions_simple_exception.txt b/tests/test_suite_generator/src/linux/exceptions_simple_exception/exceptions_simple_exception.txt new file mode 100644 index 000000000..e40f670dd --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_simple_exception/exceptions_simple_exception.txt @@ -0,0 +1 @@ +Simple throw and catch test on several types. diff --git a/tests/test_suite_generator/src/linux/exceptions_simple_exception/main.cpp b/tests/test_suite_generator/src/linux/exceptions_simple_exception/main.cpp new file mode 100644 index 000000000..e1d9e2910 --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_simple_exception/main.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2019 Trail of Bits, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#define CATCH(type, status) catch(type err) { \ + puts(#type" was caught " status); \ + } + +struct CustomException { + char inner_state[128] = "abcdefgh\0"; + + CustomException(char c) { + inner_state[0] = c; + } + + const char *what() { + puts("My inner state is:"); + puts(inner_state); + return inner_state; + } + + char state() const { + return inner_state[0]; + } +}; + +void ThrowRuntime() { + puts("Throwing runtime_error"); + throw std::runtime_error("runtime_error"); +} + +void ThrowOutOfRange() { + puts("Throwing out_of_range"); + throw std::out_of_range("out_of_range"); +} + +void ThrowInt(int a) { + puts("Throwing int"); + throw a; +} + +void ThrowCustom(char c) { + puts("Throwing custom"); + throw CustomException(c); +} + +void SimpleException() { + try { + ThrowRuntime(); + } CATCH(std::runtime_error, "OK") + + try { + ThrowOutOfRange(); + } CATCH(std::runtime_error, "NOK") + CATCH(std::out_of_range, "OK") + + try { + ThrowInt(42); + } CATCH(std::runtime_error, "NOK") + CATCH(std::out_of_range, "NOK") + catch (int a) { + if (a != 42) { + puts("Incorrect integer was caught!"); + } else { + puts("Correct in was caught!"); + } + } + + try { + ThrowCustom('m'); + } CATCH(std::runtime_error, "NOK") + CATCH(std::out_of_range, "NOK") + CATCH(int, "NOK") + CATCH(CustomException, "OK") +} + +int main(int argc, char *argv[]) { + puts("Simple exceptions being thrown\n"); + SimpleException(); + puts("End of test"); +} diff --git a/tests/test_suite_generator/src/linux/exceptions_static_var/CMakeLists.txt b/tests/test_suite_generator/src/linux/exceptions_static_var/CMakeLists.txt new file mode 100644 index 000000000..40114b39a --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_static_var/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (c) 2019 Trail of Bits, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +project(exceptions_static_var_test) +cmake_minimum_required(VERSION 3.2) + +set(PROJECT_CXXFLAGS -Wall -Werror) + +set(PROJECT_SOURCEFILES + main.cpp +) + +GenerateTest(${PROJECT_NAME} + SOURCES ${PROJECT_SOURCEFILES} + CXXFLAGS ${PROJECT_CXXFLAGS} +) diff --git a/tests/test_suite_generator/src/linux/exceptions_static_var/exceptions_static_var.txt b/tests/test_suite_generator/src/linux/exceptions_static_var/exceptions_static_var.txt new file mode 100644 index 000000000..18a35a89d --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_static_var/exceptions_static_var.txt @@ -0,0 +1 @@ +Throws on first attempt to create static variable. diff --git a/tests/test_suite_generator/src/linux/exceptions_static_var/main.cpp b/tests/test_suite_generator/src/linux/exceptions_static_var/main.cpp new file mode 100644 index 000000000..d1e611b7b --- /dev/null +++ b/tests/test_suite_generator/src/linux/exceptions_static_var/main.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019 Trail of Bits, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +struct ThrowOnFirstCreation { + static int counter; + + ThrowOnFirstCreation() { + if (!counter) { + ++counter; + throw std::runtime_error("Counter was zero!"); + } + } +}; + +int ThrowOnFirstCreation::counter = 0; + +void CreateStaticVar(ThrowOnFirstCreation **ptr) { + if (!*ptr) { + *ptr = new ThrowOnFirstCreation(); + return; + } + puts("Trying to create, ptr was not null."); +} + + +void StaticVarTest() { + static ThrowOnFirstCreation* ptr = NULL; + + // This should throw an exception and ptr should remain NULL + try { + CreateStaticVar(&ptr); + } catch(...) { + puts("It did not succeed on first try"); + } + + if (ptr) { + puts("Ptr is not NULL, error!"); + } + + // Allocates and constructs object at *ptr correctly + try { + CreateStaticVar(&ptr); + } catch(...) { + puts("It did not succeed on second try"); + } + + // Checks if it was allocated properly + if (ptr) { + puts("But it did succeed eventually"); + delete ptr; + } else { + puts("Ptr was null!"); + } +} + +int main(int argc, char *argv[]) { + puts("Throw while creating static variable\n"); + StaticVarTest(); + puts("End of test"); +}