Skip to content

Commit

Permalink
fix(parse): recognize const and pointer template arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
JohelEGP committed Jun 21, 2023
1 parent 5a57f5e commit 90faa49
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 21 deletions.
3 changes: 3 additions & 0 deletions regression-tests/pure2-bugfix-for-template-argument.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
main: () = //
std::is_void_v<* i32> //
&& std::is_void_v<const i32>;
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

#define CPP2_USE_MODULES Yes

//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"



//=== Cpp2 type definitions and function declarations ===========================

#line 1 "pure2-bugfix-for-template-argument.cpp2"
auto main() -> int;


//=== Cpp2 function definitions =================================================

#line 1 "pure2-bugfix-for-template-argument.cpp2"
auto main() -> int { //
std::is_void_v<cpp2::i32*> //
&& std::is_void_v<cpp2::i32 const>; }

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pure2-bugfix-for-template-argument.cpp2... ok (all Cpp2, passes safety checks)

53 changes: 32 additions & 21 deletions source/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ struct postfix_expression_node
if (ops.empty()) {
return false;
} else {
return (ops.front().op->type() == lexeme::Ampersand
return (ops.front().op->type() == lexeme::Ampersand
|| ops.front().op->type() == lexeme::Tilde);
}
}
Expand Down Expand Up @@ -3965,7 +3965,7 @@ class parser
// || curr().type() == lexeme::LeftBrace
)
{
bool inside_initializer = (
bool inside_initializer = (
peek(-1) && peek(-1)->type() == lexeme::Assignment
);
auto open_paren = &curr();
Expand All @@ -3987,12 +3987,12 @@ class parser
next();
if (
curr().type() != lexeme::Semicolon
&& curr().type() != lexeme::RightParen
&& curr().type() != lexeme::RightBracket
&& curr().type() != lexeme::RightParen
&& curr().type() != lexeme::RightBracket
&& curr().type() != lexeme::Comma
) {
expr_list->inside_initializer = false;
}
}
n->expr = std::move(expr_list);
return n;
}
Expand Down Expand Up @@ -4350,7 +4350,7 @@ class parser
//G shift-expression '<<' additive-expression
//G shift-expression '>>' additive-expression
//G
auto shift_expression(bool allow_angle_operators = true)
auto shift_expression(bool allow_angle_operators = true)
-> auto
{
if (allow_angle_operators) {
Expand Down Expand Up @@ -4385,7 +4385,7 @@ class parser
//G shift-expression
//G compare-expression '<=>' shift-expression
//G
auto compare_expression(bool allow_angle_operators = true)
auto compare_expression(bool allow_angle_operators = true)
-> auto
{
return binary_expression<compare_expression_node> (
Expand All @@ -4401,7 +4401,7 @@ class parser
//G relational-expression '<=' compare-expression
//G relational-expression '>=' compare-expression
//G
auto relational_expression(bool allow_angle_operators = true)
auto relational_expression(bool allow_angle_operators = true)
-> auto
{
if (allow_angle_operators) {
Expand Down Expand Up @@ -4433,7 +4433,7 @@ class parser
//G equality-expression '==' relational-expression
//G equality-expression '!=' relational-expression
//G
auto equality_expression(bool allow_angle_operators = true)
auto equality_expression(bool allow_angle_operators = true)
-> auto
{
return binary_expression<equality_expression_node> (
Expand All @@ -4446,7 +4446,7 @@ class parser
//G equality-expression
//G bit-and-expression '&' equality-expression
//G
auto bit_and_expression(bool allow_angle_operators = true)
auto bit_and_expression(bool allow_angle_operators = true)
-> auto
{
return binary_expression<bit_and_expression_node> (
Expand All @@ -4459,7 +4459,7 @@ class parser
//G bit-and-expression
//G bit-xor-expression '^' bit-and-expression
//G
auto bit_xor_expression(bool allow_angle_operators = true)
auto bit_xor_expression(bool allow_angle_operators = true)
-> auto
{
return binary_expression<bit_xor_expression_node> (
Expand All @@ -4472,7 +4472,7 @@ class parser
//G bit-xor-expression
//G bit-or-expression '|' bit-xor-expression
//G
auto bit_or_expression(bool allow_angle_operators = true)
auto bit_or_expression(bool allow_angle_operators = true)
-> auto
{
return binary_expression<bit_or_expression_node> (
Expand All @@ -4485,7 +4485,7 @@ class parser
//G bit-or-expression
//G logical-and-expression '&&' bit-or-expression
//G
auto logical_and_expression(bool allow_angle_operators = true)
auto logical_and_expression(bool allow_angle_operators = true)
-> auto
{
return binary_expression<logical_and_expression_node> (
Expand All @@ -4500,7 +4500,7 @@ class parser
//G logical-and-expression
//G logical-or-expression '||' logical-and-expression
//G
auto logical_or_expression(bool allow_angle_operators = true)
auto logical_or_expression(bool allow_angle_operators = true)
-> auto
{
return binary_expression<logical_or_expression_node> (
Expand Down Expand Up @@ -4789,6 +4789,7 @@ class parser
//G
//G template-argument:
//G # note: < > << >> are not allowed in expressions until new ( is opened
//G const type-id
//G expression
//G type-id
//G
Expand Down Expand Up @@ -4818,12 +4819,22 @@ class parser

n->open_angle = curr().position();
next();

auto term = unqualified_id_node::term{};

do {
// disallow unparenthesized relational comparisons in template args
if (auto e = expression(false)) {
if (auto e = [&]() {
// If the template-argument can only be a type id
// skip the expression production, because it start with
if (
curr().type() == lexeme::Multiply // '*'
|| curr() == "const" // 'const'
) {
return decltype(expression()){};
}
// disallow unparenthesized relational comparisons in template args
return expression(false);
}()) {
term.arg = std::move(e);
}
else if (auto i = type_id()) {
Expand Down Expand Up @@ -6389,7 +6400,7 @@ class parser
}
assert (n->is_type());
}

// Or a function type, declaring a function - and tell the function whether it's in a user-defined type
else if (auto t = function_type(n.get(), named))
{
Expand Down Expand Up @@ -6537,11 +6548,11 @@ class parser
)
{
auto& type = std::get<declaration_node::an_object>(n->type);
// object initialized by the address of the curr() object
// object initialized by the address of the curr() object
if (peek(1)->type() == lexeme::Ampersand) {
type->address_of = &curr();
}
// object initialized by (potentially multiple) dereference of the curr() object
// object initialized by (potentially multiple) dereference of the curr() object
else if (peek(1)->type() == lexeme::Multiply) {
type->dereference_of = &curr();
for (int i = 1; peek(i)->type() == lexeme::Multiply; ++i)
Expand Down Expand Up @@ -6746,7 +6757,7 @@ class parser
return {};
}
if (
t->is_wildcard()
t->is_wildcard()
|| ( t->get_token() && t->get_token()->to_string(true) == "auto" )
) {
errors.emplace_back(
Expand Down

0 comments on commit 90faa49

Please sign in to comment.