From 706ebc8e33859c30aa5b71d5006d195b0aa736ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Fri, 11 Aug 2023 00:30:56 -0400 Subject: [PATCH] fix(parse): recognize const and pointer template arguments (#521) * fix(parse): recognize const and pointer template arguments * Minor: Massage the new code's format and comment Signed-off-by: Herb Sutter * Update parse.h Signed-off-by: Herb Sutter --------- Signed-off-by: Herb Sutter Co-authored-by: Herb Sutter --- .../pure2-bugfix-for-template-argument.cpp2 | 3 +++ ...bugfix-for-template-argument.cpp.execution | 0 ...e2-bugfix-for-template-argument.cpp.output | 0 .../pure2-bugfix-for-template-argument.cpp | 23 +++++++++++++++++++ ...2-bugfix-for-template-argument.cpp2.output | 2 ++ source/parse.h | 21 +++++++++++++++-- 6 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 regression-tests/pure2-bugfix-for-template-argument.cpp2 create mode 100644 regression-tests/test-results/gcc-13/pure2-bugfix-for-template-argument.cpp.execution create mode 100644 regression-tests/test-results/gcc-13/pure2-bugfix-for-template-argument.cpp.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-template-argument.cpp create mode 100644 regression-tests/test-results/pure2-bugfix-for-template-argument.cpp2.output diff --git a/regression-tests/pure2-bugfix-for-template-argument.cpp2 b/regression-tests/pure2-bugfix-for-template-argument.cpp2 new file mode 100644 index 000000000..823e64137 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-template-argument.cpp2 @@ -0,0 +1,3 @@ +main: () = // + std::is_void_v<* i32> // + && std::is_void_v; diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-template-argument.cpp.execution b/regression-tests/test-results/gcc-13/pure2-bugfix-for-template-argument.cpp.execution new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-template-argument.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-template-argument.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/pure2-bugfix-for-template-argument.cpp b/regression-tests/test-results/pure2-bugfix-for-template-argument.cpp new file mode 100644 index 000000000..e0218aa23 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-template-argument.cpp @@ -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 // + && std::is_void_v; } + diff --git a/regression-tests/test-results/pure2-bugfix-for-template-argument.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-template-argument.cpp2.output new file mode 100644 index 000000000..f25ea8720 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-template-argument.cpp2.output @@ -0,0 +1,2 @@ +pure2-bugfix-for-template-argument.cpp2... ok (all Cpp2, passes safety checks) + diff --git a/source/parse.h b/source/parse.h index 7f54dddfa..72e3afe91 100644 --- a/source/parse.h +++ b/source/parse.h @@ -4822,6 +4822,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 @@ -4855,16 +4856,32 @@ class parser auto term = unqualified_id_node::term{}; do { - // disallow unparenthesized relational comparisons in template args - if (auto e = expression(false)) { + // If it doesn't start with * or const (which can only be a type id), + // try parsing it as an expression + if (auto e = [&]{ + if ( + curr().type() == lexeme::Multiply // '*' + || curr() == "const" // 'const' + ) + { + return decltype(expression()){}; + } + return expression(false); // false == disallow unparenthesized relational comparisons in template args + }() + ) + { term.arg = std::move(e); } + + // Else try parsing it as a type id else if (auto i = type_id()) { term.arg = std::move(i); } + else { break; } + n->template_args.push_back( std::move(term) ); } // Use the lambda trick to jam in a "next" clause