https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126040
Bug ID: 126040
Summary: [contracts] Eager template evaluation and
concept/SFINAE bypass in contract attribute predicates
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 64899
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64899&action=edit
Preprocessed source.
When a C++26 contract condition contains a C++20 requires expression inside a
ternary compile-time check intended to guard type safety during template
instantiations, the substitution framework fails to short-circuit. Branches
that should be discarded are eagerly evaluated by the contract template
synthesis engine, throwing hard compilation errors instead of resolving safely
via SFINAE.
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_contract_concepts_sfinae.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)
| ~~~~^~~~~~~~~~~~
MINIMAL STANDALONE TESTCASE (bug_contract_concepts_sfinae.cpp):
#include <contracts>
template<typename T>
void process_data(T obj)
pre(requires { obj.nested_value; } ? obj.nested_value > 0 : true)
{}
struct EmptyStruct {};
int main() {
EmptyStruct e;
process_data(e); // Should compile cleanly by evaluating the ternary path
to 'true'
}