Skip to content

Commit c119d32

Browse files
committed
Allow additional contract flags, e.g., assert<Bounds, audit, new_code>( ... )
1 parent 2893e64 commit c119d32

14 files changed

+136
-55
lines changed

regression-tests/pure2-contracts.cpp2

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
test_condition_evaluation: (tag) -> bool = { std::cout << tag << "\n"; return true; }
22

3+
audit: bool = true;
4+
35
main: () = {
6+
// A few basic tests
47
assert( 1 != 2, "ack, arithmetic is buggy" );
58
assert<Type>( typeid(int) != typeid(double), "ack, C types are broken" );
69
assert<Unevaluated>( any-grammatical.kind(of, nonsense * here) is "all ignored" );
710

8-
assert( test_condition_evaluation(1), "default" ); // evaluated: prints "1"
9-
assert<Type>( test_condition_evaluation(2), "type" ); // evaluated: prints "2"
11+
// Now test that conditions are only evaluated if there's
12+
// a handler active + any other control flags are enabled
13+
14+
assert( test_condition_evaluation(1), "default" ); // evaluated: prints "1"
15+
16+
// Type has a handler
17+
assert<Type>( test_condition_evaluation(2), "type" ); // evaluated: prints "2"
1018
cpp2::Type.set_handler();
11-
assert<Type>( test_condition_evaluation(3), "type" ); // not evaluated
12-
assert<Unevaluated>( test_condition_evaluation(4) ); // not evaluated
19+
// Type does not have a handler
20+
assert<Type>( test_condition_evaluation(3), "type" ); // not evaluated
21+
22+
// Bounds has a handler, and audit is true
23+
assert<Bounds, audit>( test_condition_evaluation(4), "type" ); // evaluated: prints "4"
24+
audit = false;
25+
// Bounds has a handler, but audit is false
26+
assert<Bounds, audit>( test_condition_evaluation(5), "type" ); // not evaluated
27+
28+
assert<Unevaluated>( test_condition_evaluation(6) ); // not evaluated
1329
}

regression-tests/pure2-print.cpp2

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
// Exercise the pretty-print visualizer for the various grammar elements
33

