| // Part of the Crubit project, under the Apache License v2.0 with LLVM |
| // Exceptions. See /LICENSE for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| // Tests involving recursion. |
| |
| #include "gmock/gmock.h" |
| #include "gtest/gtest.h" |
| #include "lifetime_analysis/test/lifetime_analysis_test.h" |
| |
| namespace clang { |
| namespace tidy { |
| namespace lifetimes { |
| namespace { |
| |
| TEST_F(LifetimeAnalysisTest, InfiniteDirectRecursion) { |
| // TODO(danakj): Infinite recursion is UB, so we would like to avoid that we |
| // call an opaque function that is able to break the recursion (by exiting the |
| // program, theoretically). |
| EXPECT_THAT(GetLifetimes(R"( |
| void opaque(); |
| int* f(int* a) { |
| // TODO(danakj): opaque(); |
| return f(a); |
| } |
| )"), |
| LifetimesAre({{"f", "a -> b"}})); |
| } |
| |
| TEST_F(LifetimeAnalysisTest, FiniteDirectRecursion_1Pointee) { |
| EXPECT_THAT(GetLifetimes(R"( |
| int* f(int n, int* a) { |
| if (n <= 0) return a; |
| return f(n - 1, a); |
| } |
| )"), |
| LifetimesAre({{"f", "(), a -> a"}})); |
| } |
| |
| TEST_F(LifetimeAnalysisTest, FiniteDirectRecursion_2Pointees) { |
| EXPECT_THAT(GetLifetimes(R"( |
| int* f(int n, int* a, int* b) { |
| if (n <= 0) return a; |
| return f(n - 1, b, a); |
| } |
| )"), |
| LifetimesAre({{"f", "(), a, a -> a"}})); |
| } |
| |
| TEST_F(LifetimeAnalysisTest, FiniteDirectRecursion_3Pointees) { |
| EXPECT_THAT(GetLifetimes(R"( |
| int* f(int n, int* a, int* b, int *c) { |
| if (n <= 0) return a; |
| return f(n - 1, b, c, a); |
| } |
| )"), |
| LifetimesAre({{"f", "(), a, a, a -> a"}})); |
| } |
| |
| TEST_F(LifetimeAnalysisTest, MutualFiniteRecursion) { |
| EXPECT_THAT(GetLifetimes(R"( |
| int* g(int n, int* a); |
| int* f(int n, int* a) { |
| if (n == 0) return a; |
| return g(n - 1, a); |
| } |
| int* g(int n, int* a) { |
| if (n == 0) return a; |
| return f(n - 1, a); |
| } |
| )"), |
| LifetimesAre({{"f", "(), a -> a"}, {"g", "(), a -> a"}})); |
| } |
| |
| } // namespace |
| } // namespace lifetimes |
| } // namespace tidy |
| } // namespace clang |