Skip to content

Commit 6f337e8

Browse files
authored
Fix #13882 (TemplateSimplifier: argument integral type is not preserved) (danmar#7546)
1 parent 41feaae commit 6f337e8

File tree

3 files changed

+58
-20
lines changed

3 files changed

+58
-20
lines changed

lib/templatesimplifier.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,27 @@ void TemplateSimplifier::expandTemplate(
20972097
continue;
20982098
if (isVariadicTemplateArg && Token::Match(tok3, "%name% ... %name%"))
20992099
tok3 = tok3->tokAt(2);
2100+
if (!isVariadicTemplateArg && copy && Token::Match(mTypesUsedInTemplateInstantiation[itype].token(), "%num% ,|>|>>") &&
2101+
Token::Match(tok3->previous(), "%assign%|%cop%|( %name% %cop%|;|)")) {
2102+
const Token* declTok = typeParametersInDeclaration[itype];
2103+
while (Token::Match(declTok->previous(), "%name%|::|*"))
2104+
declTok = declTok->previous();
2105+
if (Token::Match(declTok->previous(), "[<,]")) {
2106+
const Token* typetok = mTypesUsedInTemplateInstantiation[itype].token();
2107+
mTokenList.addtoken("(", declTok);
2108+
Token* const par1 = mTokenList.back();
2109+
while (declTok != typeParametersInDeclaration[itype]) {
2110+
mTokenList.addtoken(declTok);
2111+
declTok = declTok->next();
2112+
}
2113+
mTokenList.addtoken(")", declTok);
2114+
Token::createMutualLinks(par1, mTokenList.back());
2115+
mTokenList.addtoken(typetok, tok3);
2116+
for (Token* t = par1; t; t = t->next())
2117+
t->isTemplateArg(true);
2118+
continue;
2119+
}
2120+
}
21002121
const std::string endStr(isVariadicTemplateArg ? ">" : ",>");
21012122
for (Token *typetok = mTypesUsedInTemplateInstantiation[itype].token();
21022123
typetok && (typeindentlevel > 0 || endStr.find(typetok->str()[0]) == std::string::npos);
@@ -2551,6 +2572,10 @@ void TemplateSimplifier::simplifyTemplateArgs(Token *start, const Token *end, st
25512572
again = true;
25522573
tok = tok->previous();
25532574
}
2575+
} else if (Token::Match(tok, "( %type% ) %num%")) {
2576+
tok = tok->previous();
2577+
again = true;
2578+
tok->deleteNext(3);
25542579
}
25552580
}
25562581

test/testsimplifytemplate.cpp

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ class TestSimplifyTemplate : public TestFixture {
311311

312312
TEST_CASE(explicitBool1);
313313
TEST_CASE(explicitBool2);
314+
315+
TEST_CASE(templateArgPreserveType); // #13882 - type of template argument
314316
}
315317

316318
struct CheckOptions
@@ -677,7 +679,7 @@ class TestSimplifyTemplate : public TestFixture {
677679
"vec<4> v ; "
678680
"struct vec<4> { "
679681
"vec<4> ( ) { } "
680-
"vec<4> ( const vec < 4 - 1 > & v ) { } "
682+
"vec<4> ( const vec < ( int ) 4 - 1 > & v ) { } "
681683
"} ;";
682684

683685
ASSERT_EQUALS(expected2, tok(code2));
@@ -1302,7 +1304,7 @@ class TestSimplifyTemplate : public TestFixture {
13021304
"int calculate_value<1,1> ( ) ; "
13031305
"int value ; value = calculate_value<1,1> ( ) ; "
13041306
"int calculate_value<1,1> ( ) { "
1305-
"if ( 1 != 1 ) { "
1307+
"if ( ( int ) 1 != ( int ) 1 ) { "
13061308
"return sum<0> ( ) ; "
13071309
"} else { "
13081310
"return 0 ; "
@@ -1332,16 +1334,16 @@ class TestSimplifyTemplate : public TestFixture {
13321334
"} ; "
13331335
"const int x = Factorial<4> :: value ; "
13341336
"struct Factorial<4> { "
1335-
"enum Anonymous0 { value = 4 * Factorial<3> :: value } ; "
1337+
"enum Anonymous0 { value = ( int ) 4 * Factorial<3> :: value } ; "
13361338
"} ; "
13371339
"struct Factorial<3> { "
1338-
"enum Anonymous0 { value = 3 * Factorial<2> :: value } ; "
1340+
"enum Anonymous0 { value = ( int ) 3 * Factorial<2> :: value } ; "
13391341
"} ; "
13401342
"struct Factorial<2> { "
1341-
"enum Anonymous0 { value = 2 * Factorial<1> :: value } ; "
1343+
"enum Anonymous0 { value = ( int ) 2 * Factorial<1> :: value } ; "
13421344
"} ; "
13431345
"struct Factorial<1> { "
1344-
"enum Anonymous0 { value = 1 * Factorial<0> :: value } ; "
1346+
"enum Anonymous0 { value = ( int ) 1 * Factorial<0> :: value } ; "
13451347
"} ;";
13461348
ASSERT_EQUALS(expected, tok(code, dinit(CheckOptions, $.debugwarnings = true)));
13471349
ASSERT_EQUALS("", errout_str());
@@ -1459,10 +1461,10 @@ class TestSimplifyTemplate : public TestFixture {
14591461
"int diagonalGroupTest<4> ( ) ; "
14601462
"int main ( ) { return diagonalGroupTest<4> ( ) ; } "
14611463
"int diagonalGroupTest<4> ( ) { return Factorial<4> :: value ; } "
1462-
"struct Factorial<4> { enum FacHelper { value = 4 * Factorial<3> :: value } ; } ; "
1463-
"struct Factorial<3> { enum FacHelper { value = 3 * Factorial<2> :: value } ; } ; "
1464-
"struct Factorial<2> { enum FacHelper { value = 2 * Factorial<1> :: value } ; } ; "
1465-
"struct Factorial<1> { enum FacHelper { value = 1 * Factorial<0> :: value } ; } ;";
1464+
"struct Factorial<4> { enum FacHelper { value = ( int ) 4 * Factorial<3> :: value } ; } ; "
1465+
"struct Factorial<3> { enum FacHelper { value = ( int ) 3 * Factorial<2> :: value } ; } ; "
1466+
"struct Factorial<2> { enum FacHelper { value = ( int ) 2 * Factorial<1> :: value } ; } ; "
1467+
"struct Factorial<1> { enum FacHelper { value = ( int ) 1 * Factorial<0> :: value } ; } ;";
14661468
ASSERT_EQUALS(exp, tok(code));
14671469
}
14681470

@@ -1558,11 +1560,11 @@ class TestSimplifyTemplate : public TestFixture {
15581560
"} ; "
15591561
"void A :: t_func<0> ( ) "
15601562
"{ "
1561-
"if ( 0 != 0 || foo<int> ( ) ) { ; } "
1563+
"if ( ( int ) 0 != 0 || foo<int> ( ) ) { ; } "
15621564
"} "
15631565
"void A :: t_func<1> ( ) "
15641566
"{ "
1565-
"if ( 1 != 0 || foo<int> ( ) ) { ; } "
1567+
"if ( ( int ) 1 != 0 || foo<int> ( ) ) { ; } "
15661568
"} "
15671569
"bool foo<int> ( ) { return true ; }";
15681570
ASSERT_EQUALS(exp, tok(code));
@@ -4765,15 +4767,15 @@ class TestSimplifyTemplate : public TestFixture {
47654767
" A<int,(int)2> a1;\n"
47664768
" A<int> a2;\n"
47674769
"}\n";
4768-
const char expected[] = "class A<int,(int)2> ; "
4770+
const char expected[] = "class A<int,2> ; "
47694771
"class A<int,3> ; "
47704772
"void f ( ) "
47714773
"{ "
4772-
"A<int,(int)2> a1 ; "
4774+
"A<int,2> a1 ; "
47734775
"A<int,3> a2 ; "
47744776
"} "
4775-
"class A<int,(int)2> "
4776-
"{ int ar [ ( int ) 2 ] ; } ; "
4777+
"class A<int,2> "
4778+
"{ int ar [ 2 ] ; } ; "
47774779
"class A<int,3> "
47784780
"{ int ar [ 3 ] ; } ;";
47794781
ASSERT_EQUALS(expected, tok(code));
@@ -6311,7 +6313,7 @@ class TestSimplifyTemplate : public TestFixture {
63116313
"}";
63126314
const char expected[] = "struct A<0> ; "
63136315
"void bar ( ) { A<0> :: foo ( ) ; } "
6314-
"struct A<0> { static void foo ( ) { int i ; i = 0 ; } } ;";
6316+
"struct A<0> { static void foo ( ) { int i ; i = ( int ) 0 ; } } ;";
63156317
ASSERT_EQUALS(expected, tok(code));
63166318
}
63176319

@@ -6586,6 +6588,17 @@ class TestSimplifyTemplate : public TestFixture {
65866588
const char code[] = "class Fred { explicit(false) Fred(int); };";
65876589
ASSERT_EQUALS("class Fred { Fred ( int ) ; } ;", tok(code));
65886590
}
6591+
6592+
void templateArgPreserveType() { // #13882 - type of template argument
6593+
const char code[] = "template <uint32_t x> class Test {\n"
6594+
" uint32_t i = x;\n"
6595+
"};\n"
6596+
"Test<64> test;\n";
6597+
ASSERT_EQUALS("class Test<64> ; "
6598+
"Test<64> test ; "
6599+
"class Test<64> { uint32_t i ; i = ( uint32_t ) 64 ; } ;",
6600+
tok(code));
6601+
}
65896602
};
65906603

65916604
REGISTER_TEST(TestSimplifyTemplate)

test/testtokenize.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4211,11 +4211,11 @@ class TestTokenizer : public TestFixture {
42114211
"struct S\n"
42124212
"{};\n"
42134213
"S<int> s;\n";
4214-
ASSERT_EQUALS("struct S<int,(int)0> ;\n"
4214+
ASSERT_EQUALS("struct S<int,0> ;\n"
42154215
"\n"
42164216
"\n"
4217-
"S<int,(int)0> s ;\n"
4218-
"struct S<int,(int)0>\n"
4217+
"S<int,0> s ;\n"
4218+
"struct S<int,0>\n"
42194219
"{ } ;",
42204220
tokenizeAndStringify(code));
42214221
}

0 commit comments

Comments
 (0)