Skip to content

Commit 90faa49

Browse files
committed
fix(parse): recognize const and pointer template arguments
1 parent 5a57f5e commit 90faa49

6 files changed

+60
-21
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
main: () = //
2+
std::is_void_v<* i32> //
3+
&& std::is_void_v<const i32>;

regression-tests/test-results/gcc-13/pure2-bugfix-for-template-argument.cpp.execution

Whitespace-only changes.

regression-tests/test-results/gcc-13/pure2-bugfix-for-template-argument.cpp.output

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
#define CPP2_USE_MODULES Yes
3+
4+
//=== Cpp2 type declarations ====================================================
5+
6+
7+
#include "cpp2util.h"
8+
9+
10+
11+
//=== Cpp2 type definitions and function declarations ===========================
12+
13+
#line 1 "pure2-bugfix-for-template-argument.cpp2"
14+
auto main() -> int;
15+
16+
17+
//=== Cpp2 function definitions =================================================
18+
19+
#line 1 "pure2-bugfix-for-template-argument.cpp2"
20+
auto main() -> int { //
21+
std::is_void_v<cpp2::i32*> //
22+
&& std::is_void_v<cpp2::i32 const>; }
23+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pure2-bugfix-for-template-argument.cpp2... ok (all Cpp2, passes safety checks)
2+

source/parse.h

