Tokenizer: Improve handling of block declarations (C extension)
This commit is contained in:
parent
036306d7c2
commit
b748453b30
|
@ -9295,18 +9295,26 @@ void Tokenizer::simplifyAsm()
|
||||||
|
|
||||||
void Tokenizer::simplifyAsm2()
|
void Tokenizer::simplifyAsm2()
|
||||||
{
|
{
|
||||||
|
// Block declarations: ^{}
|
||||||
|
// A C extension used to create lambda like closures.
|
||||||
|
|
||||||
// Put ^{} statements in asm()
|
// Put ^{} statements in asm()
|
||||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||||
if (Token::simpleMatch(tok, "^ {")) {
|
if (tok->str() != "^")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Token::simpleMatch(tok, "^ {") || Token::simpleMatch(tok->linkAt(1), ") {")) {
|
||||||
Token * start = tok;
|
Token * start = tok;
|
||||||
while (start && !Token::Match(start, "[;{}=]")) {
|
while (start && !Token::Match(start, "[;{}=]")) {
|
||||||
if (start->link() && start->str() == ")")
|
if (start->link() && Token::Match(start, ")|]|>"))
|
||||||
start = start->link();
|
start = start->link();
|
||||||
start = start->previous();
|
start = start->previous();
|
||||||
}
|
}
|
||||||
if (start)
|
if (start)
|
||||||
start = start->next();
|
start = start->next();
|
||||||
const Token *last = tok->next()->link();
|
const Token *last = tok->next()->link();
|
||||||
|
if (Token::simpleMatch(last, ") {"))
|
||||||
|
last = last->linkAt(1);
|
||||||
if (start != tok) {
|
if (start != tok) {
|
||||||
last = last->next();
|
last = last->next();
|
||||||
while (last && !Token::Match(last, "[;{})]")) {
|
while (last && !Token::Match(last, "[;{})]")) {
|
||||||
|
@ -9337,9 +9345,9 @@ void Tokenizer::simplifyAsm2()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the assembly code has been cleaned up, no @ is allowed
|
// When the assembly code has been cleaned up, no @ is allowed
|
||||||
for (const Token *tok = list.front(); tok; tok = tok->next()) {
|
for (const Token *tok = list.front(); tok; tok = tok->next()) {
|
||||||
assert(list.validateToken(tok)); // see #7185 "crash: Tokenizer::simplifyAsm2 on invalid code"
|
|
||||||
if (tok->str() == "(") {
|
if (tok->str() == "(") {
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
if (!tok)
|
if (!tok)
|
||||||
|
|
|
@ -63,7 +63,6 @@ private:
|
||||||
TEST_CASE(tokenize25); // #4239 (segmentation fault)
|
TEST_CASE(tokenize25); // #4239 (segmentation fault)
|
||||||
TEST_CASE(tokenize26); // #4245 (segmentation fault)
|
TEST_CASE(tokenize26); // #4245 (segmentation fault)
|
||||||
TEST_CASE(tokenize27); // #4525 (segmentation fault)
|
TEST_CASE(tokenize27); // #4525 (segmentation fault)
|
||||||
TEST_CASE(tokenize28); // #4725 (writing asm() around "^{}")
|
|
||||||
TEST_CASE(tokenize31); // #3503 (Wrong handling of member function taking function pointer as argument)
|
TEST_CASE(tokenize31); // #3503 (Wrong handling of member function taking function pointer as argument)
|
||||||
TEST_CASE(tokenize32); // #5884 (fsanitize=undefined: left shift of negative value -10000 in lib/templatesimplifier.cpp:852:46)
|
TEST_CASE(tokenize32); // #5884 (fsanitize=undefined: left shift of negative value -10000 in lib/templatesimplifier.cpp:852:46)
|
||||||
TEST_CASE(tokenize33); // #5780 Various crashes on valid template code
|
TEST_CASE(tokenize33); // #5780 Various crashes on valid template code
|
||||||
|
@ -97,6 +96,7 @@ private:
|
||||||
TEST_CASE(removeCast17); // #6110 - don't remove any parentheses in 'a(b)(c)'
|
TEST_CASE(removeCast17); // #6110 - don't remove any parentheses in 'a(b)(c)'
|
||||||
|
|
||||||
TEST_CASE(inlineasm);
|
TEST_CASE(inlineasm);
|
||||||
|
TEST_CASE(simplifyAsm2); // #4725 (writing asm() around "^{}")
|
||||||
|
|
||||||
TEST_CASE(ifAddBraces1);
|
TEST_CASE(ifAddBraces1);
|
||||||
TEST_CASE(ifAddBraces2);
|
TEST_CASE(ifAddBraces2);
|
||||||
|
@ -769,31 +769,6 @@ private:
|
||||||
tokenizeAndStringify("static unsigned int re_string_context_at (const re_string_t *input, int idx, int eflags) internal_function __attribute__ ((pure));");
|
tokenizeAndStringify("static unsigned int re_string_context_at (const re_string_t *input, int idx, int eflags) internal_function __attribute__ ((pure));");
|
||||||
}
|
}
|
||||||
|
|
||||||
// #4725 - ^{}
|
|
||||||
void tokenize28() {
|
|
||||||
ASSERT_EQUALS("void f ( ) { asm ( \"^{}\" ) ; }", tokenizeAndStringify("void f() { ^{} }"));
|
|
||||||
ASSERT_EQUALS("void f ( ) { asm ( \"x(^{});\" ) ; }", tokenizeAndStringify("void f() { x(^{}); }"));
|
|
||||||
ASSERT_EQUALS("void f ( ) { asm ( \"foo(A(),^{bar();});\" ) ; }", tokenizeAndStringify("void f() { foo(A(), ^{ bar(); }); }"));
|
|
||||||
ASSERT_EQUALS("int f0 ( Args args ) {\n"
|
|
||||||
"asm ( \"return^{returnsizeof...(Args);}()+\" ) ;\n"
|
|
||||||
"\n"
|
|
||||||
"asm ( \"^{returnsizeof...(args);}\" ) ;\n"
|
|
||||||
"\n"
|
|
||||||
"\n"
|
|
||||||
"} ;", tokenizeAndStringify("int f0(Args args) {\n"
|
|
||||||
" return ^{\n"
|
|
||||||
" return sizeof...(Args);\n"
|
|
||||||
" }() + ^ {\n"
|
|
||||||
" return sizeof...(args);\n"
|
|
||||||
" }();\n"
|
|
||||||
"};"));
|
|
||||||
ASSERT_EQUALS("int ( ^ block ) ( void ) = asm ( \"^{staticinttest=0;returntest;}\" ) ;",
|
|
||||||
tokenizeAndStringify("int(^block)(void) = ^{\n"
|
|
||||||
" static int test = 0;\n"
|
|
||||||
" return test;\n"
|
|
||||||
"};"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// #3503 - don't "simplify" SetFunction member function to a variable
|
// #3503 - don't "simplify" SetFunction member function to a variable
|
||||||
void tokenize31() {
|
void tokenize31() {
|
||||||
ASSERT_EQUALS("struct TTestClass { TTestClass ( ) { }\n"
|
ASSERT_EQUALS("struct TTestClass { TTestClass ( ) { }\n"
|
||||||
|
@ -1021,6 +996,36 @@ private:
|
||||||
ASSERT_EQUALS(";\n\nasm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";\n\n__asm__ volatile ( \"mov ax,bx\" );", true));
|
ASSERT_EQUALS(";\n\nasm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";\n\n__asm__ volatile ( \"mov ax,bx\" );", true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #4725 - ^{}
|
||||||
|
void simplifyAsm2() {
|
||||||
|
ASSERT_EQUALS("void f ( ) { asm ( \"^{}\" ) ; }", tokenizeAndStringify("void f() { ^{} }"));
|
||||||
|
ASSERT_EQUALS("void f ( ) { asm ( \"x(^{});\" ) ; }", tokenizeAndStringify("void f() { x(^{}); }"));
|
||||||
|
ASSERT_EQUALS("void f ( ) { asm ( \"foo(A(),^{bar();});\" ) ; }", tokenizeAndStringify("void f() { foo(A(), ^{ bar(); }); }"));
|
||||||
|
ASSERT_EQUALS("int f0 ( Args args ) {\n"
|
||||||
|
"asm ( \"return^{returnsizeof...(Args);}()+\" ) ;\n"
|
||||||
|
"\n"
|
||||||
|
"asm ( \"^{returnsizeof...(args);}\" ) ;\n"
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
"} ;", tokenizeAndStringify("int f0(Args args) {\n"
|
||||||
|
" return ^{\n"
|
||||||
|
" return sizeof...(Args);\n"
|
||||||
|
" }() + ^ {\n"
|
||||||
|
" return sizeof...(args);\n"
|
||||||
|
" }();\n"
|
||||||
|
"};"));
|
||||||
|
ASSERT_EQUALS("int ( ^ block ) ( void ) = asm ( \"^{staticinttest=0;returntest;}\" ) ;",
|
||||||
|
tokenizeAndStringify("int(^block)(void) = ^{\n"
|
||||||
|
" static int test = 0;\n"
|
||||||
|
" return test;\n"
|
||||||
|
"};"));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("; asm ( \"returnf([=]().int^{});\" ) ;",
|
||||||
|
tokenizeAndStringify("; return f([=]() -> int^{});")); // #7185 - garbage
|
||||||
|
ASSERT_EQUALS("; asm ( \"returnf(^(void){somecode});\" ) ;",
|
||||||
|
tokenizeAndStringify("; return f(^(void){somecode});"));
|
||||||
|
}
|
||||||
|
|
||||||
void ifAddBraces1() {
|
void ifAddBraces1() {
|
||||||
const char code[] = "void f()\n"
|
const char code[] = "void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue