Skip to content

Commit e2b9a8d

Browse files
committed
P3290 - no cassert bit yet
1 parent 52aac6a commit e2b9a8d

13 files changed

+556
-20
lines changed

libstdc++-v3/include/std/contracts

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,48 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
4242

4343
namespace contracts
4444
{
45+
46+
// From P3290
47+
struct __location_info{
48+
std::source_location _M_source_location;
49+
explicit __location_info(std::source_location __location)
50+
: _M_source_location(__location){}
51+
};
52+
53+
[[noreturn]] void handle_enforced_contract_violation(
54+
const char*,
55+
const std::source_location &__location = std::source_location::current());
56+
57+
[[noreturn]] void handle_enforced_contract_violation(
58+
const std::nothrow_t&,
59+
const char*,
60+
const std::source_location &__location = std::source_location::current()) noexcept;
61+
62+
void handle_observed_contract_violation(
63+
const char*,
64+
const std::source_location &__location = std::source_location::current());
65+
66+
void handle_observed_contract_violation(
67+
const std::nothrow_t&,
68+
const char*,
69+
const std::source_location &__location = std::source_location::current()) noexcept;
70+
71+
[[noreturn]] void handle_quick_enforced_contract_violation(
72+
const char*,
73+
const std::source_location &__location = std::source_location::current()) noexcept;
74+
75+
4576
// From P2900R11
4677
enum class assertion_kind {
4778
pre = 1,
4879
post = 2,
49-
assert = 3
80+
assert = 3,
81+
// From P3290
82+
cassert = 4,
83+
manual = 5
5084
/* to be extended with implementation−defined values and by future extensions */
51-
/* Implementation−defined values should have a minimum value of 1000. */
52-
};
85+
/* Implementation−defined values should have a minimum value of 1000. */
86+
};
5387

