From 29ecb6e69d5051794f7c6f2fa16451a01314590e Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 20 Jun 2022 20:57:58 +0200 Subject: [PATCH 1/3] C++: remove unncessary cpp template edge case unsupported by modern cpp compilers Close #3388. Removes C++ template parsing code that was originally written to support C++03-specific template syntax. However, as described in #3388, this syntax is not actually valid C++03 syntax. Yet, the parsing code removed in this commit prevents correctly parsing non-primitive template function return types. --- parsers/cxx/cxx_parser_template.c | 36 ++++++------------------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/parsers/cxx/cxx_parser_template.c b/parsers/cxx/cxx_parser_template.c index 9e54dd379c..8c0589751c 100644 --- a/parsers/cxx/cxx_parser_template.c +++ b/parsers/cxx/cxx_parser_template.c @@ -269,7 +269,10 @@ cxxParserParseTemplateAngleBracketsInternal(bool bCaptureTypeParameters,int iNes // around but without proper state (include headers, macro expansion, full type // database etc) we simply can't do the same. However, we try to recover if we // figure out we (or the programmer?) screwed up. - // + // For 'greater-than' operators, the first non-nested operator is taken as the + // end of the template parameter list rather than a 'greater-than' operator. + // Treating non-nested operators differently is a syntax error at least since C++03 + // onwards according to https://en.cppreference.com/w/cpp/language/template_parameters. // // Like gcc, if this function knows identifiers in a template prefix more, // the quality of parsing becomes better. @@ -421,35 +424,8 @@ cxxParserParseTemplateAngleBracketsInternal(bool bCaptureTypeParameters,int iNes CXX_DEBUG_PRINT("Found %d greater-than signs",iGreaterThanCount); - // check greater than operator: very narrow conditions - if( - (iGreaterThanCount == 1) && - ( - // whatever op 2 [C++03 allows this without parens] - // whatever op (...) [C++03 allows this without parens] - cxxTokenTypeIsOneOf( - g_cxx.pToken, - CXXTokenTypeNumber | CXXTokenTypeOpeningParenthesis - ) || - // whatever op nonTypeParameter [C++03 allows this without parens] - ( - cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeIdentifier) && - cxxTokenIsPresentInTemplateParametersAsNonType(g_cxx.pToken) - ) - // WARNING: don't be tempted to add a loose condition that has - // (!cxxTokenIsPresentInTemplateParametersAsType()) on the right. - // It's unsafe. - ) - ) - { - CXX_DEBUG_PRINT("Treating as greater-than sign"); - - if(cxxTokenTypeIsOneOf(g_cxx.pToken,CXXTokenTypeOpeningParenthesis)) - cxxParserUngetCurrentToken(); // needs to be condensed - - continue; - } - + // We do not check for the greater than operator, as it is only valid + // inside parentheses in a template parameter list (see i#3388). // check right shift operator: a bit broader conditions if( From 0c762dee6704563ba13fc34992c80bf2b8535c5c Mon Sep 17 00:00:00 2001 From: Daniel Elsner Date: Fri, 24 Jun 2022 17:05:21 +0200 Subject: [PATCH 2/3] Units(C++): Add templates7.d for non-primitive return types in template functions --- Units/parser-cxx.r/templates7.d/args.ctags | 3 +++ Units/parser-cxx.r/templates7.d/expected.tags | 8 ++++++++ Units/parser-cxx.r/templates7.d/input.hpp | 11 +++++++++++ Units/parser-cxx.r/templates7.d/validator | 1 + 4 files changed, 23 insertions(+) create mode 100644 Units/parser-cxx.r/templates7.d/args.ctags create mode 100644 Units/parser-cxx.r/templates7.d/expected.tags create mode 100644 Units/parser-cxx.r/templates7.d/input.hpp create mode 100644 Units/parser-cxx.r/templates7.d/validator diff --git a/Units/parser-cxx.r/templates7.d/args.ctags b/Units/parser-cxx.r/templates7.d/args.ctags new file mode 100644 index 0000000000..6c1b352ae6 --- /dev/null +++ b/Units/parser-cxx.r/templates7.d/args.ctags @@ -0,0 +1,3 @@ +--sort=no +--kinds-C++=* +--fields-c++=+{template} \ No newline at end of file diff --git a/Units/parser-cxx.r/templates7.d/expected.tags b/Units/parser-cxx.r/templates7.d/expected.tags new file mode 100644 index 0000000000..bf3e16153d --- /dev/null +++ b/Units/parser-cxx.r/templates7.d/expected.tags @@ -0,0 +1,8 @@ +foo input.hpp /^A foo()$/;" f typeref:typename:A template: +A input.hpp /^template$/;" Z function:foo typeref:meta:typename +B input.hpp /^template$/;" Z function:foo typeref:meta:typename +bar input.hpp /^A& bar(A& a, const B& b)$/;" f typeref:typename:A & template: +A input.hpp /^template$/;" Z function:bar typeref:meta:typename +B input.hpp /^template$/;" Z function:bar typeref:meta:typename +a input.hpp /^A& bar(A& a, const B& b)$/;" z function:bar typeref:typename:A & file: +b input.hpp /^A& bar(A& a, const B& b)$/;" z function:bar typeref:typename:const B & file: diff --git a/Units/parser-cxx.r/templates7.d/input.hpp b/Units/parser-cxx.r/templates7.d/input.hpp new file mode 100644 index 0000000000..c5fcb8495e --- /dev/null +++ b/Units/parser-cxx.r/templates7.d/input.hpp @@ -0,0 +1,11 @@ +template +A foo() +{ + return A(); +} + +template +A& bar(A& a, const B& b) +{ + return a; +} \ No newline at end of file diff --git a/Units/parser-cxx.r/templates7.d/validator b/Units/parser-cxx.r/templates7.d/validator new file mode 100644 index 0000000000..30c863ebde --- /dev/null +++ b/Units/parser-cxx.r/templates7.d/validator @@ -0,0 +1 @@ +cxx11 From 7dd0cdfd140025d72ff45149c04e3929eba5d161 Mon Sep 17 00:00:00 2001 From: Daniel Elsner Date: Fri, 24 Jun 2022 17:26:36 +0200 Subject: [PATCH 3/3] Units(C++): Fix misleading comment in template-nested-triangle-brackets.d --- .../template-nested-triangle-brackets.d/input-2.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Units/parser-cxx.r/template-nested-triangle-brackets.d/input-2.hpp b/Units/parser-cxx.r/template-nested-triangle-brackets.d/input-2.hpp index cf6b134183..c2a6331583 100644 --- a/Units/parser-cxx.r/template-nested-triangle-brackets.d/input-2.hpp +++ b/Units/parser-cxx.r/template-nested-triangle-brackets.d/input-2.hpp @@ -16,7 +16,7 @@ template K funcC(T t) } // The original comment: This stuff is allowed by C++03 -// template> 2)> K funcD(T t) +// template> 2> K funcD(T t) // However, the above input is rejected with: // error: default template arguments may not be used in function templates // without `-std=c++11' or `-std=gnu++11'