Skip to content

Commit 0172e35

Browse files
authored
Merge branch 'main' into feature/regular_expression_metafunction
Signed-off-by: Max Sagebaum <[email protected]>
2 parents 5942bdd + 3a8874a commit 0172e35

27 files changed

+110
-66
lines changed

docs/cpp2/expressions.md

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,27 @@ f: ( v : std::vector<widget> ) = {
2727
log( v.ssize() );
2828
}
2929

30-
// Generic function to print "hello, ___!" for any printable type
31-
hello: (name) = {
32-
myfile := fopen("xyzzy.txt", "w");
33-
// Direct calls to C nonmember functions, using UFCS and safe
34-
// string interpolation (instead of type-unsafe format strings)
35-
myfile.fprintf( "Hello, (name)$!\n" );
36-
myfile.fclose();
30+
// Generic function to use standard I/O to print any printable types
31+
// safely using string interpolation (instead of type-unsafe format strings)
32+
hello: (name, height: float) = {
33+
// Using UFCS to make direct calls to C functions as if they were members
34+
stdout.fprintf( "%s", ("Hello (name)$, your height is (height:.1f)$ inches!\n").c_str() );
35+
// Equivalent using iostreams:
36+
// std::cout << "Hello (name)$, your height is (height:.1f)$ inches!\n";
37+
3738
// The C and C++ standard libraries are not only fully available,
3839
// but safer (and arguably nicer) when used from Cpp2 syntax code
3940
}
41+
42+
main: () = {
43+
hello("Flimnap", 6.5);
44+
hello("Goliath", 115);
45+
hello("Polyphemus", 180);
46+
}
47+
// Sample output:
48+
// Hello Flimnap, your height is 6.5 inches!
49+
// Hello Goliath, your height is 115.0 inches!
50+
// Hello Polyphemus, your height is 180.0 inches!
4051
```
4152

4253
To explicitly treat an object name passed as an argument as `move` or `out`, write that keyword before the variable name.

include/cpp2util.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@
4343

4444
// If this implementation doesn't support source_location yet, disable it
4545
#include <version>
46-
#if !defined(_MSC_VER) && !defined(__cpp_lib_source_location)
47-
#undef CPP2_USE_SOURCE_LOCATION
46+
47+
#undef CPP2_USE_SOURCE_LOCATION
48+
#if defined(__cpp_lib_source_location)
49+
#define CPP2_USE_SOURCE_LOCATION Yes
4850
#endif
4951

5052
// If the user requested making the entire C++ standard library available
@@ -557,15 +559,17 @@ auto pointer_eq(T const* a, T const* b) {
557559
//
558560

559561
#ifdef CPP2_USE_SOURCE_LOCATION
560-
#define CPP2_SOURCE_LOCATION_PARAM , std::source_location where
561-
#define CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT , std::source_location where = std::source_location::current()
562-
#define CPP2_SOURCE_LOCATION_PARAM_SOLO std::source_location where
562+
#define CPP2_SOURCE_LOCATION_PARAM , [[maybe_unused]] std::source_location where
563+
#define CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT , [[maybe_unused]] std::source_location where = std::source_location::current()
564+
#define CPP2_SOURCE_LOCATION_PARAM_SOLO [[maybe_unused]] std::source_location where
563565
#define CPP2_SOURCE_LOCATION_ARG , where
566+
#define CPP2_SOURCE_LOCATION_VALUE (cpp2::to_string(where.file_name()) + "(" + cpp2::to_string(where.line()) + ") " + where.function_name())
564567
#else
565568
#define CPP2_SOURCE_LOCATION_PARAM
566569
#define CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT
567570
#define CPP2_SOURCE_LOCATION_PARAM_SOLO
568571
#define CPP2_SOURCE_LOCATION_ARG
572+
#define CPP2_SOURCE_LOCATION_VALUE std::string("")
569573
#endif
570574

571575
// For C++23: make this std::string_view and drop the macro
@@ -1524,8 +1528,16 @@ inline constexpr auto as() -> auto
15241528
return cpp2::to_string(CPP2_FORWARD(x));
15251529
}
15261530

1531+
// Work around MSVC modules bugs: source_location doesn't work correctly if imported via a module
1532+
#if defined(_MSC_VER) && defined(CPP2_IMPORT_STD)
1533+
#define CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS
1534+
#define CPP2_SOURCE_LOCATION_ARG_AS
1535+
#else
1536+
#define CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT
1537+
#define CPP2_SOURCE_LOCATION_ARG_AS CPP2_SOURCE_LOCATION_ARG
1538+
#endif
15271539
template< typename C >
1528-
auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> decltype(auto)
1540+
auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
15291541
// This "requires" list may need to be tweaked further. The idea is to have
15301542
// this function used for all the cases it's supposed to cover, but not
15311543
// hide user-supplied extensions (such as the ones later in this file for
@@ -1559,7 +1571,7 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> decltype(auto)
15591571
const C c = static_cast<C>(CPP2_FORWARD(x));
15601572
type_safety.enforce( // precondition check: must be round-trippable => not lossy
15611573
static_cast<CPP2_TYPEOF(x)>(c) == x && (c < C{}) == (x < CPP2_TYPEOF(x){}),
1562-
"dynamic lossy narrowing conversion attempt detected" CPP2_SOURCE_LOCATION_ARG
1574+
"dynamic lossy narrowing conversion attempt detected" CPP2_SOURCE_LOCATION_ARG_AS
15631575
);
15641576
return CPP2_COPY(c);
15651577
}

regression-tests/mixed-lifetime-safety-and-null-contracts.cpp2

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,17 @@ try_pointer_stuff: () = {
1818
// to show -n
1919
}
2020

21-
call_my_framework: (msg: * const char) = {
21+
auto call_my_framework(const char* msg CPP2_SOURCE_LOCATION_PARAM) {
2222
std::cout
2323
<< "sending error to my framework... ["
24-
<< msg << "]\n";
24+
<< msg
25+
<< "]\n";
26+
auto loc = CPP2_SOURCE_LOCATION_VALUE;
27+
if (!loc.empty()) {
28+
std::cout
29+
<< "from source location: "
30+
<< loc
31+
<< "]\n";
32+
}
2533
exit(0);
2634
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Bounds safety violation: out of bounds access attempt detected - attempted access at index 5, [min,max] range is [0,4]
1+
mixed-bounds-check.cpp2(9) int main(): Bounds safety violation: out of bounds access attempt detected - attempted access at index 5, [min,max] range is [0,4]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Bounds safety violation
1+
mixed-bounds-safety-with-assert.cpp2(11) void print_subrange(const auto:89&, cpp2::impl::in<int>, cpp2::impl::in<int>) [with auto:89 = std::vector<int>; cpp2::impl::in<int> = const int]: Bounds safety violation
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
11
In file included from mixed-bugfix-for-ufcs-non-local.cpp:6:
22
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
3-
2100 | // compiler may not assume it knows anything at all about
3+
2100 | {
44
| ^
55
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
6-
2137 | //
6+
2137 | // Speculative: RAII wrapping for the C standard library
77
| ^
88
mixed-bugfix-for-ufcs-non-local.cpp2:13:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
99
mixed-bugfix-for-ufcs-non-local.cpp2:13:36: error: template argument 1 is invalid
1010
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
11-
2100 | // compiler may not assume it knows anything at all about
11+
2100 | {
1212
| ^
1313
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
14-
2137 | //
14+
2137 | // Speculative: RAII wrapping for the C standard library
1515
| ^
1616
mixed-bugfix-for-ufcs-non-local.cpp2:21:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
1717
mixed-bugfix-for-ufcs-non-local.cpp2:21:36: error: template argument 1 is invalid
1818
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
19-
2100 | // compiler may not assume it knows anything at all about
19+
2100 | {
2020
| ^
2121
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
22-
2137 | //
22+
2137 | // Speculative: RAII wrapping for the C standard library
2323
| ^
2424
mixed-bugfix-for-ufcs-non-local.cpp2:31:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
2525
mixed-bugfix-for-ufcs-non-local.cpp2:31:36: error: template argument 1 is invalid
2626
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
27-
2100 | // compiler may not assume it knows anything at all about
27+
2100 | {
2828
| ^
2929
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
30-
2137 | //
30+
2137 | // Speculative: RAII wrapping for the C standard library
3131
| ^
3232
mixed-bugfix-for-ufcs-non-local.cpp2:33:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
3333
mixed-bugfix-for-ufcs-non-local.cpp2:33:36: error: template argument 1 is invalid
3434
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
35-
2100 | // compiler may not assume it knows anything at all about
35+
2100 | {
3636
| ^
3737
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
38-
2137 | //
38+
2137 | // Speculative: RAII wrapping for the C standard library
3939
| ^
4040
mixed-bugfix-for-ufcs-non-local.cpp2:21:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
4141
mixed-bugfix-for-ufcs-non-local.cpp2:21:36: error: template argument 1 is invalid
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Contract violation: fill: value must contain at least count elements
1+
mixed-initialization-safety-3-contract-violation.cpp2(25) void fill(cpp2::impl::out<std::__cxx11::basic_string<char> >, cpp2::impl::in<std::__cxx11::basic_string<char> >, cpp2::impl::in<int>): Contract violation: fill: value must contain at least count elements
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
sending error to my framework... [dynamic null dereference attempt detected]
2+
from source location: mixed-lifetime-safety-and-null-contracts.cpp2(17) void try_pointer_stuff()]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Null safety violation: std::expected has an unexpected value
1+
pure2-assert-expected-not-null.cpp2(15) int bad_expected_access(): Null safety violation: std::expected has an unexpected value
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Null safety violation: std::optional does not contain a value
1+
pure2-assert-optional-not-null.cpp2(14) int bad_optional_access(): Null safety violation: std::optional does not contain a value
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Null safety violation: std::shared_ptr is empty
1+
pure2-assert-shared-ptr-not-null.cpp2(15) int bad_shared_ptr_access(): Null safety violation: std::shared_ptr is empty
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Null safety violation: std::unique_ptr is empty
1+
pure2-assert-unique-ptr-not-null.cpp2(15) int bad_unique_ptr_access(): Null safety violation: std::unique_ptr is empty

regression-tests/test-results/mixed-lifetime-safety-and-null-contracts.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,23 @@
2424
auto null_from_cpp1() -> int* { return nullptr; }
2525

2626
auto try_pointer_stuff() -> void;
27+
#line 20 "mixed-lifetime-safety-and-null-contracts.cpp2"
28+
29+
auto call_my_framework(const char* msg CPP2_SOURCE_LOCATION_PARAM) {
30+
std::cout
31+
<< "sending error to my framework... ["
32+
<< msg
33+
<< "]\n";
34+
auto loc = CPP2_SOURCE_LOCATION_VALUE;
35+
if (!loc.empty()) {
36+
std::cout
37+
<< "from source location: "
38+
<< loc
39+
<< "]\n";
40+
}
41+
exit(0);
42+
}
2743

28-
#line 21 "mixed-lifetime-safety-and-null-contracts.cpp2"
29-
auto call_my_framework(char const* msg) -> void;
3044

3145
//=== Cpp2 function definitions =================================================
3246

@@ -46,11 +60,3 @@ auto try_pointer_stuff() -> void{
4660
// to show -n
4761
}
4862

49-
#line 21 "mixed-lifetime-safety-and-null-contracts.cpp2"
50-
auto call_my_framework(char const* msg) -> void{
51-
std::cout
52-
<< "sending error to my framework... ["
53-
<< msg << "]\n";
54-
exit(0);
55-
}
56-
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Bounds safety violation: out of bounds access attempt detected - attempted access at index 5, [min,max] range is [0,4]
1+
mixed-bounds-check.cpp2(9) int __cdecl main(void): Bounds safety violation: out of bounds access attempt detected - attempted access at index 5, [min,max] range is [0,4]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Bounds safety violation
1+
mixed-bounds-safety-with-assert.cpp2(11) void __cdecl print_subrange<class std::vector<int,class std::allocator<int> >>(const class std::vector<int,class std::allocator<int> > &,const int,const int): Bounds safety violation
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Contract violation: fill: value must contain at least count elements
1+
mixed-initialization-safety-3-contract-violation.cpp2(25) void __cdecl fill(class cpp2::impl::out<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,const class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,const int): Contract violation: fill: value must contain at least count elements
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
sending error to my framework... [dynamic null dereference attempt detected]
2+
from source location: mixed-lifetime-safety-and-null-contracts.cpp2(17) void __cdecl try_pointer_stuff(void)]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Null safety violation: std::expected has an unexpected value
1+
pure2-assert-expected-not-null.cpp2(15) int __cdecl bad_expected_access(void): Null safety violation: std::expected has an unexpected value
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Null safety violation: std::optional does not contain a value
1+
pure2-assert-optional-not-null.cpp2(14) int __cdecl bad_optional_access(void): Null safety violation: std::optional does not contain a value
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Null safety violation: std::shared_ptr is empty
1+
pure2-assert-shared-ptr-not-null.cpp2(15) int __cdecl bad_shared_ptr_access(void): Null safety violation: std::shared_ptr is empty
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Null safety violation: std::unique_ptr is empty
1+
pure2-assert-unique-ptr-not-null.cpp2(15) int __cdecl bad_unique_ptr_access(void): Null safety violation: std::unique_ptr is empty
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
pure2-statement-parse-error.cpp2...
2-
pure2-statement-parse-error.cpp2(3,9): error: invalid statement encountered inside a compound-statement (at 'b')
2+
pure2-statement-parse-error.cpp2(3,5): error: invalid statement encountered inside a compound-statement (at 'int')
33

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.7.0 Build 9712:1020
2+
cppfront compiler v0.7.1 Build 9713:1156
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-
"9712:1020"
1+
"9713:1156"

source/parse.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6960,6 +6960,9 @@ class parser
69606960
expression_statement_node::current_expression_statements.push_back(n.get());
69616961
auto guard = finally([&]{ expression_statement_node::current_expression_statements.pop_back(); });
69626962

6963+
// Remember current position, in case this isn't a valid expression-statement
6964+
auto start_pos = pos;
6965+
69636966
if (!(n->expr = expression(true, true))) {
69646967
return {};
69656968
}
@@ -6978,6 +6981,7 @@ class parser
69786981
// it doesn't destabilize any regression tests
69796982
)
69806983
{
6984+
pos = start_pos; // backtrack
69816985
return {};
69826986
}
69836987
if (
@@ -7248,6 +7252,10 @@ class parser
72487252
return {};
72497253
}
72507254

7255+
if (curr().type() == lexeme::Comma) {
7256+
error("iterating over multiple ranges at once is not currently supported");
7257+
}
7258+
72517259
if (!handle_optional_next_clause()) { return {}; }
72527260

72537261
if (
@@ -7671,6 +7679,15 @@ class parser
76717679
}
76727680

76737681
else {
7682+
if (
7683+
curr().type() == lexeme::Identifier
7684+
&& peek(1)
7685+
&& peek(1)->type() == lexeme::Comma
7686+
)
7687+
{
7688+
next();
7689+
error("declaring multiple names at once is not currently supported");
7690+
}
76747691
return {};
76757692
}
76767693
}

source/to_cpp1.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,6 @@ static cmdline_processor::register_flag cmd_safe_comparisons(
147147
[]{ flag_safe_comparisons = false; }
148148
);
149149

150-
static auto flag_use_source_location = false;
151-
static cmdline_processor::register_flag cmd_enable_source_info(
152-
2,
153-
"add-source-info",
154-
"Enable source_location information for contract checks",
155-
[]{ flag_use_source_location = true; }
156-
);
157-
158150
static auto flag_cpp1_filename = std::string{};
159151
static cmdline_processor::register_flag cmd_cpp1_filename(
160152
8,
@@ -1309,10 +1301,6 @@ class cppfront
13091301
printer.print_extra( "#define " + cpp1_FILENAME+"_CPP2" + "\n\n" );
13101302
}
13111303

1312-
if (flag_use_source_location) {
1313-
printer.print_extra( "#define CPP2_USE_SOURCE_LOCATION Yes\n" );
1314-
}
1315-
13161304
if (flag_include_std) {
13171305
printer.print_extra( "#define CPP2_INCLUDE_STD Yes\n" );
13181306
}

source/version.info

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"v0.7.0"
1+
"v0.7.1"

0 commit comments

Comments
 (0)