Skip to content

Data<T>::Part: SFINAE-guard forwarding ctors against self / derived types (MSVC C4717) - #2

Merged
neu-rah merged 3 commits into
mainfrom
fix/msvc-data-part-ctor-recursion
Sep 1, 2026
Merged

Data<T>::Part: SFINAE-guard forwarding ctors against self / derived types (MSVC C4717)#2
neu-rah merged 3 commits into
mainfrom
fix/msvc-data-part-ctor-recursion

Conversation

@neu-rah

@neu-rah neu-rah commented Sep 1, 2026

Copy link
Copy Markdown
Member

Problem

MSVC's overload resolution picks the variadic Part(OO&&...) forwarding
constructor for Fir(const Fir&) instead of the implicit copy ctor, then
recurses one Chain::Part level per using Base::Base and C4717s into
a runtime stack overflow
. GCC and Clang pick the copy ctor and never
hit it — this only shows on the recently-added MSVC CI leg (via
OneHLS test/staticList_test.cpp, which copy-constructs a Fir<> into a
StaticList).

warning C4717: 'oneHLS::Fir<...>::Fir<oneHLS::Fir<...> &>':
  recursive on all control paths, function will cause runtime stack overflow

Fix

SFINAE-guard both Data<T>::Part forwarding ctors so a single argument
that is (a copy/move of) Part — or a type derived from it, e.g. Fir<>
cannot select them; the implicit copy/move ctor wins. The
value-plus-base-args path (Part(v, base_args...)) and default
construction are unaffected.

Verified (local, g++ 13 / clang++ 18)

  • OneData test/test.cpp — g++, clang++, -std=c++17/20/23
  • OneHLS test/test.cpp (ac_fixed + ap_fixed) and test/staticList_test.cpp
    (the case that stack-overflows on MSVC) — pass
  • downstream OneItem / OneOutput / OneMenu test suites — identical pass
    with and without the change
  • OneHLS examples/hls_streaming_buffers (16 tests + demo) — pass

MSVC itself can't be tested locally; CI will confirm. This is the
textbook remedy for a greedy forwarding ctor shadowing the copy ctor.

🤖 Generated with Claude Code

neu-rah and others added 3 commits August 26, 2026 01:26
Same fix as the examples/ sweep -- stop build_unflags from stripping
C++20+, keep C++17 as floor not ceiling. .RnD stays local per project
convention; committing here only so the fix isn't lost to a future
clean checkout, not for push.
…ypes

MSVC's overload resolution picks the variadic Part(OO&&...) forwarding
ctor for Fir(const Fir&) instead of the implicit copy ctor, then recurses
one Chain::Part level per `using Base::Base` and C4717s into a runtime
stack overflow. GCC and Clang pick the copy ctor and never hit it, so
this only shows on the MSVC CI leg (OneHLS test/staticList_test.cpp,
which copy-constructs a Fir<> into a StaticList).

Guard both forwarding ctors so a single argument that is (a copy/move
of) Part -- or a type derived from it -- cannot select them; the
implicit copy/move ctor wins. Value-and-base-args and default
construction are unaffected.

Verified: OneData/OneHLS test suites (g++, clang++, C++17/20/23),
OneHLS staticList_test.cpp, downstream OneItem/OneOutput/OneMenu tests
(identical pass with and without the change).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…late default-arg)

The first attempt used a C++17 fold expression inside the enable_if_t
default-argument; MSVC rejects that with C2059. Replace with a nested
one-arg-specialized trait, no fold. GCC/Clang/C++17/20 unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@neu-rah
neu-rah merged commit ff55ea2 into main Sep 1, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant