False-positive "function could be declared with attribute 'noreturn'" (cpp:S5271) with assert

cpp:S5271 has a false-positive here because assert() is optimized away in C++ without NDEBUG: assert - cppreference.com

#include <cassert>
void foo() { assert(false); }
int main() { return 0; }

Hey @bers, could you let us know which product/version (if applicable) are you using (SonarQube Server version X, SonarQube Cloud…)? The pre-populated template for this category contains a field for this.

Oh, I thought seeing it reproduce in Compiler Explorer would be enough information. I think we use SonarQube Server 2026.1 LTA.

Hey @bers, I’m not sure which version of the C/C++ analyzer is running on that website, it could be an outdated one. Knowing you’re on 2026.1, I checked if there was any work done on this rule after 2026.1 that would suggest it has been already fixed, and it doesn’t seem like it, so I’ll flag this for the devs.

Hi @bers

Thanks for the report. We intentionally consider standard assert conditions during analysis, even when NDEBUG is defined. We do that because those assertion conditions are meaningful preconditions that help avoid false positives in symbolic execution rules such as out-of-bounds memory access (S3519) and null-pointer dereference (S2259).

You’re right that this is unsuitable for S5271.

While some projects may always enable assertions, in which case suggesting [[noreturn]] would be arguably useful, our analysis (which is based on a single build configuration), cannot determine how users adopt assert in their projects.

Using [[noreturn]] on a function that returns is undefined behavior. Not using [[noreturn]] on a function that does not return is a missed optimization opportunity. We should probably prefer false negatives over false positives here. Thus we should avoid raising S5271 when its conclusion about non-termination depends on assert.

I’ve created an internal ticket to track this problem. Unfortunately, I don’t have an ETA for when it will be tackled.

Best,

Lijun