Skip to content

Commit 20ed93b

Browse files
committed
Extend test for infinite recursion bug in find_non_copyable_vars (#71)
These tests are still disabled as they are is still failing, but they now clearly show the problem.
1 parent 6929f36 commit 20ed93b

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

unittests/data/test_stream.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,40 @@
55

66
#include <sstream>
77

8+
// Demonstration of the real problem with basic c++
9+
namespace Test1 {
10+
11+
// Forward declaration
12+
class Base2;
13+
14+
// Base 1, with pointer to Base2
15+
class Base1 {
16+
private:
17+
Base1();
18+
19+
protected:
20+
Base2* aBasePtr2;
21+
};
22+
23+
// Base 2, child class of Base1
24+
class Base2: public Base1 {
25+
private:
26+
Base2();
27+
};
28+
29+
// Child class of Base2
30+
// Holds a pointer to Base2
31+
class Child: public Base2 {
32+
private:
33+
Child();
34+
35+
protected:
36+
Base2* aBasePtr2;
37+
};
38+
39+
}
40+
41+
// Real-life test with std::istream where this happened
842
namespace Test2 {
943

1044
class FileStreamDataStream {

unittests/test_stream.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,52 @@ def __init__(self, *args):
1717
self.header = "test_stream.hpp"
1818
self.config.cflags = "-std=c++11"
1919

20-
def test_stream_non_copyable(self):
20+
def test_infinite_recursion_base_classes(self):
2121
"""
2222
Test find_noncopyable_vars
2323
2424
See #71
2525
26-
find_noncopyable_vars is throwing:
26+
find_noncopyable_vars was throwing:
2727
RuntimeError: maximum recursion depth exceeded while
2828
calling a Python object
2929
"""
3030
decls = parser.parse([self.header], self.config)
3131
global_ns = declarations.get_global_namespace(decls)
3232

33+
# Description of the problem (before the fix):
34+
# find_noncopyable_vars (on Child class) looks up the variables,
35+
# and finds aBasePtr2 (a pointer to the Base2 class).
36+
# Then it looks recursively at the base classes of Base2, and finds
37+
# Base1. Then, it looks up the variables from Base, to check if Base1
38+
# is non copyable. It finds another aBasePtr2 variable, which leads to
39+
# a new check of Base2; this recurses infinitely.
40+
test_ns = global_ns.namespace('Test1')
41+
cls = test_ns.class_('Child')
42+
declarations.type_traits_classes.find_noncopyable_vars(cls)
43+
44+
def test_infinite_recursion_sstream(self):
45+
"""
46+
Test find_noncopyable_vars
47+
48+
See #71
49+
50+
find_noncopyable_vars was throwing:
51+
RuntimeError: maximum recursion depth exceeded while
52+
calling a Python object
53+
"""
54+
decls = parser.parse([self.header], self.config)
55+
global_ns = declarations.get_global_namespace(decls)
56+
57+
# Real life example of the bug. This leads to a similar error,
58+
# but the situation is more complex as there are multiple
59+
# classes that are related the one to the others
60+
# (basic_istream, basic_ios, ios_base, ...)
3361
test_ns = global_ns.namespace('Test2')
3462
cls = test_ns.class_('FileStreamDataStream')
3563
declarations.type_traits_classes.find_noncopyable_vars(cls)
3664

65+
3766
def create_suite():
3867
suite = unittest.TestSuite()
3968
suite.addTest(unittest.makeSuite(Test))

0 commit comments

Comments
 (0)