https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126041

            Bug ID: 126041
           Summary: [contracts] Source-location line table underflow and
                    diagnostic metadata corruption in nested generic
                    lambda contract assertions
           Product: gcc
           Version: 16.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: zuhaitz.zechhub at gmail dot com
  Target Milestone: ---
              Host: x86_64-redhat-linux
            Target: x86_64-redhat-linux
             Build: x86_64-redhat-linux

Created attachment 64900
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64900&action=edit
Preprocessed source.

When a contract_assert evaluates variables captured across multiple nested
generic lambda boundaries (specifically interacting with structured bindings
unpacked from an outer scope), the contract scope-resolution mechanics fail to
resolve implicit reference tracking. 

Crucially, the lookup failure completely corrupts the compiler's internal
diagnostic line-number table mapping, forcing the frontend diagnostics to
output garbage negative line numbers (e.g., Location: [filename]:-18826752)
when compiling or handling errors for the assertion block.

EXACT GCC VERSION:
gcc version 16.1.1 20260515 (Red Hat 16.1.1-2) (GCC)

SYSTEM TYPE / TARGET:
Target: x86_64-redhat-linux

COMPLETE COMMAND LINE TRIGGERING THE BUG:
g++ -std=c++26 -fcontracts -save-temps bug_nested_lambda_overflow.cpp

COMPILER OUTPUT:
bug_contract_concepts_sfinae.cpp: In instantiation of ‘void process_data(T)
[with T = EmptyStruct]’:
bug_contract_concepts_sfinae.cpp:12:17:   required from here
   12 |     process_data(e);
      |     ~~~~~~~~~~~~^~~
bug_contract_concepts_sfinae.cpp:5:46: error: ‘const struct EmptyStruct’ has no
member named ‘nested_value’
    5 |     pre(requires { obj.nested_value; } ? obj.nested_value > 0 : true)
      |                                          ~~~~^~~~~~~~~~~~
zuhaitz@fedora:~/cpp26-contracts/bugs$ g++ -std=c++26 -fcontracts -save-temps
bug_nested_lambda_overflow.cpp
bug_nested_lambda_overflow.cpp: In lambda function:
bug_nested_lambda_overflow.cpp:10:44: error: ‘y’ is not implicitly captured by
a contract assertion [-Wtemplate-body]
   10 |             contract_assert((x * factor) + y + offset > 0);
      |                                            ^
bug_nested_lambda_overflow.cpp:-25147723:35: note: ‘y’ declared here
bug_nested_lambda_overflow.cpp:10:34: error: ‘factor’ is not implicitly
captured by a contract assertion [-Wtemplate-body]
   10 |             contract_assert((x * factor) + y + offset > 0);
      |                                  ^~~~~~
bug_nested_lambda_overflow.cpp:8:34: note: ‘factor’ declared here
    8 |     auto outer_lambda = [&](auto factor) {
      |                             ~~~~~^~~~~~
bug_nested_lambda_overflow.cpp:10:30: error: ‘x’ is not implicitly captured by
a contract assertion [-Wtemplate-body]
   10 |             contract_assert((x * factor) + y + offset > 0);
      |                              ^
bug_nested_lambda_overflow.cpp:-25147723:32: note: ‘x’ declared here

MINIMAL STANDALONE TESTCASE (bug_nested_lambda_overflow.cpp):
#include <contracts>
#include <tuple>

int main() {
    auto data = std::make_tuple(10, -20);
    auto [x, y] = data;

    auto outer_lambda = [&](auto factor) {
        auto inner_lambda = [&](auto offset) {
            contract_assert((x * factor) + y + offset > 0);
        };
        inner_lambda(5);
    };
    outer_lambda(2);
}
  • [Bug c++/126041] New: [contr... zuhaitz.zechhub at gmail dot com via Gcc-bugs

Reply via email to