Fixed #9005 (Syntax error on valid C++) (#1716)

This commit is contained in:
IOBYTE 2019-03-01 02:18:53 -05:00 committed by Daniel Marjamäki
parent f4b5b156d7
commit b78b3c6ab1
2 changed files with 44 additions and 6 deletions

View File

@ -838,7 +838,10 @@ void TemplateSimplifier::getTemplateInstantiations()
break;
if (scopeName.empty()) {
mTemplateInstantiations.emplace_back(tok, getScopeName(scopeList));
if (!qualification.empty())
mTemplateInstantiations.emplace_back(tok, qualification);
else
mTemplateInstantiations.emplace_back(tok, getScopeName(scopeList));
break;
}
const std::string::size_type pos = scopeName.rfind(" :: ");
@ -2178,11 +2181,15 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
continue;
if (instantiation.fullName != templateDeclaration.fullName) {
// FIXME: fallback to not matching scopes until type deduction work
// FIXME: fallback to not matching scopes until type deduction works
// names must match
if (instantiation.name != templateDeclaration.name)
continue;
// scopes must match when present
if (!instantiation.scope.empty() && !templateDeclaration.scope.empty())
continue;
}
if (!matchSpecialization(templateDeclaration.nameToken, instantiation.token, specializations))

View File

@ -119,8 +119,8 @@ private:
TEST_CASE(template79); // #5133
TEST_CASE(template80);
TEST_CASE(template81);
TEST_CASE(template82); // 8603
TEST_CASE(template83);
TEST_CASE(template82); // #8603
TEST_CASE(template83); // #8867
TEST_CASE(template84); // #8880
TEST_CASE(template85); // #8902 crash
TEST_CASE(template86); // crash
@ -139,6 +139,7 @@ private:
TEST_CASE(template99); // #8960
TEST_CASE(template100); // #8967
TEST_CASE(template101); // #8968
TEST_CASE(template102); // #9005
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
@ -1783,13 +1784,21 @@ private:
ASSERT_EQUALS(exp, tok(code));
}
void template83() {
void template83() { // #8867
const char code[] = "template<typename Task>\n"
"class MultiConsumer {\n"
" MultiConsumer();\n"
"};\n"
"template<typename Task>\n"
"MultiConsumer<Task>::MultiConsumer() : sizeBuffer(0) {}\n"
"MultiReads::MultiReads() {\n"
" mc = new MultiConsumer<reads_packet>();\n"
"}";
const char exp[] = "MultiConsumer<reads_packet> :: MultiConsumer<reads_packet> ( ) ; "
const char exp[] = "template < typename Task > " // TODO: this should be expanded
"class MultiConsumer { "
"MultiConsumer ( ) ; "
"} ; "
"MultiConsumer<reads_packet> :: MultiConsumer<reads_packet> ( ) ; "
"MultiReads :: MultiReads ( ) { "
"mc = new MultiConsumer<reads_packet> ( ) ; "
"} "
@ -2303,6 +2312,28 @@ private:
ASSERT_EQUALS("", errout.str());
}
void template102() { // #9005
const char code[] = "namespace ns {\n"
"template <class T>\n"
"struct is_floating_point \n"
": std::integral_constant<bool, std::is_floating_point<T>::value || true>\n"
"{};\n"
"}\n"
"void f() {\n"
" if(std::is_floating_point<float>::value) {}\n"
"}";
const char exp[] = "namespace ns { "
"template < class T > "
"struct is_floating_point "
": std :: integral_constant < bool , std :: is_floating_point < T > :: value || true > "
"{ } ; "
"} "
"void f ( ) { "
"if ( std :: is_floating_point < float > :: value ) { } "
"}";
ASSERT_EQUALS(exp, tok(code));
}
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
const char code[] = "template <typename T> struct C {};\n"
"template <typename T> struct S {a};\n"