Skip to content

fix(orm): reject callbacks SqlBinder::operator>> cannot classify - #2606

Open
markm101 wants to merge 1 commit into
drogonframework:masterfrom
markm101:bugfix/2605-sqlbinder-missing-return
Open

markm101 wants to merge 1 commit into
drogonframework:masterfrom
markm101:bugfix/2605-sqlbinder-missing-return

Conversation

@markm101

@markm101 markm101 commented Sep 26, 2026 •

Copy link
Copy Markdown

Fixes #2605.

Problem

SqlBinder::operator>> picks where to store a callback with if constexpr on traits::isExceptCallback / traits::isSqlCallback. A callable that is neither (per FunctionTraits.h, a void() callable such as [] {}, std::function<void()> or void (*)()) falls off the end of a function returning SqlBinder &. That is undefined behaviour, the callback is silently dropped, and the only signal is -Wreturn-type. This is the path cppcheck reported.

Fix

Add a final else branch with a static_assert, so such a callback fails to compile with a clear message:

static assertion failed: The callback must be either an SQL result callback or an exception callback

The assert depends on the template parameter, so it is only evaluated for callbacks that reach that branch; valid callbacks are unaffected. The trailing return *this; keeps every path returning, which is what static analysers check. This follows the existing static_assert checks for wrong callback types in CallbackHolder.

Testing

  • Built drogon, db_test and db_api_test (Apple Clang, macOS); db_test passes against SQLite (124 assertions, 3 test cases).
  • Passing [] {} to operator>>: master compiles with -Wreturn-type; this branch fails with the message above.
  • A standalone copy of FunctionTraits plus the fixed operator compiles cleanly on GCC 9.3–13.2, Clang 11–17 and MSVC for the valid callback kinds, and rejects the void() case on all of them.
  • No in-repo code passes a void() callback to operator>>.
  • clang-format produces no changes.

No unit test is added: the change only affects code that fails to compile, which the gtest suite can't express without extra compile-failure test plumbing.

operator>> dispatches on whether the callback is an exception callback
or an SQL callback. A callable that is neither (a void() callable such
as `[] {}` or std::function<void()>) fell off the end of a function
returning SqlBinder&, which is undefined behaviour, and the callback
was silently dropped. Compilers only emitted -Wreturn-type.

Add a final else branch with a static_assert so such callbacks fail at
compile time with a clear message. Valid callbacks are unaffected.

Fixes drogonframework#2605
@markm101
markm101 force-pushed the bugfix/2605-sqlbinder-missing-return branch from e991de1 to df34091 Compare September 26, 2026 05:22

This branch has not been deployed

No deployments
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.

Code path without return value

1 participant