From 2a0a8ebd746bc8cf9af3b2852c94102828323df3 Mon Sep 17 00:00:00 2001 From: Nerixyz Date: Mon, 7 Apr 2025 20:46:53 +0200 Subject: [PATCH] fix: avoid infinite recursion in `OverloadsFinalizer` --- .../Finalizers/OverloadsFinalizer.cpp | 4 +- .../golden-tests/config/overloads/bases.adoc | 342 +++++++++++++ .../golden-tests/config/overloads/bases.cpp | 19 + .../golden-tests/config/overloads/bases.html | 455 ++++++++++++++++++ .../golden-tests/config/overloads/bases.xml | 78 +++ .../config/overloads/recursion.adoc | 180 +++++++ .../config/overloads/recursion.cpp | 19 + .../config/overloads/recursion.html | 257 ++++++++++ .../config/overloads/recursion.xml | 59 +++ 9 files changed, 1411 insertions(+), 2 deletions(-) create mode 100644 test-files/golden-tests/config/overloads/bases.adoc create mode 100644 test-files/golden-tests/config/overloads/bases.cpp create mode 100644 test-files/golden-tests/config/overloads/bases.html create mode 100644 test-files/golden-tests/config/overloads/bases.xml create mode 100644 test-files/golden-tests/config/overloads/recursion.adoc create mode 100644 test-files/golden-tests/config/overloads/recursion.cpp create mode 100644 test-files/golden-tests/config/overloads/recursion.html create mode 100644 test-files/golden-tests/config/overloads/recursion.xml diff --git a/src/lib/Metadata/Finalizers/OverloadsFinalizer.cpp b/src/lib/Metadata/Finalizers/OverloadsFinalizer.cpp index c9cf05ebd..88bf176e2 100644 --- a/src/lib/Metadata/Finalizers/OverloadsFinalizer.cpp +++ b/src/lib/Metadata/Finalizers/OverloadsFinalizer.cpp @@ -188,7 +188,8 @@ void OverloadsFinalizer:: operator()(RecordInfo& I) { - MRDOCS_CHECK_OR(!finalized_.contains(I.id)); + MRDOCS_CHECK_OR(finalized_.emplace(I.id).second); + for (auto& b: I.Bases) { auto& BT = b.Type; @@ -213,7 +214,6 @@ operator()(RecordInfo& I) foldRecordMembers(I.Interface.Public.Records); foldRecordMembers(I.Interface.Protected.Records); foldRecordMembers(I.Interface.Private.Records); - finalized_.emplace(I.id); } } // clang::mrdocs diff --git a/test-files/golden-tests/config/overloads/bases.adoc b/test-files/golden-tests/config/overloads/bases.adoc new file mode 100644 index 000000000..43f6599fd --- /dev/null +++ b/test-files/golden-tests/config/overloads/bases.adoc @@ -0,0 +1,342 @@ += Reference +:mrdocs: + +[#index] +== Global namespace + +=== Types + +[cols=1] +|=== +| Name +| <> +| <> +| <> +| <> +| <> +|=== + +[#Base1] +== Base1 + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +struct Base1 + : <>; +---- + +=== Base Classes + +[cols=2] +|=== +| Name +| Description +| `<>` +| +|=== + +=== Member Functions + +[cols=2] +|=== +| Name +| Description +| <> +| +|=== + +=== Derived Classes + +[cols=2] +|=== +| Name +| Description +| <> +| +|=== + +[#Base1-foo-0b] +== <>::foo + +=== Synopses + +Declared in `<bases.cpp>` + + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +<>(bool); +---- + +[.small]#<># + + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +<>(int); +---- + +[.small]#<># + +[#BaseBase1-foo] +== <>::foo + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +foo(bool); +---- + +[#Base1-foo-0a] +== <>::foo + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +foo(int); +---- + +[#Base2] +== Base2 + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +struct Base2; +---- + +=== Member Functions + +[cols=1] +|=== +| Name +| <> +|=== + +=== Derived Classes + +[cols=2] +|=== +| Name +| Description +| <> +| +|=== + +[#Base2-foo] +== <>::foo + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +foo(double); +---- + +[#BaseBase1] +== BaseBase1 + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +struct BaseBase1; +---- + +=== Member Functions + +[cols=1] +|=== +| Name +| <> +|=== + +=== Derived Classes + +[cols=2] +|=== +| Name +| Description +| <> +| +|=== + +[#BaseBase1-foo] +== <>::foo + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +foo(bool); +---- + +[#BaseBase2] +== BaseBase2 + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +struct BaseBase2; +---- + +=== Member Functions + +[cols=1] +|=== +| Name +| <> +|=== + +[#BaseBase2-foo] +== <>::foo + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +foo(bool); +---- + +[#User] +== User + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +struct User + : <> + , <>; +---- + +=== Base Classes + +[cols=2] +|=== +| Name +| Description +| `<>` +| +| `<>` +| +|=== + +=== Member Functions + +[cols=2] +|=== +| Name +| Description +| <> +| +|=== + +[#User-foo-0a] +== <>::foo + +=== Synopses + +Declared in `<bases.cpp>` + + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +<>(bool); +---- + +[.small]#<># + + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +<>(int); +---- + +[.small]#<># + + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +<>(double); +---- + +[.small]#<># + +[#BaseBase1-foo] +== <>::foo + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +foo(bool); +---- + +[#User-foo-0e] +== <>::foo + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +foo(int); +---- + +[#Base2-foo] +== <>::foo + +=== Synopsis + +Declared in `<bases.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +foo(double); +---- + + +[.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/config/overloads/bases.cpp b/test-files/golden-tests/config/overloads/bases.cpp new file mode 100644 index 000000000..1bd444a82 --- /dev/null +++ b/test-files/golden-tests/config/overloads/bases.cpp @@ -0,0 +1,19 @@ +struct BaseBase1 { + void foo(bool); +}; + +struct BaseBase2 { + void foo(bool); +}; + +struct Base1 : public BaseBase1 { + void foo(int); +}; + +struct Base2 : private BaseBase2 { + void foo(double); +}; + +struct User : public Base1, Base2 { + void foo(int); +}; diff --git a/test-files/golden-tests/config/overloads/bases.html b/test-files/golden-tests/config/overloads/bases.html new file mode 100644 index 000000000..5026af780 --- /dev/null +++ b/test-files/golden-tests/config/overloads/bases.html @@ -0,0 +1,455 @@ + + +Reference + + +
+

Reference

+
+
+

Global namespace

+
+

Types

+ + + + + + + + + + + + + + +
Name
Base1
Base2
BaseBase1
BaseBase2
User
+ +
+
+
+

Base1

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+struct Base1
+    : BaseBase1;
+
+
+
+
+

Base Classes

+ + + + + + + + + + +
NameDescription
BaseBase1
+
+

Member Functions

+ + + + + + + + + + + +
NameDescription
foo
+ + + +
+

Derived Classes

+ + + + + + + + + + +
NameDescription
User +
+
+
+
+
+

Base1::foo

+
+
+

Synopses

+
+Declared in <bases.cpp>
+ +
+
+void
+foo(bool);
+
+
» more... + + +
+
+void
+foo(int);
+
+
» more... + + +
+
+
+
+

BaseBase1::foo

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+void
+foo(bool);
+
+
+
+
+
+
+

Base1::foo

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+void
+foo(int);
+
+
+
+
+
+
+

Base2

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+struct Base2;
+
+
+
+

Member Functions

+ + + + + + + + + + +
Name
foo
+ + + +
+

Derived Classes

+ + + + + + + + + + +
NameDescription
User +
+
+
+
+
+

Base2::foo

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+void
+foo(double);
+
+
+
+
+
+
+

BaseBase1

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+struct BaseBase1;
+
+
+
+

Member Functions

+ + + + + + + + + + +
Name
foo
+ + + +
+

Derived Classes

+ + + + + + + + + + +
NameDescription
Base1 +
+
+
+
+
+

BaseBase1::foo

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+void
+foo(bool);
+
+
+
+
+
+
+

BaseBase2

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+struct BaseBase2;
+
+
+
+

Member Functions

+ + + + + + + + + + +
Name
foo
+ + + +
+
+
+

BaseBase2::foo

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+void
+foo(bool);
+
+
+
+
+
+
+

User

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+struct User
+    : Base1
+    , Base2;
+
+
+
+
+

Base Classes

+ + + + + + + + + + + +
NameDescription
Base1
Base2
+
+

Member Functions

+ + + + + + + + + + + +
NameDescription
foo
+ + + +
+
+
+

User::foo

+
+
+

Synopses

+
+Declared in <bases.cpp>
+ +
+
+void
+foo(bool);
+
+
» more... + + +
+
+void
+foo(int);
+
+
» more... + + +
+
+void
+foo(double);
+
+
» more... + + +
+
+
+
+

BaseBase1::foo

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+void
+foo(bool);
+
+
+
+
+
+
+

User::foo

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+void
+foo(int);
+
+
+
+
+
+
+

Base2::foo

+
+
+

Synopsis

+
+Declared in <bases.cpp>
+
+
+void
+foo(double);
+
+
+
+
+ +
+
+

Created with MrDocs