+32-21
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ struct postfix_expression_node
721721
if (ops.empty()) {
722722
return false;
723723
} else {
724-
return (ops.front().op->type() == lexeme::Ampersand
724+
return (ops.front().op->type() == lexeme::Ampersand
725725
|| ops.front().op->type() == lexeme::Tilde);
726726
}
727727
}
@@ -3965,7 +3965,7 @@ class parser
39653965
// || curr().type() == lexeme::LeftBrace
39663966
)
39673967
{
3968-
bool inside_initializer = (
3968+
bool inside_initializer = (
39693969
peek(-1) && peek(-1)->type() == lexeme::Assignment
39703970
);
39713971
auto open_paren = &curr();
@@ -3987,12 +3987,12 @@ class parser
39873987
next();
39883988
if (
39893989
curr().type() != lexeme::Semicolon
3990-
&& curr().type() != lexeme::RightParen
3991-
&& curr().type() != lexeme::RightBracket
3990+
&& curr().type() != lexeme::RightParen
3991+
&& curr().type() != lexeme::RightBracket
39923992
&& curr().type() != lexeme::Comma
39933993
) {
39943994
expr_list->inside_initializer = false;
3995-
}
3995+
}
39963996
n->expr = std::move(expr_list);
39973997
return n;
39983998
}
@@ -4350,7 +4350,7 @@ class parser
43504350
//G shift-expression '<<' additive-expression
43514351
//G shift-expression '>>' additive-expression
43524352
//G
4353-
auto shift_expression(bool allow_angle_operators = true)
4353+
auto shift_expression(bool allow_angle_operators = true)
43544354
-> auto
43554355
{
43564356
if (allow_angle_operators) {
@@ -4385,7 +4385,7 @@ class parser
43854385
//G shift-expression
43864386
//G compare-expression '<=>' shift-expression
43874387
//G
4388-
auto compare_expression(bool allow_angle_operators = true)
4388+
auto compare_expression(bool allow_angle_operators = true)
43894389
-> auto
43904390
{
43914391
return binary_expression<compare_expression_node> (
@@ -4401,7 +4401,7 @@ class parser
44014401
//G relational-expression '<=' compare-expression
44024402
//G relational-expression '>=' compare-expression
44034403
//G
4404-
auto relational_expression(bool allow_angle_operators = true)
4404+
auto relational_expression(bool allow_angle_operators = true)
44054405
-> auto
44064406
{
44074407
if (allow_angle_operators) {
@@ -4433,7 +4433,7 @@ class parser
44334433
//G equality-expression '==' relational-expression
44344434
//G equality-expression '!=' relational-expression
44354435
//G
4436-
auto equality_expression(bool allow_angle_operators = true)
4436+
auto equality_expression(bool allow_angle_operators = true)
44374437
-> auto
44384438
{
44394439
return binary_expression<equality_expression_node> (
@@ -4446,7 +4446,7 @@ class parser
44464446
//G equality-expression
44474447
//G bit-and-expression '&' equality-expression
44484448
//G
4449-
auto bit_and_expression(bool allow_angle_operators = true)
4449+
auto bit_and_expression(bool allow_angle_operators = true)
44504450
-> auto
44514451
{
44524452
return binary_expression<bit_and_expression_node> (
@@ -4459,7 +4459,7 @@ class parser
44594459
//G bit-and-expression
44604460
//G bit-xor-expression '^' bit-and-expression
44614461
//G
4462-
auto bit_xor_expression(bool allow_angle_operators = true)
4462+
auto bit_xor_expression(bool allow_angle_operators = true)
44634463
-> auto
44644464
{
44654465
return binary_expression<bit_xor_expression_node> (
@@ -4472,7 +4472,7 @@ class parser
44724472
//G bit-xor-expression
44734473
//G bit-or-expression '|' bit-xor-expression
44744474
//G
4475-
auto bit_or_expression(bool allow_angle_operators = true)
4475+
auto bit_or_expression(bool allow_angle_operators = true)
44764476
-> auto
44774477
{
44784478
return binary_expression<bit_or_expression_node> (
@@ -4485,7 +4485,7 @@ class parser
44854485
//G bit-or-expression
44864486
//G logical-and-expression '&&' bit-or-expression
44874487
//G
4488-
auto logical_and_expression(bool allow_angle_operators = true)
4488+
auto logical_and_expression(bool allow_angle_operators = true)
44894489
-> auto
44904490
{
44914491
return binary_expression<logical_and_expression_node> (
@@ -4500,7 +4500,7 @@ class parser
45004500
//G logical-and-expression
45014501
//G logical-or-expression '||' logical-and-expression
45024502
//G
4503-
auto logical_or_expression(bool allow_angle_operators = true)
4503+
auto logical_or_expression(bool allow_angle_operators = true)
45044504
-> auto
45054505
{
45064506
return binary_expression<logical_or_expression_node> (
@@ -4789,6 +4789,7 @@ class parser
47894789
//G
47904790
//G template-argument:
47914791
//G # note: < > << >> are not allowed in expressions until new ( is opened
4792+
//G const type-id
47924793
//G expression
47934794
//G type-id
47944795
//G
@@ -4818,12 +4819,22 @@ class parser
48184819

48194820
n->open_angle = curr().position();
48204821
next();
4821-
4822+
48224823
auto term = unqualified_id_node::term{};
48234824

48244825
do {
4825-
// disallow unparenthesized relational comparisons in template args
4826-
if (auto e = expression(false)) {
4826+
if (auto e = [&]() {
4827+
// If the template-argument can only be a type id
4828+
// skip the expression production, because it start with
4829+
if (
4830+
curr().type() == lexeme::Multiply // '*'
4831+
|| curr() == "const" // 'const'
4832+
) {
4833+
return decltype(expression()){};
4834+
}
4835+
// disallow unparenthesized relational comparisons in template args
4836+
return expression(false);
4837+
}()) {
48274838
term.arg = std::move(e);
48284839
}
48294840
else if (auto i = type_id()) {
@@ -6389,7 +6400,7 @@ class parser
63896400
}
63906401
assert (n->is_type());
63916402
}
6392-
6403+
63936404
// Or a function type, declaring a function - and tell the function whether it's in a user-defined type
63946405
else if (auto t = function_type(n.get(), named))
63956406
{
@@ -6537,11 +6548,11 @@ class parser
65376548
)
65386549
{
65396550
auto& type = std::get<declaration_node::an_object>(n->type);
6540-
// object initialized by the address of the curr() object
6551+
// object initialized by the address of the curr() object
65416552
if (peek(1)->type() == lexeme::Ampersand) {
65426553
type->address_of = &curr();
65436554
}
6544-
// object initialized by (potentially multiple) dereference of the curr() object
6555+
// object initialized by (potentially multiple) dereference of the curr() object
65456556
else if (peek(1)->type() == lexeme::Multiply) {
65466557
type->dereference_of = &curr();
65476558
for (int i = 1; peek(i)->type() == lexeme::Multiply; ++i)
@@ -6746,7 +6757,7 @@ class parser
67466757
return {};
67476758
}
67486759
if (
6749-
t->is_wildcard()
6760+
t->is_wildcard()
67506761
|| ( t->get_token() && t->get_token()->to_string(true) == "auto" )
67516762
) {
67526763
errors.emplace_back(

0 commit comments

Comments
 (0)