https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125733
Bug ID: 125733
Summary: contracts: ICE on deducing this and precondition
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: ivan.lazaric.gcc at gmail dot com
Target Milestone: ---
```cpp
struct foo_t {
bool check() const { return true; }
auto get(this auto&& self) pre(self.check()) { return 123; }
};
int main() {
foo_t foo;
foo.get();
}
```
Compiler flags: "-std=c++26 -fcontracts"
ICE:
```
ice.cpp: In instantiation of 'auto foo_t::get(this auto:1&&) [with auto:1 =
foo_t&]':
ice.cpp:8:10: required from here
8 | foo.get();
| ~~~~~~~^~
ice.cpp:3:62: internal compiler error: in check_noexcept_r, at
cp/except.cc:1095
3 | auto get(this auto&& self) pre(self.check()) { return 123; }
| ^
0x261ef02 internal_error(char const*, ...)
/home/ilazaric/repos/ALL/submodules/gcc/gcc/diagnostic-global-context.cc:787
0x7ba504 fancy_abort(char const*, int, char const*)
/home/ilazaric/repos/ALL/submodules/gcc/gcc/diagnostics/context.cc:1823
0x76a035 check_noexcept_r
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/except.cc:1095
0x15d746c walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
/home/ilazaric/repos/ALL/submodules/gcc/gcc/tree.cc:11742
0x15d9a70 walk_tree_without_duplicates_1(tree_node**, tree_node*
(*)(tree_node**, int*, void*), void*, tree_node* (*)(tree_node**, int*,
tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, false,
default_hash_traits<tree_node*> >*))
/home/ilazaric/repos/ALL/submodules/gcc/gcc/tree.cc:12005
0x8c2823 expr_noexcept_p(tree_node*, int)
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/except.cc:1200
0x865c50 build_contract_check(tree_node*)
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/contracts.cc:2955
0x850485 cp_genericize_r
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/cp-gimplify.cc:2183
0x15d746c walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
/home/ilazaric/repos/ALL/submodules/gcc/gcc/tree.cc:11742
0xb1e119 c_genericize_control_stmt(tree_node**, int*, void*, tree_node*
(*)(tree_node**, int*, void*), tree_node* (*)(tree_node**, int*, tree_node*
(*)(tree_node**, int*, void*), void*, hash_set<tree_node*, false,
default_hash_traits<tree_node*> >*))
/home/ilazaric/repos/ALL/submodules/gcc/gcc/c-family/c-gimplify.cc:731
0x850c6c cp_genericize_r
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/cp-gimplify.cc:2563
0x15d746c walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
/home/ilazaric/repos/ALL/submodules/gcc/gcc/tree.cc:11742
0x84d5d2 cp_genericize_tree
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/cp-gimplify.cc:2615
0x84e2bd cp_genericize(tree_node*)
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/cp-gimplify.cc:2757
0x89b9c8 finish_function(bool)
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/decl.cc:20819
0xa2ab66 instantiate_body
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/pt.cc:28721
0xa2b7b5 instantiate_decl(tree_node*, bool, bool)
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/pt.cc:28996
0x8ac728 maybe_instantiate_decl(tree_node*)
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/decl2.cc:6437
0x8ac728 maybe_instantiate_decl(tree_node*)
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/decl2.cc:6425
0x8ac728 mark_used(tree_node*, int)
/home/ilazaric/repos/ALL/submodules/gcc/gcc/cp/decl2.cc:6793
/opt/GCC/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/cc1plus -quiet -imultiarch
x86_64-linux-gnu -D_GNU_SOURCE ice.cpp -quiet -dumpbase ice.cpp -dumpbase-ext
.cpp -mtune=generic -march=x86-64 -std=c++26 -fcontracts -o /tmp/ccgJ86Dy.s
```
Godbolt: https://godbolt.org/z/15a391c9G
Changing the member function into regular implicit object form doesn't ICE:
```cpp
auto get() pre(check()) { return 123; }
```
https://godbolt.org/z/Mdndev17n
^ but that comparison is pretty weak bc it no longer is a template,
making it a template ICEs (segmentation fault):
```cpp
auto get(auto...) pre(check()) { return 123; }
```
https://godbolt.org/z/jez3Tods1
Also ICEs if return type is `int` instead of `auto`
https://godbolt.org/z/fMxoGsoKM
Changing the return type from `auto` to `int` in the original
explicit object form doesn't ICE:
```cpp
int get(this auto&& self) pre(self.check()) { return 123; }
```
https://godbolt.org/z/1o5fKPbY3