+
+ + \ No newline at end of file diff --git a/test-files/golden-tests/config/overloads/bases.xml b/test-files/golden-tests/config/overloads/bases.xml new file mode 100644 index 000000000..bdeaebe45 --- /dev/null +++ b/test-files/golden-tests/config/overloads/bases.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-files/golden-tests/config/overloads/recursion.adoc b/test-files/golden-tests/config/overloads/recursion.adoc new file mode 100644 index 000000000..85fdc87e3 --- /dev/null +++ b/test-files/golden-tests/config/overloads/recursion.adoc @@ -0,0 +1,180 @@ += Reference +:mrdocs: + +[#index] +== Global namespace + +=== Types + +[cols=1] +|=== +| Name +| <> +| <> +| <> +| <> +|=== + +[#Bar-0a] +== Bar + +=== Synopsis + +Declared in `<recursion.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template< + typename T, + typename List> +struct Bar + : <><T, <><List>>; +---- + +=== Base Classes + +[cols=2] +|=== +| Name +| Description +| `<><T, <><List>>` +| +|=== + +=== Member Functions + +[cols=1] +|=== +| Name +| <> +|=== + +=== Derived Classes + +[cols=2] +|=== +| Name +| Description +| <> +| +|=== + +[#Bar-0a-baz] +== <>::baz + +=== Synopsis + +Declared in `<recursion.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +baz(bool); +---- + +[#Bar-01] +== Bar<T, <><Args...>> + +=== Synopsis + +Declared in `<recursion.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template< + typename T, + typename... Args> +struct <><T, <><Args...>>; +---- + +=== Member Functions + +[cols=1] +|=== +| Name +| <> +|=== + +[#Bar-01-baz] +== <><T, <><Args...>>::baz + +=== Synopsis + +Declared in `<recursion.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +baz(Args...); +---- + +[#Foo-02] +== Foo + +=== Synopsis + +Declared in `<recursion.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +struct Foo; +---- + +=== Types + +[cols=1] +|=== +| Name +| <> +|=== + +[#Foo-02-Type] +== <>::Type + +=== Synopsis + +Declared in `<recursion.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +using Type = T; +---- + +[#Foo-0c] +== Foo<T[]> + +=== Synopsis + +Declared in `<recursion.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template< + typename T, + int N> +struct <><T[]>; +---- + +=== Types + +[cols=1] +|=== +| Name +| <> +|=== + +[#Foo-0c-Type] +== <><T[]>::Type + +=== Synopsis + +Declared in `<recursion.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +using Type = <><T>; +---- + + +[.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/config/overloads/recursion.cpp b/test-files/golden-tests/config/overloads/recursion.cpp new file mode 100644 index 000000000..69a54dc11 --- /dev/null +++ b/test-files/golden-tests/config/overloads/recursion.cpp @@ -0,0 +1,19 @@ +template +struct Foo { + using Type = T; +}; + +template +struct Foo { + using Type = Foo; +}; + +template +struct Bar : Bar> { + void baz(bool) {} +}; + +template +struct Bar> { + void baz(Args...) {} +}; diff --git a/test-files/golden-tests/config/overloads/recursion.html b/test-files/golden-tests/config/overloads/recursion.html new file mode 100644 index 000000000..666648793 --- /dev/null +++ b/test-files/golden-tests/config/overloads/recursion.html @@ -0,0 +1,257 @@ + + +Reference + + +
+

Reference

+
+
+

Global namespace

+
+

Types

+ + + + + + + + + + + + + +
Name
Bar
Bar<T, Foo<Args...>>
Foo
Foo<T[]>
+ +
+
+
+

Bar

+
+
+

Synopsis

+
+Declared in <recursion.cpp>
+
+
+template<
+    typename T,
+    typename List>
+struct Bar
+    : Bar<T, Foo<List>>;
+
+
+
+
+

Base Classes

+ + + + + + + + + + +
NameDescription
Bar<T, Foo<List>>
+
+

Member Functions

+ + + + + + + + + + +
Name
baz
+ + + +
+

Derived Classes

+ + + + + + + + + + +
NameDescription
Bar +
+
+
+
+
+

Bar::baz

+
+
+

Synopsis

+
+Declared in <recursion.cpp>
+
+
+void
+baz(bool);
+
+
+
+
+
+
+

Bar<T, Foo<Args...>>

+
+
+

Synopsis

+
+Declared in <recursion.cpp>
+
+
+template<
+    typename T,
+    typename... Args>
+struct Bar<T, Foo<Args...>>;
+
+
+
+

Member Functions

+ + + + + + + + + + +
Name
baz
+ + + +
+
+
+

Bar<T, Foo<Args...>>::baz

+
+
+

Synopsis

+
+Declared in <recursion.cpp>
+
+
+void
+baz(Args...);
+
+
+
+
+
+
+

Foo

+
+
+

Synopsis

+
+Declared in <recursion.cpp>
+
+
+template<typename T>
+struct Foo;
+
+
+
+

Types

+ + + + + + + + + + +
Name
Type
+ + + +
+
+
+

Foo::Type

+
+
+

Synopsis

+
+Declared in <recursion.cpp>
+
+
+using Type = T;
+
+
+
+
+
+
+

Foo<T[]>

+
+
+

Synopsis

+
+Declared in <recursion.cpp>
+
+
+template<
+    typename T,
+    int N>
+struct Foo<T[]>;
+
+
+
+

Types

+ + + + + + + + + + +
Name
Type
+ + + +
+
+
+

Foo<T[]>::Type

+
+
+

Synopsis

+
+Declared in <recursion.cpp>
+
+
+using Type = Foo<T>;
+
+
+
+
+ +
+
+

Created with MrDocs

+
+ + \ No newline at end of file diff --git a/test-files/golden-tests/config/overloads/recursion.xml b/test-files/golden-tests/config/overloads/recursion.xml new file mode 100644 index 000000000..1750d0aa9 --- /dev/null +++ b/test-files/golden-tests/config/overloads/recursion.xml @@ -0,0 +1,59 @@ + + + + + + + + +