4+
testing_enabled: bool = false;
5+
46
outer: @print type = {
57

68
object_alias: <T> T requires true == 42;
@@ -30,7 +32,7 @@ outer: @print type = {
3032

3133
private h: (s: std::string, inout m: std::map<const int,std::string> ) -> std::string
3234
pre( m.empty() == false || false, "message" )
33-
pre<Bounds>( 0 < m.ssize() < 100 && true != false )
35+
pre<Bounds, testing_enabled>( 0 < m.ssize() < 100 && true != false )
3436
= {
3537
a := :()={};
3638
b := :()={};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
1
22
2
3+
4
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
1
22
2
3+
4
Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
In file included from pure2-print.cpp:7:
22
../../../include/cpp2util.h:10005:33: error: expected unqualified-id before ‘static_assert’
3-
pure2-print.cpp2:7:1: note: in expansion of macro ‘CPP2_REQUIRES_’
4-
pure2-print.cpp2:65:59: error: expected ‘;’ at end of member declaration
3+
pure2-print.cpp2:9:1: note: in expansion of macro ‘CPP2_REQUIRES_’
4+
pure2-print.cpp2:67:59: error: expected ‘;’ at end of member declaration
55
In file included from pure2-print.cpp:7:
66
../../../include/cpp2util.h:10005:47: error: static assertion failed: GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.
7-
pure2-print.cpp2:66:1: note: in expansion of macro ‘CPP2_REQUIRES_’
7+
pure2-print.cpp2:68:1: note: in expansion of macro ‘CPP2_REQUIRES_’
88
../../../include/cpp2util.h:10005:33: error: expected initializer before ‘static_assert’
9-
pure2-print.cpp2:94:1: note: in expansion of macro ‘CPP2_REQUIRES_’
10-
pure2-print.cpp2:7:41: error: ‘constexpr const T outer::object_alias’ is not a static data member of ‘class outer’
11-
pure2-print.cpp2:7:48: error: template definition of non-template ‘constexpr const T outer::object_alias’
12-
pure2-print.cpp2:65:14: error: no declaration matches ‘void outer::mytype::variadic(const auto:90& ...) requires (is_convertible_v<typename std::remove_cv<typename std::remove_reference<decltype(outer::mytype::variadic::x)>::type>::type, int> && ...)’
13-
pure2-print.cpp2:65:29: note: candidate is: ‘template<class ... auto:89> static void outer::mytype::variadic(const auto:89& ...)’
14-
pure2-print.cpp2:8:19: note: ‘class outer::mytype’ defined here
15-
pure2-print.cpp2:93:37: error: no declaration matches ‘void outer::print(std::ostream&, const Args& ...) requires cpp2::cmp_greater_eq(sizeof (Args)..., 0)’
16-
pure2-print.cpp2:93:37: note: no functions named ‘void outer::print(std::ostream&, const Args& ...) requires cpp2::cmp_greater_eq(sizeof (Args)..., 0)’
17-
pure2-print.cpp2:4:7: note: ‘class outer’ defined here
9+
pure2-print.cpp2:96:1: note: in expansion of macro ‘CPP2_REQUIRES_’
10+
pure2-print.cpp2:9:41: error: ‘constexpr const T outer::object_alias’ is not a static data member of ‘class outer’
11+
pure2-print.cpp2:9:48: error: template definition of non-template ‘constexpr const T outer::object_alias’
12+
pure2-print.cpp2:67:14: error: no declaration matches ‘void outer::mytype::variadic(const auto:90& ...) requires (is_convertible_v<typename std::remove_cv<typename std::remove_reference<decltype(outer::mytype::variadic::x)>::type>::type, int> && ...)’
13+
pure2-print.cpp2:67:29: note: candidate is: ‘template<class ... auto:89> static void outer::mytype::variadic(const auto:89& ...)’
14+
pure2-print.cpp2:10:19: note: ‘class outer::mytype’ defined here
15+
pure2-print.cpp2:95:37: error: no declaration matches ‘void outer::print(std::ostream&, const Args& ...) requires cpp2::cmp_greater_eq(sizeof (Args)..., 0)’
16+
pure2-print.cpp2:95:37: note: no functions named ‘void outer::print(std::ostream&, const Args& ...) requires cpp2::cmp_greater_eq(sizeof (Args)..., 0)’
17+
pure2-print.cpp2:6:7: note: ‘class outer’ defined here
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
1
22
2
3+
4
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
1
22
2
3+
4

regression-tests/test-results/pure2-contracts.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
[[nodiscard]] auto test_condition_evaluation(auto const& tag) -> bool;
1616

1717
#line 3 "pure2-contracts.cpp2"
18+
extern bool audit;
19+
1820
auto main() -> int;
1921

2022
//=== Cpp2 function definitions =================================================
@@ -23,15 +25,31 @@ auto main() -> int;
2325
[[nodiscard]] auto test_condition_evaluation(auto const& tag) -> bool{std::cout << tag << "\n"; return true; }
2426

2527
#line 3 "pure2-contracts.cpp2"
28+
bool audit {true};
29+
2630
auto main() -> int{
31+
// A few basic tests
2732
if (cpp2::Default.has_handler() && !(1 != 2) ) { cpp2::Default.violation("ack, arithmetic is buggy"); }
2833
if (cpp2::Type.has_handler() && !(typeid(int) != typeid(double)) ) { cpp2::Type.violation("ack, C types are broken"); }
2934

30-
#line 8 "pure2-contracts.cpp2"
35+
#line 11 "pure2-contracts.cpp2"
36+
// Now test that conditions are only evaluated if there's
37+
// a handler active + any other control flags are enabled
38+
3139
if (cpp2::Default.has_handler() && !(test_condition_evaluation(1)) ) { cpp2::Default.violation("default"); }// evaluated: prints "1"
40+
41+
// Type has a handler
3242
if (cpp2::Type.has_handler() && !(test_condition_evaluation(2)) ) { cpp2::Type.violation("type"); }// evaluated: prints "2"
3343
CPP2_UFCS(set_handler)(cpp2::Type);
44+
// Type does not have a handler
3445
if (cpp2::Type.has_handler() && !(test_condition_evaluation(3)) ) { cpp2::Type.violation("type"); }// not evaluated
35-
// not evaluated
46+
47+
// Bounds has a handler, and audit is true
48+
if (cpp2::Bounds.has_handler() && audit && !(test_condition_evaluation(4)) ) { cpp2::Bounds.violation("type"); }// evaluated: prints "4"
49+
audit = false;
50+
// Bounds has a handler, but audit is false
51+
if (cpp2::Bounds.has_handler() && audit && !(test_condition_evaluation(5)) ) { cpp2::Bounds.violation("type"); }// not evaluated
52+
53+
// not evaluated
3654
}
3755

regression-tests/test-results/pure2-print.cpp

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#line 1 "pure2-print.cpp2"
1010

11-
#line 4 "pure2-print.cpp2"
11+
#line 6 "pure2-print.cpp2"
1212
class outer;
1313

1414

@@ -19,9 +19,11 @@ class outer;
1919
// Exercise the pretty-print visualizer for the various grammar elements
2020

2121
#line 4 "pure2-print.cpp2"
22+
extern bool testing_enabled;
23+
2224
class outer {
2325

24-
#line 6 "pure2-print.cpp2"
26+
#line 8 "pure2-print.cpp2"
2527
public: template<typename T>
2628
CPP2_REQUIRES_ (true) static const T object_alias;
2729
public: class mytype final
@@ -30,16 +32,16 @@ CPP2_REQUIRES_ (true) static const T object_alias;
3032

3133
public: [[nodiscard]] virtual auto g(cpp2::in<int> i) const -> int;
3234

33-
#line 31 "pure2-print.cpp2"
35+
#line 33 "pure2-print.cpp2"
3436
private: [[nodiscard]] static auto h(cpp2::in<std::string> s, std::map<int const,std::string>& m) -> std::string;
3537
struct values_ret { int offset; std::string name; };
3638

3739

3840

39-
#line 54 "pure2-print.cpp2"
41+
#line 56 "pure2-print.cpp2"
4042
public: template<typename T> [[nodiscard]] auto values([[maybe_unused]] T const& unnamed_param_2) const& -> values_ret;
4143

42-
#line 59 "pure2-print.cpp2"
44+
#line 61 "pure2-print.cpp2"
4345
public: explicit mytype();
4446

4547
public: mytype([[maybe_unused]] mytype const& that);
@@ -48,32 +50,32 @@ struct values_ret { int offset; std::string name; };
4850

4951
public: static auto variadic(auto const& ...x) -> void
5052
CPP2_REQUIRES_ ((std::is_convertible_v<CPP2_TYPEOF(x), int> && ...)) ;
51-
#line 66 "pure2-print.cpp2"
53+
#line 68 "pure2-print.cpp2"
5254
};
5355

5456
public: static auto test() -> void;
5557

56-
#line 89 "pure2-print.cpp2"
58+
#line 91 "pure2-print.cpp2"
5759
public: template<typename ...Ts> class x {
5860
private: std::tuple<Ts...> tup {};
5961
public: x() = default;
6062
public: x(x const&) = delete; /* No 'that' constructor, suppress copy */
6163
public: auto operator=(x const&) -> void = delete;
6264

63-
#line 91 "pure2-print.cpp2"
65+
#line 93 "pure2-print.cpp2"
6466
};
6567

6668
public: template<typename ...Args> static auto print(std::ostream& out, Args const& ...args) -> void
6769
CPP2_REQUIRES_ (cpp2::cmp_greater_eq(sizeof(Args)...,0)) ;
6870

69-
#line 97 "pure2-print.cpp2"
71+
#line 99 "pure2-print.cpp2"
7072
public: template<typename ...Args> [[nodiscard]] static auto all(Args const& ...args) -> bool;
7173
public: outer() = default;
7274
public: outer(outer const&) = delete; /* No 'that' constructor, suppress copy */
7375
public: auto operator=(outer const&) -> void = delete;
7476

7577

76-
#line 100 "pure2-print.cpp2"
78+
#line 102 "pure2-print.cpp2"
7779
};
7880

7981
auto main() -> int;
@@ -82,12 +84,15 @@ auto main() -> int;
8284

8385
#line 1 "pure2-print.cpp2"
8486

85-
#line 6 "pure2-print.cpp2"
87+
#line 4 "pure2-print.cpp2"
88+
bool testing_enabled {false};
89+
90+
#line 8 "pure2-print.cpp2"
8691
template<typename T>
8792
requires (true) inline CPP2_CONSTEXPR T outer::object_alias = 42;
88-
#line 7 "pure2-print.cpp2"
93+
#line 9 "pure2-print.cpp2"
8994

90-
#line 10 "pure2-print.cpp2"
95+
#line 12 "pure2-print.cpp2"
9196
[[nodiscard]] auto outer::mytype::f() -> int { return 42; }
9297

9398
[[nodiscard]] auto outer::mytype::g(cpp2::in<int> i) const -> int{
@@ -111,11 +116,11 @@ requires (true) inline CPP2_CONSTEXPR T outer::object_alias = 42;
111116

112117
[[nodiscard]] auto outer::mytype::h(cpp2::in<std::string> s, std::map<int const,std::string>& m) -> std::string
113118

114-
#line 34 "pure2-print.cpp2"
119+
#line 36 "pure2-print.cpp2"
115120
{
116121
if (cpp2::Default.has_handler() && !(CPP2_UFCS(empty)(m) == false || false) ) { cpp2::Default.violation("message"); }
117-
if (cpp2::Bounds.has_handler() && !([_0 = 0, _1 = CPP2_UFCS(ssize)(m), _2 = 100]{ return cpp2::cmp_less(_0,_1) && cpp2::cmp_less(_1,_2); }() && true != false) ) { cpp2::Bounds.violation(""); }
118-
#line 35 "pure2-print.cpp2"
122+
if (cpp2::Bounds.has_handler() && testing_enabled && !([_0 = 0, _1 = CPP2_UFCS(ssize)(m), _2 = 100]{ return cpp2::cmp_less(_0,_1) && cpp2::cmp_less(_1,_2); }() && true != false) ) { cpp2::Bounds.violation(""); }
123+
#line 37 "pure2-print.cpp2"
119124
auto a {[]() mutable -> void{}};
120125
auto b {[]() mutable -> void{}};
121126
auto c {[]() mutable -> void{}};
@@ -124,9 +129,9 @@ requires (true) inline CPP2_CONSTEXPR T outer::object_alias = 42;
124129

125130
do {} while ( [&]{ b() ; return true; }() && CPP2_UFCS(empty)(s));
126131

127-
for ( [[maybe_unused]] auto const& unnamed_param_1 : m ) { { do {goto CONTINUE_43_13; } while (false); c(); } CPP2_CONTINUE_BREAK(43_13) }
132+
for ( [[maybe_unused]] auto const& unnamed_param_1 : m ) { { do {goto CONTINUE_45_13; } while (false); c(); } CPP2_CONTINUE_BREAK(45_13) }
128133

129-
#line 45 "pure2-print.cpp2"
134+
#line 47 "pure2-print.cpp2"
130135
if (cpp2::is(!(CPP2_UFCS(empty)(s)), (true))) {std::move(a)(); }
131136
else {if (!(CPP2_UFCS(empty)(m))) {std::move(b)(); }
132137
else {std::move(c)(); }}
@@ -139,7 +144,7 @@ requires (true) inline CPP2_CONSTEXPR T outer::object_alias = 42;
139144
template<typename T> [[nodiscard]] auto outer::mytype::values([[maybe_unused]] T const& unnamed_param_2) const& -> values_ret{
140145
cpp2::deferred_init<int> offset;
141146
cpp2::deferred_init<std::string> name;
142-
#line 55 "pure2-print.cpp2"
147+
#line 57 "pure2-print.cpp2"
143148
offset.construct(53);
144149
name.construct("plugh");
145150
return { std::move(offset.value()), std::move(name.value()) }; }
@@ -153,7 +158,7 @@ requires (true) inline CPP2_CONSTEXPR T outer::object_alias = 42;
153158
auto outer::mytype::variadic(auto const& ...x) -> void
154159
requires ((std::is_convertible_v<CPP2_TYPEOF(x), int> && ...)) {(std::cout << ... << x); }
155160

156-
#line 68 "pure2-print.cpp2"
161+
#line 70 "pure2-print.cpp2"
157162
auto outer::test() -> void{
158163
namespace namespace_alias = ::std;
159164

@@ -165,7 +170,7 @@ requires ((std::is_convertible_v<CPP2_TYPEOF(x), int> && ...)) {(std::cout << ..
165170
cpp2::i8 constexpr object_alias_1 = 42;
166171
auto constexpr object_alias_2 = 42;
167172

168-
#line 80 "pure2-print.cpp2"
173+
#line 82 "pure2-print.cpp2"
169174
::outer::mytype var {};
170175
cout << CPP2_UFCS(g)(var, 42) << "\n";
171176

@@ -175,17 +180,17 @@ requires ((std::is_convertible_v<CPP2_TYPEOF(x), int> && ...)) {(std::cout << ..
175180
() << "\n";
176181
}
177182

178-
#line 93 "pure2-print.cpp2"
183+
#line 95 "pure2-print.cpp2"
179184
template<typename ...Args> auto outer::print(std::ostream& out, Args const& ...args) -> void
180185
requires (cpp2::cmp_greater_eq(sizeof(Args)...,0)) {
181-
#line 94 "pure2-print.cpp2"
186+
#line 96 "pure2-print.cpp2"
182187
(out << ... << args);
183188
}
184189

185190
template<typename ...Args> [[nodiscard]] auto outer::all(Args const& ...args) -> bool {
186191
return (... && args); }
187192

188-
#line 102 "pure2-print.cpp2"
193+
#line 104 "pure2-print.cpp2"
189194
auto main() -> int{
190195
outer::test();
191196
}

regression-tests/test-results/pure2-print.cpp2.output

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ outer: type =
3333
inout m: std::map<const int, std::string>
3434
) -> move std::string
3535
pre( m.empty() == false || false, "message" )
36-
pre<Bounds>( 0 < m.ssize() < 100 && true != false ) =
36+
pre<Bounds,testing_enabled>( 0 < m.ssize() < 100 && true != false ) =
3737
{
3838
a: = :() =
3939
{

regression-tests/test-results/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
cppfront compiler v0.3.0 Build 8C17:0658
2+
cppfront compiler v0.3.0 Build 8C17:1133
33
Copyright(c) Herb Sutter All rights reserved
44

55
SPDX-License-Identifier: CC-BY-NC-ND-4.0

source/build.info

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"8C17:0658"
1+
"8C17:1133"

0 commit comments

Comments
 (0)