template simplifier: add links to expanded return type in function forward declaration (#1868)

This crash was seen in daca capnproto but I could only get creduce to
generate garbage code so the test is in checkgarbage.
This commit is contained in:
IOBYTE 2019-06-03 01:06:04 -04:00 committed by Daniel Marjamäki
parent 7ca35d181b
commit 41cf865947
2 changed files with 26 additions and 4 deletions

View File

@ -1560,6 +1560,7 @@ void TemplateSimplifier::expandTemplate(
if (itype < typeParametersInDeclaration.size() &&
(!isVariable || !Token::Match(typeParametersInDeclaration[itype]->previous(), "<|, %type% >|,"))) {
typeindentlevel = 0;
std::stack<Token *> brackets1; // holds "(" and "{" tokens
for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype].token;
typetok && (typeindentlevel > 0 || !Token::Match(typetok, ",|>"));
typetok = typetok->next()) {
@ -1572,10 +1573,26 @@ void TemplateSimplifier::expandTemplate(
else if (typeindentlevel > 0 && typetok->str() == ">")
--typeindentlevel;
dst->insertToken(typetok->str(), typetok->originalName(), true);
dst->previous()->isTemplateArg(true);
dst->previous()->isSigned(typetok->isSigned());
dst->previous()->isUnsigned(typetok->isUnsigned());
dst->previous()->isLong(typetok->isLong());
Token *previous = dst->previous();
previous->isTemplateArg(true);
previous->isSigned(typetok->isSigned());
previous->isUnsigned(typetok->isUnsigned());
previous->isLong(typetok->isLong());
if (previous->str() == "{") {
brackets1.push(previous);
} else if (previous->str() == "(") {
brackets1.push(previous);
} else if (previous->str() == "}") {
assert(brackets1.empty() == false);
assert(brackets1.top()->str() == "{");
Token::createMutualLinks(brackets1.top(), previous);
brackets1.pop();
} else if (previous->str() == ")") {
assert(brackets1.empty() == false);
assert(brackets1.top()->str() == "(");
Token::createMutualLinks(brackets1.top(), previous);
brackets1.pop();
}
}
} else {
if (isSpecialization && !copy && !scope.empty() && Token::Match(start, (scope + templateDeclarationNameToken->str()).c_str())) {

View File

@ -234,6 +234,7 @@ private:
TEST_CASE(garbageCode201); // #8873
TEST_CASE(garbageCode202); // #8907
TEST_CASE(garbageCode203); // #8972
TEST_CASE(garbageCode204);
TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1
@ -1593,6 +1594,10 @@ private:
ASSERT_THROW(checkCode("{ template <a> class b { } template <> template <c> c() b<a>::e() { } template b<d>; }"), InternalError);
}
void garbageCode204() {
checkCode("template <a, = b<>()> c; template <a> a as() {} as<c<>>();");
}
void syntaxErrorFirstToken() {
ASSERT_THROW(checkCode("&operator(){[]};"), InternalError); // #7818
ASSERT_THROW(checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }"), InternalError); // #6858