5488
enum class evaluation_semantic {
5589
ignore = 1,
@@ -65,21 +99,58 @@ namespace contracts
6599

66100
enum class detection_mode {
67101
predicate_false = 1,
68-
evaluation_exception = 2
102+
evaluation_exception = 2,
103+
// From P3290
104+
unspecified = 3
69105
/* to be extended with implementation−defined values and by future extensions
70106
Implementation−defined values should have a minimum value of 1000. */
71107
};
72108

73109
using __vendor_ext = void;
74110

75111
class contract_violation {
76-
int version;
77-
__vendor_ext* _M_ext;
78-
const char* _M_comment;
112+
int version = 0;
113+
__vendor_ext* _M_ext = nullptr;
114+
const char* _M_comment = nullptr;
79115
detection_mode _M_detection_mode;
80116
assertion_kind _M_assertion_kind;
81117
std::source_location _M_source_location;
82118
evaluation_semantic _M_evaluation_semantic;
119+
120+
contract_violation(evaluation_semantic __semantic,
121+
const std::source_location &__location,
122+
const char* __comment):
123+
_M_comment(__comment),
124+
_M_detection_mode(detection_mode::unspecified),
125+
_M_assertion_kind(assertion_kind::manual),
126+
_M_source_location(__location),
127+
_M_evaluation_semantic(__semantic)
128+
{
129+
130+
}
131+
132+
friend void handle_enforced_contract_violation(
133+
const char*,
134+
const std::source_location &);
135+
136+
friend void handle_enforced_contract_violation(
137+
const std::nothrow_t&,
138+
const char*,
139+
const std::source_location &) noexcept;
140+
141+
friend void handle_observed_contract_violation(
142+
const char*,
143+
const std::source_location &);
144+
145+
friend void handle_observed_contract_violation(
146+
const std::nothrow_t&,
147+
const char*,
148+
const std::source_location &) noexcept;
149+
150+
friend void handle_quick_enforced_contract_violation(
151+
const char*,
152+
const std::source_location &) noexcept;
153+
83154
public:
84155
// cannot be copied or moved
85156
contract_violation(const contract_violation&) = delete;
@@ -88,7 +159,7 @@ namespace contracts
88159
contract_violation& operator=(const contract_violation&) = delete;
89160

90161
/* see below */
91-
~ contract_violation();
162+
//~contract_violation();
92163

93164
const char* comment() const noexcept { return _M_comment; }
94165
detection_mode mode() const noexcept { return _M_detection_mode; }
@@ -108,6 +179,7 @@ namespace contracts
108179

109180
void invoke_default_contract_violation_handler(const contract_violation&) noexcept;
110181

182+
111183
} // namespace contracts
112184

113185
_GLIBCXX_END_NAMESPACE_VERSION

libstdc++-v3/src/experimental/contract26.cc

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2424
// <http://www.gnu.org/licenses/>.
2525

26-
#include <contracts>
26+
#include "../../include/std/contracts"
2727
#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE
2828
# include <iostream>
2929
# include <cxxabi.h>
@@ -51,8 +51,14 @@ void __handle_contract_violation(const std::contracts::contract_violation &viola
5151
case std::contracts::assertion_kind::assert:
5252
std::cerr << " assert";
5353
break;
54+
case std::contracts::assertion_kind::cassert:
55+
std::cerr << " cassert";
56+
break;
57+
case std::contracts::assertion_kind::manual:
58+
std::cerr << " manual";
59+
break;
5460
default:
55-
std::cerr << " unknown" << (int) violation.semantic();
61+
std::cerr << " unknown: " << (int) violation.semantic();
5662
}
5763
delimiter = ", ";
5864

@@ -66,7 +72,7 @@ void __handle_contract_violation(const std::contracts::contract_violation &viola
6672
std::cerr << " observe";
6773
break;
6874
default:
69-
std::cerr << " unknown" << (int) violation.semantic();
75+
std::cerr << " unknown: " << (int) violation.semantic();
7076
}
7177
delimiter = ", ";
7278

@@ -79,8 +85,11 @@ void __handle_contract_violation(const std::contracts::contract_violation &viola
7985
case std::contracts::detection_mode::evaluation_exception:
8086
std::cerr << " evaluation_exception";
8187
break;
88+
case std::contracts::detection_mode::unspecified:
89+
std::cerr << " unspecified";
90+
break;
8291
default:
83-
std::cerr << "unknown";
92+
std::cerr << " unknown";
8493
}
8594
delimiter = ", ";
8695

@@ -111,6 +120,12 @@ void __handle_contract_violation(const std::contracts::contract_violation &viola
111120
#endif
112121
}
113122

123+
__attribute__ ((weak)) void
124+
handle_contract_violation (const std::contracts::contract_violation &violation)
125+
{
126+
return __handle_contract_violation(violation);
127+
}
128+
114129
namespace std _GLIBCXX_VISIBILITY(default)
115130
{
116131
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -120,18 +135,58 @@ namespace contracts
120135

121136
void invoke_default_contract_violation_handler(const std::contracts::contract_violation& violation) noexcept
122137
{
123-
return __handle_contract_violation(violation);
138+
__handle_contract_violation(violation);
124139
}
125140

141+
// From P3290
142+
[[noreturn]] void handle_enforced_contract_violation(
143+
const char* __comment,
144+
const std::source_location &__location)
145+
{
146+
contract_violation __violation{evaluation_semantic::enforce, __location, __comment};
147+
handle_contract_violation(__violation);
148+
std::terminate();
126149
}
150+
151+
[[noreturn]] void handle_enforced_contract_violation(
152+
const std::nothrow_t&,
153+
const char* __comment,
154+
const std::source_location &__location) noexcept
155+
{
156+
contract_violation __violation{evaluation_semantic::enforce, __location, __comment};
157+
handle_contract_violation(__violation);
158+
std::terminate();
127159
}
128160

129-
__attribute__ ((weak)) void
130-
handle_contract_violation (const std::contracts::contract_violation &violation)
161+
162+
void handle_observed_contract_violation(
163+
const char* __comment,
164+
const std::source_location &__location)
131165
{
132-
return __handle_contract_violation(violation);
166+
contract_violation __violation{evaluation_semantic::observe, __location, __comment};
167+
handle_contract_violation(__violation);
133168
}
134169

170+
void handle_observed_contract_violation(
171+
const std::nothrow_t&,
172+
const char* __comment,
173+
const std::source_location &__location) noexcept
174+
{
175+
contract_violation __violation{evaluation_semantic::observe, __location, __comment};
176+
handle_contract_violation(__violation);
177+
}
178+
179+
[[noreturn]] void handle_quick_enforced_contract_violation(
180+
const char*,
181+
const std::source_location &) noexcept
182+
{
183+
std::terminate();
184+
}
185+
186+
}
187+
}
188+
189+
135190
#if _GLIBCXX_INLINE_VERSION
136191
// The compiler expects the contract_violation class to be in an unversioned
137192
// namespace, so provide a forwarding function with the expected symbol name.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (C) 2025 Free Software Foundation, Inc.
2+
//
3+
// This file is part of the GNU ISO C++ Library. This library is free
4+
// software; you can redistribute it and/or modify it under the
5+
// terms of the GNU General Public License as published by the
6+
// Free Software Foundation; either version 3, or (at your option)
7+
// any later version.
8+
9+
// This library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License along
15+
// with this library; see the file COPYING3. If not see
16+
// <http://www.gnu.org/licenses/>.
17+
18+
// { dg-options "-g0 -fcontracts -fcontracts-nonattr -fcontract-evaluation-semantic=observe" }
19+
// { dg-do run { target c++2a } }
20+
21+
#include <exception>
22+
#include <cstdlib>
23+
#include <testsuite_hooks.h>
24+
#include <cstring>
25+
#include <iostream>
26+
27+
#include "../../../include/std/contracts"
28+
29+
void my_term()
30+
{
31+
std::exit(0);
32+
}
33+
34+
35+
int main()
36+
{
37+
std::set_terminate (my_term);
38+
39+
std::contracts::handle_quick_enforced_contract_violation("test comment");
40+
// We should not get here
41+
return 1;
42+
}
43+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (C) 2025 Free Software Foundation, Inc.
2+
//
3+
// This file is part of the GNU ISO C++ Library. This library is free
4+
// software; you can redistribute it and/or modify it under the
5+
// terms of the GNU General Public License as published by the
6+
// Free Software Foundation; either version 3, or (at your option)
7+
// any later version.
8+
9+
// This library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License along
15+
// with this library; see the file COPYING3. If not see
16+
// <http://www.gnu.org/licenses/>.
17+
18+
// { dg-options "-g0 -fcontracts -fcontracts-nonattr -fcontract-evaluation-semantic=observe" }
19+
// { dg-do run { target c++2a } }
20+
21+
#include <exception>
22+
#include <cstdlib>
23+
#include <testsuite_hooks.h>
24+
25+
#include "../../../include/std/contracts"
26+
27+
28+
struct MyException{};
29+
30+
void handle_contract_violation(const std::contracts::contract_violation& v)
31+
{
32+
invoke_default_contract_violation_handler(v);
33+
throw MyException{};
34+
}
35+
36+
37+
int main()
38+
{
39+
bool exception_thrown = false;
40+
try {
41+
std::contracts::handle_enforced_contract_violation("test comment");
42+
}
43+
catch(MyException)
44+
{
45+
exception_thrown = true;
46+
}
47+
VERIFY( exception_thrown == true);
48+
}
49+
// { dg-output "contract violation in function int main.* at .*:41: test comment.*" }
50+
// { dg-output "assertion_kind: manual, semantic: enforce, mode: unspecified, terminating: yes" }

0 commit comments

Comments
 (0)