/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2013 Daniel Marjamäki and Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "testsuite.h"
#include "tokenize.h"
#include "token.h"
#include "settings.h"
#include "templatesimplifier.h"
#include "path.h"
#include
#include
extern std::ostringstream errout;
class TestSimplifyTokens : public TestFixture {
public:
TestSimplifyTokens() : TestFixture("TestSimplifyTokens") {
}
private:
void run() {
// Make sure the Tokenizer::simplifyTokenList works.
// The order of the simplifications is important. So this test
// case shall make sure the simplifications are done in the
// correct order
TEST_CASE(simplifyTokenList1);
TEST_CASE(cast);
TEST_CASE(iftruefalse);
TEST_CASE(combine_strings);
TEST_CASE(double_plus);
TEST_CASE(redundant_plus);
TEST_CASE(redundant_plus_numbers);
TEST_CASE(parentheses1);
TEST_CASE(parenthesesVar); // Remove redundant parentheses around variable .. "( %var% )"
TEST_CASE(declareVar);
TEST_CASE(declareArray);
TEST_CASE(dontRemoveIncrement);
TEST_CASE(removePostIncrement);
TEST_CASE(removePreIncrement);
TEST_CASE(elseif1);
TEST_CASE(ifa_ifa); // "if (a) { if (a) .." => "if (a) { if (1) .."
TEST_CASE(sizeof2);
TEST_CASE(sizeof3);
TEST_CASE(sizeof4);
TEST_CASE(sizeof5);
TEST_CASE(sizeof6);
TEST_CASE(sizeof7);
TEST_CASE(sizeof8);
TEST_CASE(sizeof9);
TEST_CASE(sizeof10);
TEST_CASE(sizeof11);
TEST_CASE(sizeof12);
TEST_CASE(sizeof13);
TEST_CASE(sizeof14);
TEST_CASE(sizeof15);
TEST_CASE(sizeof16);
TEST_CASE(sizeof17);
TEST_CASE(sizeof18);
TEST_CASE(sizeof19); // #1891 - sizeof 'x'
TEST_CASE(sizeof20); // #2024 - sizeof a)
TEST_CASE(sizeof21); // #2232 - sizeof...(Args)
TEST_CASE(sizeof22); // #2599
TEST_CASE(sizeof23); // #2604
TEST_CASE(sizeofsizeof);
TEST_CASE(casting);
TEST_CASE(strlen1);
TEST_CASE(strlen2);
TEST_CASE(template1);
TEST_CASE(template2);
TEST_CASE(template3);
TEST_CASE(template4);
TEST_CASE(template5);
TEST_CASE(template6);
TEST_CASE(template7);
TEST_CASE(template8);
TEST_CASE(template9);
TEST_CASE(template10);
TEST_CASE(template11);
TEST_CASE(template12);
TEST_CASE(template13);
TEST_CASE(template14);
TEST_CASE(template15);
TEST_CASE(template16);
TEST_CASE(template17);
TEST_CASE(template18);
TEST_CASE(template19);
TEST_CASE(template20);
TEST_CASE(template21);
TEST_CASE(template22);
TEST_CASE(template23);
TEST_CASE(template24); // #2648 - using sizeof in template parameter
TEST_CASE(template25); // #2648 - another test for sizeof template parameter
TEST_CASE(template26); // #2721 - passing 'char[2]' as template parameter
TEST_CASE(template27); // #3350 - removing unused template in macro call
TEST_CASE(template28);
TEST_CASE(template29); // #3449 - don't crash for garbage code
TEST_CASE(template30); // #3529 - template < template < ..
TEST_CASE(template31); // #4010 - reference type
TEST_CASE(template32); // #3818 - mismatching template not handled well
TEST_CASE(template33); // #3818,#4544 - inner templates in template instantiation not handled well
TEST_CASE(template34); // #3706 - namespace => hang
TEST_CASE(template35); // #4074 - A<'x'> a;
TEST_CASE(template36); // #4310 - passing unknown template instantiation as template argument
TEST_CASE(template37); // #4544 - A a;
TEST_CASE(template38); // #4832 - crash on C++11 right angle brackets
TEST_CASE(template39); // #4742 - freeze
TEST_CASE(template40); // #5055 - template specialization outside struct
TEST_CASE(template41); // #4710 - const in instantiation not handled perfectly
TEST_CASE(template42); // #4878 - variadic templates
TEST_CASE(template_unhandled);
TEST_CASE(template_default_parameter);
TEST_CASE(template_default_type);
TEST_CASE(template_typename);
TEST_CASE(template_constructor); // #3152 - template constructor is removed
// Test TemplateSimplifier::templateParameters
TEST_CASE(templateParameters);
TEST_CASE(templateParameters1); // #4169 - segmentation fault
TEST_CASE(namespaces);
// Assignment in condition..
TEST_CASE(ifassign1);
TEST_CASE(ifAssignWithCast);
TEST_CASE(whileAssign1);
TEST_CASE(whileAssign2);
TEST_CASE(whileAssign3); // varid
TEST_CASE(doWhileAssign); // varid
TEST_CASE(test_4881); // similar to doWhileAssign (#4911), taken from #4881 with full code
// "if(0==x)" => "if(!x)"
TEST_CASE(ifnot);
TEST_CASE(combine_wstrings);
// Simplify "not" to "!" (#345)
TEST_CASE(not1);
// Simplify "and" to "&&" (#620)
TEST_CASE(and1);
// Simplify "or" to "||"
TEST_CASE(or1);
TEST_CASE(comma_keyword);
TEST_CASE(remove_comma);
// Simplify "?:"
TEST_CASE(simplifyConditionOperator);
// Simplify calculations
TEST_CASE(calculations);
TEST_CASE(comparisons);
// Simplify goto..
TEST_CASE(goto1);
TEST_CASE(goto2);
TEST_CASE(goto3); // #3138
TEST_CASE(goto4); // #3459
TEST_CASE(goto5); // #3705 - return ({asm("");});
TEST_CASE(goto6);
//remove dead code after flow control statements
TEST_CASE(flowControl);
// Simplify nested strcat() calls
TEST_CASE(strcat1);
TEST_CASE(strcat2);
TEST_CASE(simplifyAtol)
TEST_CASE(simplifyTypedef1)
TEST_CASE(simplifyTypedef2)
TEST_CASE(simplifyTypedef3)
TEST_CASE(simplifyTypedef4)
TEST_CASE(simplifyTypedef5)
TEST_CASE(simplifyTypedef6)
TEST_CASE(simplifyTypedef7);
TEST_CASE(simplifyTypedef8);
TEST_CASE(simplifyTypedef9);
TEST_CASE(simplifyTypedef10);
TEST_CASE(simplifyTypedef11);
TEST_CASE(simplifyTypedef12);
TEST_CASE(simplifyTypedef13);
TEST_CASE(simplifyTypedef14);
TEST_CASE(simplifyTypedef15);
TEST_CASE(simplifyTypedef16);
TEST_CASE(simplifyTypedef17);
TEST_CASE(simplifyTypedef18); // typedef vector a;
TEST_CASE(simplifyTypedef19);
TEST_CASE(simplifyTypedef20);
TEST_CASE(simplifyTypedef21);
TEST_CASE(simplifyTypedef22);
TEST_CASE(simplifyTypedef23);
TEST_CASE(simplifyTypedef24);
TEST_CASE(simplifyTypedef25);
TEST_CASE(simplifyTypedef26);
TEST_CASE(simplifyTypedef27);
TEST_CASE(simplifyTypedef28);
TEST_CASE(simplifyTypedef29);
TEST_CASE(simplifyTypedef30);
TEST_CASE(simplifyTypedef31);
TEST_CASE(simplifyTypedef32);
TEST_CASE(simplifyTypedef33);
TEST_CASE(simplifyTypedef34); // ticket #1411
TEST_CASE(simplifyTypedef35);
TEST_CASE(simplifyTypedef36); // ticket #1434
TEST_CASE(simplifyTypedef37); // ticket #1449
TEST_CASE(simplifyTypedef38);
TEST_CASE(simplifyTypedef39);
TEST_CASE(simplifyTypedef40);
TEST_CASE(simplifyTypedef41); // ticket #1488
TEST_CASE(simplifyTypedef42); // ticket #1506
TEST_CASE(simplifyTypedef43); // ticket #1588
TEST_CASE(simplifyTypedef44);
TEST_CASE(simplifyTypedef45); // ticket #1613
TEST_CASE(simplifyTypedef46);
TEST_CASE(simplifyTypedef47);
TEST_CASE(simplifyTypedef48); // ticket #1673
TEST_CASE(simplifyTypedef49); // ticket #1691
TEST_CASE(simplifyTypedef50);
TEST_CASE(simplifyTypedef51);
TEST_CASE(simplifyTypedef52); // ticket #1782
TEST_CASE(simplifyTypedef53); // ticket #1801
TEST_CASE(simplifyTypedef54); // ticket #1814
TEST_CASE(simplifyTypedef55);
TEST_CASE(simplifyTypedef56); // ticket #1829
TEST_CASE(simplifyTypedef57); // ticket #1846
TEST_CASE(simplifyTypedef58); // ticket #1963
TEST_CASE(simplifyTypedef59); // ticket #2011
TEST_CASE(simplifyTypedef60); // ticket #2035
TEST_CASE(simplifyTypedef61); // ticket #2074 and 2075
TEST_CASE(simplifyTypedef62); // ticket #2082
TEST_CASE(simplifyTypedef63); // ticket #2175 'typedef float x[3];'
TEST_CASE(simplifyTypedef64);
TEST_CASE(simplifyTypedef65); // ticket #2314
TEST_CASE(simplifyTypedef66); // ticket #2341
TEST_CASE(simplifyTypedef67); // ticket #2354
TEST_CASE(simplifyTypedef68); // ticket #2355
TEST_CASE(simplifyTypedef69); // ticket #2348
TEST_CASE(simplifyTypedef70); // ticket #2348
TEST_CASE(simplifyTypedef71); // ticket #2348
TEST_CASE(simplifyTypedef72); // ticket #2375
TEST_CASE(simplifyTypedef73); // ticket #2412
TEST_CASE(simplifyTypedef74); // ticket #2414
TEST_CASE(simplifyTypedef75); // ticket #2426
TEST_CASE(simplifyTypedef76); // ticket #2453
TEST_CASE(simplifyTypedef77); // ticket #2554
TEST_CASE(simplifyTypedef78); // ticket #2568
TEST_CASE(simplifyTypedef79); // ticket #2348
TEST_CASE(simplifyTypedef80); // ticket #2587
TEST_CASE(simplifyTypedef81); // ticket #2603
TEST_CASE(simplifyTypedef82); // ticket #2403
TEST_CASE(simplifyTypedef83); // ticket #2620
TEST_CASE(simplifyTypedef84); // ticket #2630
TEST_CASE(simplifyTypedef85); // ticket #2651
TEST_CASE(simplifyTypedef86); // ticket #2581
TEST_CASE(simplifyTypedef87); // ticket #2651
TEST_CASE(simplifyTypedef88); // ticket #2675
TEST_CASE(simplifyTypedef89); // ticket #2717
TEST_CASE(simplifyTypedef90); // ticket #2718
TEST_CASE(simplifyTypedef91); // ticket #2716
TEST_CASE(simplifyTypedef92); // ticket #2736
TEST_CASE(simplifyTypedef93); // ticket #2738
TEST_CASE(simplifyTypedef94); // ticket #1982
TEST_CASE(simplifyTypedef95); // ticket #2844
TEST_CASE(simplifyTypedef96); // ticket #2886
TEST_CASE(simplifyTypedef97); // ticket #2983 (segmentation fault)
TEST_CASE(simplifyTypedef98); // ticket #2963
TEST_CASE(simplifyTypedef99); // ticket #2999
TEST_CASE(simplifyTypedef100); // ticket #3000
TEST_CASE(simplifyTypedef101); // ticket #3003 (segmentation fault)
TEST_CASE(simplifyTypedef102); // ticket #3004
TEST_CASE(simplifyTypedef103); // ticket #3007
TEST_CASE(simplifyTypedef104); // ticket #3070
TEST_CASE(simplifyTypedef105); // ticket #3616
TEST_CASE(simplifyTypedef106); // ticket #3619
TEST_CASE(simplifyTypedef107); // ticket #3963 - bad code => segmentation fault
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
TEST_CASE(simplifyTypedefFunction3);
TEST_CASE(simplifyTypedefFunction4);
TEST_CASE(simplifyTypedefFunction5);
TEST_CASE(simplifyTypedefFunction6);
TEST_CASE(simplifyTypedefFunction7);
TEST_CASE(simplifyTypedefFunction8);
TEST_CASE(simplifyTypedefShadow); // #4445 - shadow variable
TEST_CASE(simplifyOperator1);
TEST_CASE(reverseArraySyntax)
TEST_CASE(simplify_numeric_condition)
TEST_CASE(simplify_condition);
TEST_CASE(pointeralias1);
TEST_CASE(pointeralias2);
TEST_CASE(pointeralias3);
TEST_CASE(pointeralias4);
TEST_CASE(pointeralias5);
TEST_CASE(reduceConstness);
// simplify "while (0)"
TEST_CASE(while0);
// ticket #3140
TEST_CASE(while0for);
TEST_CASE(while1);
TEST_CASE(enum1);
TEST_CASE(enum2);
TEST_CASE(enum3);
TEST_CASE(enum4);
TEST_CASE(enum5);
TEST_CASE(enum6);
TEST_CASE(enum7);
TEST_CASE(enum8);
TEST_CASE(enum9); // ticket 1404
TEST_CASE(enum10); // ticket 1445
TEST_CASE(enum11);
TEST_CASE(enum12);
TEST_CASE(enum13);
TEST_CASE(enum14);
TEST_CASE(enum15);
TEST_CASE(enum16); // ticket #1988
TEST_CASE(enum17); // ticket #2381 (duplicate enums)
TEST_CASE(enum18); // #2466 (array with same name as enum constant)
TEST_CASE(enum19); // ticket #2536
TEST_CASE(enum20); // ticket #2600
TEST_CASE(enum21); // ticket #2720
TEST_CASE(enum22); // ticket #2745
TEST_CASE(enum23); // ticket #2804
TEST_CASE(enum24); // ticket #2828
TEST_CASE(enum25); // ticket #2966
TEST_CASE(enum26); // ticket #2975 (segmentation fault)
TEST_CASE(enum27); // ticket #3005 (segmentation fault)
TEST_CASE(enum28);
TEST_CASE(enum29); // ticket #3747 (bitwise or value)
TEST_CASE(enum30); // ticket #3852 (false positive)
TEST_CASE(enum31); // ticket #3934 (calculation in first item)
TEST_CASE(enum32); // ticket #3998 (access violation)
TEST_CASE(enum33); // ticket #4015 (segmentation fault)
TEST_CASE(enum34); // ticket #4141 (division by zero)
TEST_CASE(enum35); // ticket #3953 (avoid simplification of type)
TEST_CASE(enum36); // ticket #4378
TEST_CASE(enum37); // ticket #4280 (shadow variable)
TEST_CASE(enum38); // ticket #4463 (when throwing enum id, don't warn about shadow variable)
TEST_CASE(enum39); // ticket #5145 (fp variable hides enum)
TEST_CASE(enum40);
TEST_CASE(enum41); // ticket #5212 (valgrind errors during enum simplification)
TEST_CASE(enum42); // ticket #5182 (template function call in enum value)
TEST_CASE(enumscope1); // ticket #3949
TEST_CASE(duplicateDefinition); // ticket #3565
// remove "std::" on some standard functions
TEST_CASE(removestd);
// Tokenizer::simplifyInitVar
TEST_CASE(simplifyInitVar);
// Tokenizer::simplifyReference
TEST_CASE(simplifyReference);
// x = realloc(y,0); => free(y);x=0;
TEST_CASE(simplifyRealloc);
// while(f() && errno==EINTR) { } => while (f()) { }
TEST_CASE(simplifyErrNoInWhile);
// while(fclose(f)); => r = fclose(f); while(r){r=fclose(f);}
TEST_CASE(simplifyFuncInWhile);
// struct ABC abc = { .a = 3 }; => struct ABC abc; abc.a = 3;
TEST_CASE(initstruct);
// struct ABC { } abc; => struct ABC { }; ABC abc;
TEST_CASE(simplifyStructDecl1);
TEST_CASE(simplifyStructDecl2); // ticket #2579
TEST_CASE(simplifyStructDecl3);
TEST_CASE(simplifyStructDecl4);
TEST_CASE(simplifyStructDecl5); // ticket #3533 (segmentation fault)
TEST_CASE(simplifyStructDecl6); // ticket #3732
TEST_CASE(simplifyStructDecl7); // ticket #476 (static anonymous struct array)
// register int var; => int var;
// inline int foo() {} => int foo() {}
TEST_CASE(removeUnwantedKeywords);
// remove calling convention __cdecl, __stdcall, ...
TEST_CASE(simplifyCallingConvention);
TEST_CASE(simplifyFunctorCall);
TEST_CASE(redundant_semicolon);
TEST_CASE(simplifyFunctionReturn);
// void foo(void) -> void foo()
TEST_CASE(removeVoidFromFunction);
TEST_CASE(removeUnnecessaryQualification1);
TEST_CASE(removeUnnecessaryQualification2);
TEST_CASE(removeUnnecessaryQualification3);
TEST_CASE(removeUnnecessaryQualification4);
TEST_CASE(removeUnnecessaryQualification5);
TEST_CASE(removeUnnecessaryQualification6); // ticket #2859
TEST_CASE(removeUnnecessaryQualification7); // ticket #2970
TEST_CASE(removeUnnecessaryQualification8);
TEST_CASE(removeUnnecessaryQualification9); // ticket #3151
TEST_CASE(removeUnnecessaryQualification10); // ticket #3310 segmentation fault
TEST_CASE(simplifyIfNotNull);
TEST_CASE(simplifyVarDecl1); // ticket # 2682 segmentation fault
TEST_CASE(simplifyVarDecl2); // ticket # 2834 segmentation fault
TEST_CASE(return_strncat); // ticket # 2860 Returning value of strncat() reported as memory leak
// #3069 : for loop with 1 iteration
// for (x=0;x<1;x++) { .. }
// The for is redundant
TEST_CASE(removeRedundantFor);
TEST_CASE(consecutiveBraces);
TEST_CASE(undefinedSizeArray);
TEST_CASE(simplifyArrayAddress); // Replace "&str[num]" => "(str + num)"
TEST_CASE(simplifyCharAt);
TEST_CASE(simplifyOverride); // ticket #5069
TEST_CASE(simplifyFlowControl);
}
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Unspecified) {
errout.str("");
Settings settings;
settings.addEnabled("portability");
settings.platform(type);
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
if (simplify)
tokenizer.simplifyTokenList();
return tokenizer.tokens()->stringifyList(0, !simplify);
}
std::string tok(const std::string& code, bool simplify = true, Settings::PlatformType type = Settings::Unspecified) {
return tok(code.c_str(), simplify, type);
}
std::string tok(const char code[], const char filename[]) {
errout.str("");
Settings settings;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, filename);
tokenizer.simplifyTokenList();
return tokenizer.tokens()->stringifyList(0, false);
}
std::string tokenizeDebugListing(const std::string &code, bool simplify = false, const char filename[] = "test.cpp") {
errout.str("");
Settings settings;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, filename);
if (simplify)
tokenizer.simplifyTokenList();
// result..
return tokenizer.tokens()->stringifyList(true);
}
void simplifyTokenList1() {
// #1717 : The simplifyErrNoInWhile needs to be used before simplifyIfAndWhileAssign..
ASSERT_EQUALS("; x = f ( ) ; while ( x == -1 ) { x = f ( ) ; }",
tok(";while((x=f())==-1 && errno==EINTR){}",true));
}
void cast() {
ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)0);"));
ASSERT_EQUALS("return str ;", tok("return (char *)str;"));
{
const char code[] = "static void crash()\n"
"{\n"
" goto err_exit;\n"
"err_exit:\n"
" (void)foo();\n"
"}\n";
const char expected[] = "static void crash ( ) "
"{ foo ( ) ; return ; }";
ASSERT_EQUALS(expected, tok(code));
}
ASSERT_EQUALS("if ( * a )", tok("if ((char)*a)"));
ASSERT_EQUALS("if ( & a )", tok("if ((int)&a)"));
ASSERT_EQUALS("if ( * a )", tok("if ((unsigned int)(unsigned char)*a)"));
ASSERT_EQUALS("class A { A operator* ( int ) ; } ;", tok("class A { A operator *(int); };"));
ASSERT_EQUALS("class A { A operator* ( int ) const ; } ;", tok("class A { A operator *(int) const; };"));
ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)(char *)0);"));
// no simplification as the cast may be important here. see #2897 for example
ASSERT_EQUALS("; * ( ( char * ) p + 1 ) = 0 ;", tok("; *((char *)p + 1) = 0;"));
ASSERT_EQUALS("if ( true )", tok("if ((unsigned char)1)")); // #4164
ASSERT_EQUALS("f ( 200 )", tok("f((unsigned char)200)"));
ASSERT_EQUALS("f ( ( char ) 1234 )", tok("f((char)1234)")); // dont simplify downcast
}
void iftruefalse() {
{
const char code1[] = " void f() { int a; bool use = false; if( use ) { a=0; } else {a=1;} }";
const char code2[] = " void f() { int a; bool use = false; {a=1;} }";
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = true; if( use ) { a=0; } else {a=1;} }";
const char code2[] = " void f() { int a; bool use = true; { a=0; } }";
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; int use = 5; if( use ) { a=0; } else {a=1;} }";
const char code2[] = " void f() { int a; int use = 5; { a=0; } }";
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; int use = 0; if( use ) { a=0; } else {a=1;} }";
const char code2[] = " void f() { int a; int use = 0; {a=1;} }";
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = false; if( use ) a=0; else a=1; int c=1; }";
const char code2[] = " void f() { int a; bool use = false; { a=1; } int c=1; }";
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = true; if( use ) a=0; else a=1; int c=1; }";
const char code2[] = " void f() { int a; bool use = true; { a=0; } int c=1; }";
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = false; if( use ) a=0; else if( bb ) a=1; int c=1; }";
const char code2[] = " void f ( ) { int a ; bool use ; use = false ; { if ( bb ) { a = 1 ; } } int c ; c = 1 ; }";
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { int a; bool use = true; if( use ) a=0; else if( bb ) a=1; int c=1; }";
const char code2[] = " void f() { int a; bool use = true; { a=0;} int c=1; }";
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = "void f() { int a; bool use = true; if( use ) a=0; else if( bb ) a=1; else if( cc ) a=33; else { gg = 0; } int c=1; }";
const char code2[] = "void f ( ) { }";
ASSERT_EQUALS(code2, tok(code1));
}
{
const char code1[] = " void f() { if( aa ) { a=0; } else if( true ) a=1; else { a=2; } }";
const char code2[] = " void f ( ) { if ( aa ) { a = 0 ; } else { { a = 1 ; } } }";
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = " void f() { if( aa ) { a=0; } else if( false ) a=1; else { a=2; } }";
const char code2[] = " void f ( ) { if ( aa ) { a = 0 ; } else { { a = 2 ; } } }";
ASSERT_EQUALS(tok(code2), tok(code1));
}
{
const char code1[] = "static const int x=1; void f() { if(x) { a=0; } }";
ASSERT_EQUALS("void f ( ) { a = 0 ; }", tok(code1));
}
}
void combine_strings() {
const char code1[] = "void foo()\n"
"{\n"
"const char *a =\n"
"{\n"
"\"hello \"\n"
"\"world\"\n"
"};\n"
"}\n";
const char code2[] = "void foo()\n"
"{\n"
"const char *a =\n"
"{\n"
"\"hello world\"\n"
"};\n"
"}\n";
ASSERT_EQUALS(tok(code2), tok(code1));
}
void combine_wstrings() {
const char code1[] = "void foo()\n"
"{\n"
"const wchar_t *a =\n"
"{\n"
"L\"hello \"\n"
"L\"world\"\n"
"};\n"
"}\n";
const char code2[] = "void foo()\n"
"{\n"
"const wchar_t *a =\n"
"{\n"
"\"hello world\"\n"
"};\n"
"}\n";
Settings settings;
settings.platform(Settings::Unspecified);
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code1);
tokenizer.tokenize(istr, "test.cpp");
ASSERT_EQUALS(tok(code2), tokenizer.tokens()->stringifyList(0, false));
ASSERT_EQUALS(true, tokenizer.tokens()->tokAt(13) && tokenizer.tokens()->tokAt(13)->isLong());
}
void double_plus() {
{
const char code1[] = "void foo( int a )\n"
"{\n"
"a++;\n"
"a--;\n"
"++a;\n"
"--a;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a ) { a ++ ; a -- ; ++ a ; -- a ; }", tok(code1));
}
{
const char code1[] = "void foo( int a )\n"
"{\n"
"a=a+a;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a ) { a = a + a ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a+++b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a ++ + b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a---b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a -- - b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a--+b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a -- + b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a++-b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a ++ - b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a+--b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a + -- b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a-++b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a - ++ b ; }", tok(code1));
}
}
void redundant_plus() {
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a + + b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a + b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a + + + b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a + b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a + - b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a - b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a - + b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a - b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a - - b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a + b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a - + - b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a + b ; }", tok(code1));
}
{
const char code1[] = "void foo( int a, int b )\n"
"{\n"
"a=a - - - b;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a , int b ) { a = a - b ; }", tok(code1));
}
}
void redundant_plus_numbers() {
{
const char code1[] = "void foo( int a )\n"
"{\n"
"a=a + + 1;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a ) { a = a + 1 ; }", tok(code1));
}
{
const char code1[] = "void foo( int a )\n"
"{\n"
"a=a + + + 1;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a ) { a = a + 1 ; }", tok(code1));
}
{
const char code1[] = "void foo( int a )\n"
"{\n"
"a=a + - 1;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a ) { a = a - 1 ; }", tok(code1));
}
{
const char code1[] = "void foo( int a )\n"
"{\n"
"a=a - + 1;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a ) { a = a - 1 ; }", tok(code1));
}
{
const char code1[] = "void foo( int a )\n"
"{\n"
"a=a - - 1;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a ) { a = a + 1 ; }", tok(code1));
}
{
const char code1[] = "void foo( int a )\n"
"{\n"
"a=a - + - 1;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a ) { a = a + 1 ; }", tok(code1));
}
{
const char code1[] = "void foo( int a )\n"
"{\n"
"a=a - - - 1;\n"
"}\n";
ASSERT_EQUALS("void foo ( int a ) { a = a - 1 ; }", tok(code1));
}
}
void parentheses1() {
ASSERT_EQUALS("<= 110 ;", tok("<= (10+100);"));
ASSERT_EQUALS("while ( x ( ) == -1 ) { }", tok("while((x()) == -1){ }"));
}
void parenthesesVar() {
// remove parentheses..
ASSERT_EQUALS("= p ;", tok("= (p);"));
ASSERT_EQUALS("if ( a < p ) { }", tok("if(a<(p)){}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( p == -1 ) { } }", tok("void f(){int p; if((p)==-1){}}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( p == -1 ) { } }", tok("void f(){int p; if(-1==(p)){}}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( p ) { } }", tok("void f(){int p; if((p)){}}"));
ASSERT_EQUALS("return p ;", tok("return (p);"));
ASSERT_EQUALS("void f ( ) { int * p ; if ( ! * p ) { } }", tok("void f(){int *p; if (*(p) == 0) {}}"));
ASSERT_EQUALS("void f ( ) { int * p ; if ( ! * p ) { } }", tok("void f(){int *p; if (*p == 0) {}}"));
ASSERT_EQUALS("void f ( int & p ) { p = 1 ; }", tok("void f(int &p) {(p) = 1;}"));
ASSERT_EQUALS("void f ( ) { int p [ 10 ] ; p [ 0 ] = 1 ; }", tok("void f(){int p[10]; (p)[0] = 1;}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( ! p ) { } }", tok("void f(){int p; if ((p) == 0) {}}"));
ASSERT_EQUALS("void f ( ) { int * p ; * p = 1 ; }", tok("void f(){int *p; *(p) = 1;}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( p ) { } p = 1 ; }", tok("void f(){int p; if ( p ) { } (p) = 1;}"));
// keep parentheses..
ASSERT_EQUALS("= a ;", tok("= (char)a;"));
ASSERT_EQUALS("cast < char * > ( p )", tok("cast(p)"));
ASSERT_EQUALS("return ( a + b ) * c ;", tok("return (a+b)*c;"));
ASSERT_EQUALS("void f ( ) { int p ; if ( 2 * p == 0 ) { } }", tok("void f(){int p; if (2*p == 0) {}}"));
ASSERT_EQUALS("void f ( ) { DIR * f ; f = opendir ( dirname ) ; if ( closedir ( f ) ) { } }", tok("void f(){DIR * f = opendir(dirname);if (closedir(f)){}}"));
ASSERT_EQUALS("void foo ( int p ) { if ( 0 <= p ) { ; } }", tok("void foo(int p){if((p)>=0);}"));
}
void declareVar() {
const char code[] = "void f ( ) { char str [ 100 ] = \"100\" ; }";
ASSERT_EQUALS(code, tok(code));
}
void declareArray() {
const char code1[] = "void f ( ) { char str [ ] = \"100\" ; }";
const char expected1[] = "void f ( ) { char str [ 4 ] = \"100\" ; }";
ASSERT_EQUALS(expected1, tok(code1));
const char code2[] = "char str [ ] = \"\\x00\";";
const char expected2[] = "char str [ 2 ] = \"\\0\" ;";
ASSERT_EQUALS(expected2, tok(code2));
const char code3[] = "char str [ ] = \"\\0\";";
const char expected3[] = "char str [ 2 ] = \"\\0\" ;";
ASSERT_EQUALS(expected3, tok(code3));
}
void dontRemoveIncrement() {
{
const char code[] = "void f(int a)\n"
"{\n"
" if (a > 10)\n"
" a = 5;\n"
" else\n"
" a = 10;\n"
" a++;\n"
"}\n";
ASSERT_EQUALS("void f ( int a ) { if ( 10 < a ) { a = 5 ; } else { a = 10 ; } a ++ ; }", tok(code));
}
{
const char code[] = "void f(int a)\n"
"{\n"
" if (a > 10)\n"
" a = 5;\n"
" else\n"
" a = 10;\n"
" ++a;\n"
"}\n";
ASSERT_EQUALS("void f ( int a ) { if ( 10 < a ) { a = 5 ; } else { a = 10 ; } ++ a ; }", tok(code));
}
}
void removePostIncrement() {
const char code[] = "void f(int &c)\n"
"{\n"
" c = 0;\n"
" c++;\n"
" if (c>0) { c++; }\n"
" c++;\n"
"}\n";
TODO_ASSERT_EQUALS("void f ( int & c ) { c = 3 ; { ; } ; }",
"void f ( int & c ) { c = 1 ; { c ++ ; } c ++ ; }", tok(code));
}
void removePreIncrement() {
{
const char code[] = "void f(int &c)\n"
"{\n"
" c = 0;\n"
" ++c;\n"
" if (c>0) { ++c; }\n"
" ++c;\n"
"}\n";
TODO_ASSERT_EQUALS("void f ( int & c ) { c = 3 ; { ; } ; }",
"void f ( int & c ) { c = 1 ; { ++ c ; } ++ c ; }", tok(code));
}
{
const char code[] = "void f()\n"
"{\n"
" char a[] = \"p\";\n"
" ++a[0];\n"
"}\n";
ASSERT_EQUALS("void f ( ) { char a [ 2 ] = \"p\" ; ++ a [ 0 ] ; }", tok(code));
}
}
std::string elseif(const char code[]) {
errout.str("");
Settings settings;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.elseif();
return tokenizer.tokens()->stringifyList(false);
}
void elseif1() {
const char code[] = "else if(ab) { cd } else { ef }gh";
ASSERT_EQUALS("\n\n##file 0\n1: else { if ( ab ) { cd } else { ef } } gh\n", elseif(code));
// syntax error: assert there is no segmentation fault
ASSERT_EQUALS("\n\n##file 0\n1: else if ( x ) { }\n", elseif("else if (x) { }"));
{
const char src[] = "void f(int g,int f) {\n"
"if(g==1) {poo();}\n"
"else if( g == 2 )\n"
"{\n"
" if( f == 0 ){coo();}\n"
" else if( f==1)\n"
" goo();\n"
"}\n"
"}";
const char expected[] = "void f ( int g , int f ) "
"{ "
"if ( g == 1 ) { poo ( ) ; } "
"else { "
"if ( g == 2 ) "
"{ "
"if ( ! f ) { coo ( ) ; } "
"else { "
"if ( f == 1 ) "
"{ "
"goo ( ) ; "
"} "
"} "
"} "
"} "
"}";
ASSERT_EQUALS(tok(expected), tok(src));
}
}
void ifa_ifa() {
ASSERT_EQUALS("int a ; if ( a ) { { ab } cd }", tok("int a ; if (a) { if (a) { ab } cd }", true));
ASSERT_EQUALS("int a ; if ( a ) { { ab } cd }", tok("int a ; if (unlikely(a)) { if (a) { ab } cd }", true));
}
unsigned int sizeofFromTokenizer(const char type[]) {
errout.str("");
Settings settings;
Tokenizer tokenizer(&settings, this);
std::istringstream istr("");
tokenizer.tokenize(istr, "test.cpp");
Token tok1(0);
tok1.str(type);
return tokenizer.sizeOfType(&tok1);
}
void sizeof2() {
const char code[] = "void foo()\n"
"{\n"
" int i[4];\n"
" sizeof(i);\n"
" sizeof(*i);\n"
"}\n";
ASSERT_EQUALS("void foo ( ) { int i [ 4 ] ; 16 ; 4 ; }", tok(code));
}
void sizeof3() {
const char code[] = "static int i[4];\n"
"void f()\n"
"{\n"
" int i[10];\n"
" sizeof(i);\n"
"}\n";
ASSERT_EQUALS("static int i [ 4 ] ; void f ( ) { int i [ 10 ] ; 40 ; }", tok(code));
}
void sizeof4() {
{
const char code[] = "int i[10];\n"
"sizeof(i[0]);\n";
ASSERT_EQUALS("int i [ 10 ] ; 4 ;", tok(code));
}
{
const char code[] = "int i[10];\n"
"sizeof i[0];\n";
ASSERT_EQUALS("int i [ 10 ] ; 4 ;", tok(code));
}
}
void sizeof5() {
const char code[] =
"const char * names[2];"
"for (int i = 0; i != sizeof(names[0]); i++)"
"{}";
std::ostringstream expected;
expected << "const char * names [ 2 ] ; for ( int i = 0 ; i != " << sizeofFromTokenizer("*") << " ; i ++ ) { }";
ASSERT_EQUALS(expected.str(), tok(code));
}
void sizeof6() {
const char code[] = ";int i;\n"
"sizeof(i);\n";
std::ostringstream expected;
expected << "; int i ; " << sizeof(int) << " ;";
ASSERT_EQUALS(expected.str(), tok(code));
}
void sizeof7() {
const char code[] = ";INT32 i[10];\n"
"sizeof(i[0]);\n";
ASSERT_EQUALS("; INT32 i [ 10 ] ; sizeof ( i [ 0 ] ) ;", tok(code, true, Settings::Unspecified));
ASSERT_EQUALS("; int i [ 10 ] ; 4 ;", tok(code, true, Settings::Win32A));
}
void sizeof8() {
{
const char code[] = "void f()\n"
"{\n"
" char* ptrs[2];\n"
" a = sizeof( ptrs );\n"
"}\n";
std::ostringstream oss;
oss << (sizeofFromTokenizer("*") * 2);
ASSERT_EQUALS("void f ( ) { char * ptrs [ 2 ] ; a = " + oss.str() + " ; }", tok(code));
}
{
const char code[] = "void f()\n"
"{\n"
" char* ptrs[55];\n"
" a = sizeof( ptrs );\n"
"}\n";
std::ostringstream oss;
oss << (sizeofFromTokenizer("*") * 55);
ASSERT_EQUALS("void f ( ) { char * ptrs [ 55 ] ; a = " + oss.str() + " ; }", tok(code));
}
{
const char code[] = "void f()\n"
"{\n"
" char* ptrs;\n"
" a = sizeof( ptrs );\n"
"}\n";
std::ostringstream oss;
oss << sizeofFromTokenizer("*");
ASSERT_EQUALS("void f ( ) { a = " + oss.str() + " ; }", tok(code));
}
}
void sizeof9() {
// ticket #487
{
const char code[] = "; const char *str = \"1\"; sizeof(str);";
std::ostringstream expected;
expected << "; const char * str ; str = \"1\" ; " << sizeofFromTokenizer("*") << " ;";
ASSERT_EQUALS(expected.str(), tok(code));
}
{
const char code[] = "; const char str[] = \"1\"; sizeof(str);";
std::ostringstream expected;
expected << "; const char str [ 2 ] = \"1\" ; " << sizeofFromTokenizer("char")*2 << " ;";
ASSERT_EQUALS(expected.str(), tok(code));
}
{
// Ticket #799
const char code[] = "; const char str[] = {'1'}; sizeof(str);";
ASSERT_EQUALS("; const char str [ 1 ] = { '1' } ; 1 ;", tok(code));
}
{
// Ticket #2087
const char code[] = "; const char str[] = {\"abc\"}; sizeof(str);";
ASSERT_EQUALS("; const char str [ 4 ] = \"abc\" ; 4 ;", tok(code));
}
// ticket #716 - sizeof string
{
std::ostringstream expected;
expected << "; " << (sizeof "123");
ASSERT_EQUALS(expected.str(), tok("; sizeof \"123\""));
ASSERT_EQUALS(expected.str(), tok("; sizeof(\"123\")"));
}
{
const char code[] = "void f(char *a,char *b, char *c)"
"{g(sizeof(a),sizeof(b),sizeof(c));}";
std::ostringstream expected;
expected << "void f ( char * a , char * b , char * c ) { g ( " <<
sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " ) ; }";
ASSERT_EQUALS(expected.str(), tok(code));
}
{
const char code[] = "void f(char a,char b, char c)"
"{g(sizeof(a),sizeof(b),sizeof(c));}";
std::ostringstream expected;
expected << "void f ( char a , char b , char c ) { g ( " <<
sizeofFromTokenizer("char") << " , " << sizeofFromTokenizer("char") << " , " << sizeofFromTokenizer("char") << " ) ; }";
ASSERT_EQUALS(expected.str(), tok(code));
}
{
const char code[] = "void f(const char *a,const char *b, const char *c)"
"{g(sizeof(a),sizeof(b),sizeof(c));}";
std::ostringstream expected;
expected << "void f ( const char * a , const char * b , const char * c ) { g ( " <<
sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " ) ; }";
ASSERT_EQUALS(expected.str(), tok(code));
}
{
const char code[] = "void f(char a[10],char b[10], char c[10])"
"{g(sizeof(a),sizeof(b),sizeof(c));}";
std::ostringstream expected;
expected << "void f ( char a [ 10 ] , char b [ 10 ] , char c [ 10 ] ) { g ( " <<
sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " ) ; }";
ASSERT_EQUALS(expected.str(), tok(code));
}
{
const char code[] = "void f(const char a[10],const char b[10], const char c[10])"
"{g(sizeof(a),sizeof(b),sizeof(c));}";
std::ostringstream expected;
expected << "void f ( const char a [ 10 ] , "
"const char b [ 10 ] , "
"const char c [ 10 ] ) { g ( " <<
sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " ) ; }";
ASSERT_EQUALS(expected.str(), tok(code));
}
{
const char code[] = "void f(const char *a[10],const char *b[10], const char *c[10])"
"{g(sizeof(a),sizeof(b),sizeof(c));}";
std::ostringstream expected;
expected << "void f ( const char * a [ 10 ] , "
"const char * b [ 10 ] , "
"const char * c [ 10 ] ) { g ( " <<
sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " ) ; }";
ASSERT_EQUALS(expected.str(), tok(code));
}
{
const char code[] = "void f(char *a[10],char *b[10], char *c[10])"
"{g(sizeof(a),sizeof(b),sizeof(c));}";
std::ostringstream expected;
expected << "void f ( char * a [ 10 ] , char * b [ 10 ] , char * c [ 10 ] ) { g ( " <<
sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " , " << sizeofFromTokenizer("*") << " ) ; }";
ASSERT_EQUALS(expected.str(), tok(code));
}
{
std::ostringstream expected;
expected << "; " << sizeof("\"quote\"");
ASSERT_EQUALS(expected.str(), tok("; sizeof(\"\\\"quote\\\"\")"));
}
{
std::ostringstream expected;
expected << "void f ( ) { char str [ 100 ] = \"100\" ; " << sizeofFromTokenizer("char")*100 << " }";
ASSERT_EQUALS(expected.str(), tok("void f ( ) { char str [ 100 ] = \"100\" ; sizeof ( str ) }"));
}
}
void sizeof10() {
// ticket #809
const char code[] = "int m ; "
"compat_ulong_t um ; "
"long size ; size = sizeof ( m ) / sizeof ( um ) ;";
ASSERT_EQUALS(code, tok(code, true, Settings::Win32A));
}
void sizeof11() {
// ticket #827
const char code[] = "void f()\n"
"{\n"
" char buf2[4];\n"
" sizeof buf2;\n"
"}\n"
"\n"
"void g()\n"
"{\n"
" struct A a[2];\n"
" char buf[32];\n"
" sizeof buf;\n"
"}";
const char expected[] = "void f ( ) "
"{"
" char buf2 [ 4 ] ;"
" 4 ; "
"} "
""
"void g ( ) "
"{"
" struct A a [ 2 ] ;"
" char buf [ 32 ] ;"
" 32 ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
void sizeof12() {
// ticket #827
const char code[] = "void f()\n"
"{\n"
" int *p;\n"
" (sizeof *p);\n"
"}";
const char expected[] = "void f ( ) "
"{"
""
" 4 ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
void sizeof13() {
// ticket #851
const char code[] = "int main()\n"
"{\n"
" char *a;\n"
" a = malloc(sizeof(*a));\n"
"}\n"
"\n"
"struct B\n"
"{\n"
" char * b[2];\n"
"};";
const char expected[] = "int main ( ) "
"{"
" char * a ;"
" a = malloc ( 1 ) ; "
"} "
"struct B "
"{"
" char * b [ 2 ] ; "
"} ;";
ASSERT_EQUALS(expected, tok(code));
}
void sizeof14() {
// ticket #954
const char code[] = "void f()\n"
"{\n"
" A **a;\n"
" int aa = sizeof *(*a)->b;\n"
"}\n";
const char expected[] = "void f ( ) "
"{"
" A * * a ;"
" int aa ; aa = sizeof ( * ( * a ) . b ) ; "
"}";
ASSERT_EQUALS(expected, tok(code));
// #5064 - sizeof !! (a == 1);
ASSERT_EQUALS("sizeof ( ! ! ( a == 1 ) ) ;", tok("sizeof !!(a==1);"));
}
void sizeof15() {
// ticket #1020
tok("void f()\n"
"{\n"
" int *n;\n"
" sizeof *(n);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void sizeof16() {
// ticket #1027
const char code[] = "void f()\n"
"{\n"
" int a;\n"
" printf(\"%i\", sizeof a++);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { int a ; printf ( \"%i\" , sizeof ( a ++ ) ) ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
void sizeof17() {
// ticket #1050
const char code[] = "void f()\n"
"{\n"
" sizeof 1;\n"
" while (0);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { sizeof ( 1 ) ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
void sizeof18() {
{
std::ostringstream expected;
expected << sizeof(short int);
{
const char code[] = "void f()\n"
"{\n"
" sizeof(short int);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(unsigned short int);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(short unsigned int);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(signed short int);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
}
{
std::ostringstream expected;
expected << sizeof(long long);
{
const char code[] = "void f()\n"
"{\n"
" sizeof(long long);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(signed long long);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(unsigned long long);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(long unsigned long);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(long long int);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(signed long long int);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(unsigned long long int);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(long unsigned long int);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(char*);\n"
"}\n";
std::ostringstream expected;
expected << sizeof(int*);
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof(unsigned int*);\n"
"}\n";
std::ostringstream expected;
expected << sizeof(int*);
ASSERT_EQUALS("void f ( ) { " + expected.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
}
void sizeof19() {
// ticket #1891 - sizeof 'x'
{
const char code[] = "void f()\n"
"{\n"
" sizeof 'x';\n"
"}\n";
std::ostringstream sz;
sz << sizeof('x');
ASSERT_EQUALS("void f ( ) { " + sz.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
{
const char code[] = "void f()\n"
"{\n"
" sizeof('x');\n"
"}\n";
std::ostringstream sz;
sz << sizeof('x');
ASSERT_EQUALS("void f ( ) { " + sz.str() + " ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
}
void sizeof20() {
// ticket #2024 - sizeof a)
const char code[] = "struct struct_a {\n"
" char a[20];\n"
"};\n"
"\n"
"void foo() {\n"
" struct_a a;\n"
" append(sizeof a).append();\n"
"}\n";
ASSERT_EQUALS("struct struct_a { char a [ 20 ] ; } ; "
"void foo ( ) {"
" struct_a a ;"
" append ( sizeof ( a ) ) . append ( ) ; "
"}", tok(code));
}
void sizeof21() {
// ticket #2232 - sizeof...(Args)
const char code[] = "struct Internal {\n"
" int operator()(const Args&... args) const {\n"
" int n = sizeof...(Args);\n"
" return n;\n"
" }\n"
"};\n"
"\n"
"int main() {\n"
" Internal internal;\n"
" int n = 0; n = internal(1);\n"
" return 0;\n"
"}\n";
// don't segfault
tok(code);
}
void sizeof22() {
// ticket #2599 segmentation fault
const char code[] = "sizeof\n";
// don't segfault
tok(code);
}
void sizeof23() {
// ticket #2604 segmentation fault
const char code[] = "sizeof <= A\n";
// don't segfault
tok(code);
}
void sizeofsizeof() {
// ticket #1682
const char code[] = "void f()\n"
"{\n"
" sizeof sizeof 1;\n"
"}\n";
ASSERT_EQUALS("void f ( ) { sizeof sizeof ( 1 ) ; }", tok(code));
ASSERT_EQUALS("", errout.str());
}
void casting() {
{
const char code[] = "void f()\n"
"{\n"
"for (int i = 0; i < static_cast(3); ++i) {}\n"
"}\n";
const std::string expected("void f ( ) { for ( int i = 0 ; i < 3 ; ++ i ) { } }");
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "void f()\n"
"{\n"
" p = const_cast qtu ();\n"
"}\n";
const std::string expected("void f ( ) { p = const_cast < char * > qtu ( ) ; }");
ASSERT_EQUALS(expected, tok(code));
}
{
// ticket #645
const char code[] = "void f()\n"
"{\n"
" return dynamic_cast((bar()));\n"
"}\n";
const std::string expected("void f ( ) { return bar ( ) ; }");
ASSERT_EQUALS(expected, tok(code));
}
}
void strlen1() {
ASSERT_EQUALS("4", tok("strlen(\"abcd\")"));
{
const char code[] = "void f()\n"
"{\n"
" const char *s = \"abcd\";\n"
" strlen(s);\n"
"}\n";
const char expected[] = "void f ( ) "
"{"
" const char * s ;"
" s = \"abcd\" ;"
" 4 ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "void f()\n"
"{\n"
" const char s [ ] = \"abcd\";\n"
" strlen(s);\n"
"}\n";
const char expected[] = "void f ( ) "
"{"
" const char s [ 5 ] = \"abcd\" ;"
" 4 ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
}
void strlen2() {
// #4530 - make sure calculation with strlen is simplified
ASSERT_EQUALS("i = -4 ;",
tok("i = (strlen(\"abcd\") - 8);"));
}
void template1() {
const char code[] = "template void f(T val) { T a; }\n"
"f(10);";
const std::string expected("f ( 10 ) ; "
"void f ( int val ) { }");
ASSERT_EQUALS(expected, tok(code));
}
void template2() {
const char code[] = "template class Fred { T a; };\n"
"Fred fred;";
const std::string expected("Fred fred ; "
"class Fred { int a ; }");
ASSERT_EQUALS(expected, tok(code));
}
void template3() {
const char code[] = "template class Fred { T data[sz]; };\n"
"Fred fred;";
const std::string expected("Fred fred ; "
"class Fred { float data [ 4 ] ; }");
ASSERT_EQUALS(expected, tok(code));
}
void template4() {
const char code[] = "template class Fred { Fred(); };\n"
"Fred fred;";
const std::string expected("Fred fred ; "
"class Fred { Fred ( ) ; }");
ASSERT_EQUALS(expected, tok(code));
}
void template5() {
const char code[] = "template class Fred { };\n"
"template Fred::Fred() { }\n"
"Fred fred;";
const std::string expected("template < classname T > Fred < T > :: Fred ( ) { } " // <- TODO: this should be removed
"Fred fred ; "
"class Fred { } "
"Fred :: Fred ( ) { }");
ASSERT_EQUALS(expected, tok(code));
}
void template6() {
const char code[] = "template class Fred { };\n"
"Fred fred1;\n"
"Fred fred2;";
const std::string expected("Fred fred1 ; "
"Fred fred2 ; "
"class Fred { }");
ASSERT_EQUALS(expected, tok(code));
}
void template7() {
// A template class that is not used => no simplification
{
const char code[] = "template \n"
"class ABC\n"
"{\n"
"public:\n"
" typedef ABC m;\n"
"};\n";
const std::string expected("template < class T > class ABC { public: } ;");
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "template class ABC {\n"
"public:\n"
" typedef std::vector type;\n"
"};\n"
"int main() {\n"
" ABC::type v;\n"
" v.push_back(4);\n"
" return 0;\n"
"}\n";
const std::string wanted("template < typename T > class ABC { public: } ; "
"int main ( ) { "
"std :: vector < int > v ; "
"v . push_back ( 4 ) ; "
"return 0 ; "
"}");
const std::string current("template < typename T > class ABC { public: } ; "
"int main ( ) { "
"ABC < int > :: type v ; "
"v . push_back ( 4 ) ; "
"return 0 ; "
"}");
TODO_ASSERT_EQUALS(wanted, current, tok(code));
}
{
const char code[] = "template class ABC {\n"
"public:\n"
" typedef std::vector type;\n"
" void f()\n"
" {\n"
" ABC::type v;\n"
" v.push_back(4);\n"
" }\n"
"};\n";
const std::string expected("template < typename T > class ABC { "
"public: void f ( ) { "
"ABC < int > :: type v ; "
"v . push_back ( 4 ) ; "
"} "
"} ;");
ASSERT_EQUALS(expected, tok(code));
}
}
// Template definitions but no usage => no expansion
void template8() {
const char code[] = "template class A;\n"
"template class B;\n"
"\n"
"typedef A x;\n"
"typedef B y;\n"
"\n"
"template class A {\n"
" void f() {\n"
" B a = B::g();\n"
" T b = 0;\n"
" if (b)\n"
" b = 0;\n"
" }\n"
"};\n"
"\n"
"template inline B h() { return B(); }\n";
ASSERT_EQUALS("template < typename T > class A ; "
"template < typename T > class B ; "
"template < typename T > class A { void f ( ) { B < T > a ; a = B < T > :: g ( ) ; T b ; b = 0 ; } } ; "
"template < typename T > B < T > h ( ) { return B < T > ( ) ; }", tok(code));
ASSERT_EQUALS("class A { template < typename T > int foo ( T d ) ; } ;", tok("class A{ template int foo(T d);};"));
}
void template9() {
const char code[] = "template < typename T > class A { } ;\n"
"\n"
"void f ( ) {\n"
" A a ;\n"
"}\n"
"\n"
"template < typename T >\n"
"class B {\n"
" void g ( ) {\n"
" A < T > b = A < T > :: h ( ) ;\n"
" }\n"
"} ;\n";
// The expected result..
std::string expected("void f ( ) { A a ; } "
"template < typename T > class B { void g ( ) { A b ; b = A :: h ( ) ; } } ; "
"class A { } class A { }");
ASSERT_EQUALS(expected, tok(code));
}
void template10() {
const char code[] = "template T * foo()\n"
"{ return new T[ui]; }\n"
"\n"
"void f ( )\n"
"{\n"
" foo<3,int>();\n"
"}\n";
// The expected result..
const std::string expected("void f ( ) "
"{"
" foo<3,int> ( ) ; "
"} "
"int * foo<3,int> ( ) { return new int [ 3 ] ; }");
ASSERT_EQUALS(expected, tok(code));
}
void template11() {
const char code[] = "template T * foo()\n"
"{ return new T[ui]; }\n"
"\n"
"void f ( )\n"
"{\n"
" char * p = foo<3,char>();\n"
"}\n";
// The expected result..
const std::string expected("void f ( ) "
"{"
" char * p ; p = foo<3,char> ( ) ; "
"} "
"char * foo<3,char> ( ) { return new char [ 3 ] ; }");
ASSERT_EQUALS(expected, tok(code));
}
void template12() {
const char code[] = "template \n"
"class A : public B\n"
"{ };\n"
"\n"
"void f()\n"
"{\n"
" A<12,12,11> a;\n"
"}\n";
// The expected result..
const std::string expected("void f ( ) "
"{"
" A<12,12,11> a ; "
"} "
"class A<12,12,11> : public B < 12 , 12 , 0 > "
"{ }");
ASSERT_EQUALS(expected, tok(code));
}
void template13() {
const char code[] = "class BB {};\n"
"\n"
"template \n"
"class AA\n"
"{\n"
"public:\n"
" static AA create(T* newObject);\n"
" static int size();\n"
"};\n"
"\n"
"class CC { public: CC(AA, int) {} };\n"
"\n"
"class XX {\n"
" AA y;\n"
"public:\n"
" XX();\n"
"};\n"
"\n"
"XX::XX():\n"
" y(AA::create(new CC(AA(), 0)))\n"
" {}\n"
"\n"
"int yy[AA::size()];";
// Just run it and check that there are not assertions.
tok(code);
}
void template14() {
const char code[] = "template <> void foo()\n"
"{ x(); }\n"
"\n"
"int main()\n"
"{\n"
"foo();\n"
"}\n";
// The expected result..
const std::string expected("void foo ( ) "
"{ x ( ) ; } "
"int main ( ) "
"{ foo ( ) ; }");
ASSERT_EQUALS(expected, tok(code));
}
void template15() {
const char code[] = "template void a()\n"
"{\n"
" a();\n"
"}\n"
"\n"
"template <> void a<0>()\n"
"{ }\n"
"\n"
"int main()\n"
"{\n"
" a<2>();\n"
" return 0;\n"
"}\n";
// The expected result..
const std::string expected("void a<0> ( ) { } "
"int main ( ) "
"{ a<2> ( ) ; return 0 ; } "
"void a<2> ( ) { a<1> ( ) ; } "
"void a<1> ( ) { a<0> ( ) ; }");
ASSERT_EQUALS(expected, tok(code));
}
void template16() {
const char code[] = "template void a()\n"
"{ }\n"
"\n"
"template void b()\n"
"{ a(); }\n"
"\n"
"int main()\n"
"{\n"
" b<2>();\n"
" return 0;\n"
"}\n";
const std::string expected("int main ( ) { b<2> ( ) ; return 0 ; } "
"void b<2> ( ) { a<2> ( ) ; } "
"void a ( ) { } "
"void a<2> ( ) { }");
ASSERT_EQUALS(expected, tok(code));
}
void template17() {
const char code[] = "template\n"
"class Fred\n"
"{\n"
" template\n"
" static shared_ptr< Fred > CreateFred()\n"
" {\n"
" }\n"
"};\n"
"\n"
"shared_ptr i;\n";
// Assert that there is no segmentation fault..
tok(code);
}
void template18() {
const char code[] = "template class foo { T a; };\n"
"foo *f;";
const std::string expected("foo * f ; "
"class foo { int a ; }");
ASSERT_EQUALS(expected, tok(code));
}
void template19() {
const char code[] = "template T & foo()\n"
"{ static T temp; return temp; }\n"
"\n"
"void f ( )\n"
"{\n"
" char p = foo();\n"
"}\n";
// The expected result..
const std::string expected("void f ( ) "
"{"
" char p ; p = foo ( ) ; "
"} "
"char & foo ( ) { static char temp ; return temp ; }");
ASSERT_EQUALS(expected, tok(code));
}
void template20() {
// Ticket #1788 - the destructor implementation is lost
const char code[] = "template class A\n"
"{\n"
"public:\n"
" ~A();\n"
"};\n"
"\n"
"template A::~A()\n"
"{\n"
"}\n"
"\n"
"A a;\n";
// The expected result..
const std::string expected("template < class T > A < T > :: ~ A ( ) { } " // <- TODO: this should be removed
"A a ; "
"class A { public: ~ A ( ) ; } "
"A :: ~ A ( ) { }");
ASSERT_EQUALS(expected, tok(code));
}
void template21() {
{
const char code[] = "template struct Fred { T a; };\n"
"Fred fred;";
const std::string expected("Fred fred ; "
"struct Fred { int a ; }");
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "template struct Fred { T data[sz]; };\n"
"Fred fred;";
const std::string expected("Fred fred ; "
"struct Fred { float data [ 4 ] ; }");
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "template struct Fred { Fred(); };\n"
"Fred fred;";
const std::string expected("Fred fred ; "
"struct Fred { Fred ( ) ; }");
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "template struct Fred { };\n"
"Fred fred1;\n"
"Fred fred2;";
const std::string expected("Fred fred1 ; "
"Fred fred2 ; "
"struct Fred { }");
ASSERT_EQUALS(expected, tok(code));
}
}
void template22() {
const char code[] = "template struct Fred { T a; };\n"
"Fred fred;";
const std::string expected("Fred fred ; "
"struct Fred { std :: string a ; }");
ASSERT_EQUALS(expected, tok(code));
}
void template23() {
const char code[] = "template void foo() { }\n"
"void bar() {\n"
" std::cout << (foo());\n"
"}";
const std::string expected("void bar ( ) {"
" std :: cout << ( foo ( ) ) ; "
"} "
"void foo ( ) { }");
ASSERT_EQUALS(expected, tok(code));
}
void template24() {
// #2648
const char code[] = "template struct B\n"
"{\n"
" int a[n];\n"
"};\n"
"\n"
"template class bitset: B\n"
"{};\n"
"\n"
"bitset<1> z;";
const char expected[] = "bitset<1> z ; "
"class bitset<1> : B<4> { } "
"struct B<4> { int a [ 4 ] ; }";
ASSERT_EQUALS(expected, tok(code));
}
void template25() {
const char code[] = "template struct B\n"
"{\n"
" int a[n];\n"
"};\n"
"\n"
"template class bitset: B<((sizeof(int)) ? : 1)>\n"
"{};\n"
"\n"
"bitset<1> z;";
const char actual[] = "template < int n > struct B { int a [ n ] ; } ; "
"bitset<1> z ; "
"class bitset<1> : B < 4 > { }";
const char expected[] = "bitset<1> z ; "
"class bitset<1> : B<4> { } "
"struct B<4> { int a [ 4 ] ; }";
TODO_ASSERT_EQUALS(expected, actual, tok(code));
}
void template26() {
// #2721
const char code[] = "template\n"
"class A { public: T x; };\n"
"\n"
"template\n"
"class C: public A {};\n"
"\n"
"C<2> a;\n";
// TODO: expand A also
ASSERT_EQUALS("template < class T > class A { public: T x ; } ; C<2> a ; class C<2> : public A < char [ 2 ] > { }", tok(code));
}
void template27() {
// #3350 - template inside macro call
const char code[] = "X(template class Fred);";
ASSERT_EQUALS("X ( template < class T > class Fred ) ;", tok(code));
}
void template28() {
// #3226 - inner template
const char code[] = "template class Fred {};\n"
"Fred > x;\n";
ASSERT_EQUALS("Fred> x ; class Fred { } class Fred> { }", tok(code));
}
void template29() {
// #3449 - garbage code (don't segfault)
const char code[] = "template struct A;\n"
"struct B { template struct C };\n"
"{};";
ASSERT_EQUALS("template < typename T > struct A ; struct B { template < typename T > struct C } ; { } ;", tok(code));
}
void template30() {
// #3529 - template < template < ..
const char code[] = "template class A, class B> void f(){}";
ASSERT_EQUALS("template < template < class > class A , class B > void f ( ) { }", tok(code));
}
void template31() {
// #4010 - template reference type
const char code[] = "template struct A{}; A a;";
ASSERT_EQUALS("A a ; struct A { }", tok(code));
}
void template32() {
// #3818 - mismatching template not handled well
const char code[] = "template struct A { };\n"
"\n"
"template \n"
"struct B\n"
"{\n"
" public:\n"
" A < int, Pair, int > a;\n" // mismatching parameters => don't instantiate
"};\n"
"\n"
"B b;\n";
ASSERT_EQUALS("template < class T1 , class T2 , class T3 , class T4 > struct A { } ; "
"B b ; "
"struct B { public: A < int , Pair < int , int > , int > a ; }", tok(code));
}
void template33() {
{
// #3818 - inner templates in template instantiation not handled well
const char code[] = "template struct A { };\n"
"template struct B { };\n"
"template struct C { A > > ab; };\n"
"C c;";
ASSERT_EQUALS("C c ; "
"struct C { A>> ab ; } "
"struct B> { } " // <- redundant.. but nevermind
"struct A>> { } " // <- redundant.. but nevermind
"struct A>> { }", tok(code));
}
{
// #4544
const char code[] = "struct A { };\n"
"template struct B { };\n"
"template struct C { };\n"
"C< B > c;";
ASSERT_EQUALS("struct A { } ; "
"template < class T > struct B { } ; " // <- redundant.. but nevermind
"C> c ; struct C> { }",
tok(code));
}
}
void template34() {
// #3706 - namespace => hang
const char code[] = "namespace abc {\n"
"template struct X { void f(X &x) {} };\n"
"}\n"
"template <> int X::Y(0);";
ASSERT_EQUALS("namespace abc { "
"template < typename T > struct X { void f ( X < T > & x ) { } } ; "
"} "
"template < > int X < int > :: Y ( 0 ) ;", tok(code));
}
void template35() { // #4074 - "A<'x'> a;" is not recognized as template instantiation
const char code[] = "template class A {};\n"
"A<'x'> a;";
ASSERT_EQUALS("A<'x'> a ; class A<'x'> { }", tok(code));
}
void template36() { // #4310 - Passing unknown template instantiation as template argument
const char code[] = "template struct X { T t; };\n"
"template struct Y { Foo < X< Bar > > _foo; };\n" // <- Bar is unknown
"Y bar;";
ASSERT_EQUALS("Y bar ; "
"struct Y { Foo < X> > _foo ; } "
"struct X> { Bar < int > t ; }",
tok(code));
}
void template37() { // #4544 - A a;
const char code[] = "class A { };\n"
"template class B {};\n"
"B b1;\n"
"B b2;";
ASSERT_EQUALS("class A { } ; B b1 ; B b2 ; class B { }",
tok(code));
}
void template_unhandled() {
// An unhandled template usage should be simplified..
ASSERT_EQUALS("x ( ) ;", tok("x();"));
}
void template38() { // #4832 - Crash on C++11 right angle brackets
const char code[] = "template class A {\n"
" T mT;\n"
"public:\n"
" void foo() {}\n"
"};\n"
"\n"
"int main() {\n"
" A> gna1;\n"
" A gna2;\n"
"}\n";
tok(code); // Don't crash or freeze
}
void template39() { // #4742 - Used to freeze in 1.60
const char code[] = "template struct vector {"
" operator T() const;"
"};"
"void f() {"
" vector> v;"
" const vector vi = static_cast>(v);"
"}";
tok(code);
}
void template40() { // #5055 - false negatives when there is template specialization outside struct
const char code[] = "struct A {"
" template struct X { T t; };"
"};"
"template<> struct A::X { int *t; };";
ASSERT_EQUALS("struct A { template < typename T > struct X { T t ; } ; } ;", tok(code));
}
void template41() { // #4710 - const in template instantiation not handled perfectly
const char code1[] = "template struct X { };\n"
"void f(const X x) { }";
ASSERT_EQUALS("void f ( const X x ) { } struct X { }", tok(code1));
const char code2[] = "template T f(T t) { return t; }\n"
"int x() { return f(123); }";
ASSERT_EQUALS("int x ( ) { return f ( 123 ) ; } int f ( int t ) { return t ; }", tok(code2));
}
void template42() { // #4878 cpcheck aborts in ext-blocks.cpp (clang testcode)
const char code[] = "template\n"
"int f0(Args ...args) {\n"
" return ^ {\n"
" return sizeof...(Args);\n"
" }() + ^ {\n"
" return sizeof...(args);\n"
" }();\n"
"}";
tok(code);
}
void template_default_parameter() {
{
const char code[] = "template \n"
"class A\n"
"{ T ar[n]; };\n"
"\n"
"void f()\n"
"{\n"
" A a1;\n"
" A a2;\n"
"}\n";
// The expected result..
const std::string expected("void f ( ) "
"{"
" A a1 ;"
" A a2 ; "
"} "
"class A "
"{ int ar [ 2 ] ; } "
"class A "
"{ int ar [ 3 ] ; }");
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "template \n"
"class A\n"
"{ T ar[n1+n2]; };\n"
"\n"
"void f()\n"
"{\n"
" A a1;\n"
" A a2;\n"
"}\n";
// The expected result..
const std::string expected("void f ( ) "
"{"
" A a1 ;"
" A a2 ; "
"} "
"class A "
"{ int ar [ 5 ] ; }");
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "template \n"
"class A\n"
"{ T ar[n]; };\n"
"\n"
"void f()\n"
"{\n"
" A a1;\n"
" A a2;\n"
"}\n";
const std::string wanted("template < class T , int n >"
" class A"
" { T ar [ n ] ; } ;"
" void f ( )"
" {"
" A a1 ;"
" A a2 ;"
" }"
" class A"
" { int ar [ 2 ] ; }"
" class A"
" { int ar [ 3 ] ; }");
const std::string current("void f ( ) "
"{ "
"A < int , ( int ) 2 > a1 ; "
"A a2 ; "
"} "
"class A "
"{ int ar [ 3 ] ; }"
);
TODO_ASSERT_EQUALS(wanted, current, tok(code));
}
{
const char code[] = "template> class B {};\n"
"template> class C;\n"
"template class D { };\n";
ASSERT_EQUALS("template < class T , class T2 > class B { } ; "
"template < class B , typename C > class C ; "
"template < class B , typename C > class D { } ;", tok(code));
}
}
void template_default_type() {
const char code[] = "template \n"
"class A\n"
"{\n"
"public:\n"
" void foo() {\n"
" int a;\n"
" a = static_cast(a);\n"
" }\n"
"};\n"
"\n"
"template \n"
"class B\n"
"{\n"
"protected:\n"
" A a;\n"
"};\n"
"\n"
"class C\n"
" : public B\n"
"{\n"
"};\n";
tok(code);
//ASSERT_EQUALS("[file1.cpp:15]: (error) Internal error: failed to instantiate template. The checking continues anyway.\n", errout.str());
ASSERT_EQUALS("", errout.str());
}
void template_typename() {
{
const char code[] = "template \n"
"void foo(typename T::t *)\n"
"{ }";
// The expected result..
const std::string expected("template < class T > void foo ( T :: t * ) { }");
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "void f() {\n"
" x(sizeof typename);\n"
" type = 0;\n"
"}";
ASSERT_EQUALS("void f ( ) { x ( sizeof ( typename ) ) ; type = 0 ; }", tok(code));
}
}
void template_constructor() {
// #3152 - if template constructor is removed then there might be
// "no constructor" false positives
const char code[] = "class Fred {\n"
" template explicit Fred(T t) { }\n"
"}";
ASSERT_EQUALS("class Fred { template < class T > explicit Fred ( T t ) { } }", tok(code));
// #3532
const char code2[] = "class Fred {\n"
" template Fred(T t) { }\n"
"}";
ASSERT_EQUALS("class Fred { template < class T > Fred ( T t ) { } }", tok(code2));
}
unsigned int templateParameters(const char code[]) {
Settings settings;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
return TemplateSimplifier::templateParameters(tokenizer.tokens());
}
void templateParameters() {
// Test that the function TemplateSimplifier::templateParameters works
ASSERT_EQUALS(1U, templateParameters(" x;"));
ASSERT_EQUALS(1U, templateParameters(" x;"));
ASSERT_EQUALS(1U, templateParameters(" x;"));
ASSERT_EQUALS(1U, templateParameters(" x;"));
ASSERT_EQUALS(1U, templateParameters(" x;"));
}
void templateParameters1() {
// #4169 - segmentation fault (invalid code)
const char code[] = "volatile true , test < test < #ifdef __ppc__ true ,";
// do not crash on invalid code
ASSERT_EQUALS(0, templateParameters(code));
}
void namespaces() {
{
const char code[] = "namespace std { }";
ASSERT_EQUALS("", tok(code));
}
{
const char code[] = "; namespace std { }";
ASSERT_EQUALS(";", tok(code));
}
{
const char code[] = "using namespace std; namespace a{ namespace b{ void f(){} } }";
const std::string expected("namespace a { namespace b { void f ( ) { } } }");
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "namespace b{ void f(){} }";
const std::string expected("namespace b { void f ( ) { } }");
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "void f(int namespace) { }";
const std::string expected("void f ( int namespace ) { }");
ASSERT_EQUALS(expected, tok(code));
}
}
std::string simplifyIfAndWhileAssign(const char code[]) {
errout.str("");
Settings settings;
// tokenize..
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyIfAndWhileAssign();
return tokenizer.tokens()->stringifyList(0, false);
}
void ifassign1() {
ASSERT_EQUALS("; a = b ; if ( a ) { ; }", simplifyIfAndWhileAssign(";if(a=b);"));
ASSERT_EQUALS("; a = b ( ) ; if ( a ) { ; }", simplifyIfAndWhileAssign(";if((a=b()));"));
ASSERT_EQUALS("; a = b ( ) ; if ( ! ( a ) ) { ; }", simplifyIfAndWhileAssign(";if(!(a=b()));"));
ASSERT_EQUALS("; a . x = b ( ) ; if ( ! ( a . x ) ) { ; }", simplifyIfAndWhileAssign(";if(!(a->x=b()));"));
ASSERT_EQUALS("void f ( ) { A ( ) a = b ; if ( a ) { ; } }", simplifyIfAndWhileAssign("void f() { A() if(a=b); }"));
ASSERT_EQUALS("void foo ( int a ) { a = b ( ) ; if ( 0 <= a ) { ; } }", tok("void foo(int a) {if((a=b())>=0);}"));
TODO_ASSERT_EQUALS("void foo ( A a ) { a . c = b ( ) ; if ( 0 <= a . c ) { ; } }",
"void foo ( A a ) { a . c = b ( ) ; if ( a . c >= 0 ) { ; } }",
tok("void foo(A a) {if((a.c=b())>=0);}"));
}
void ifAssignWithCast() {
const char *code = "void foo()\n"
"{\n"
"FILE *f;\n"
"if( (f = fopen(\"foo\", \"r\")) == ((FILE*)NULL) )\n"
"return(-1);\n"
"fclose(f);\n"
"}\n";
const char *expected = "void foo ( ) "
"{ "
"FILE * f ; "
"f = fopen ( \"foo\" , \"r\" ) ; "
"if ( ! f ) "
"{ "
"return -1 ; "
"} "
"fclose ( f ) ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
void whileAssign1() {
ASSERT_EQUALS("; a = b ; while ( a ) { b = 0 ; a = b ; }", simplifyIfAndWhileAssign(";while(a=b) { b = 0; }"));
ASSERT_EQUALS("; a . b = c ; while ( a . b ) { c = 0 ; a . b = c ; }", simplifyIfAndWhileAssign(";while(a.b=c) { c=0; }"));
ASSERT_EQUALS("struct hfs_bnode * node ; "
"struct hfs_btree * tree ; "
"node = tree . node_hash [ i ++ ] ; "
"while ( node ) { node = tree . node_hash [ i ++ ] ; }",
tok("struct hfs_bnode *node;"
"struct hfs_btree *tree;"
"while ((node = tree->node_hash[i++])) { }"));
ASSERT_EQUALS("char * s ; s = new char [ 10 ] ; while ( ! s ) { s = new char [ 10 ] ; }",
tok("char *s; while (0 == (s=new char[10])) { }"));
}
void whileAssign2() {
// #1909 - Internal error
tok("void f()\n"
"{\n"
" int b;\n"
" while (b = sizeof (struct foo { int i0;}))\n"
" ;\n"
" if (!(0 <= b ))\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void whileAssign3() {
// #4254 - Variable id
const char code[] = "void f() {\n"
" int a;\n"
" while (a = x());\n"
"}";
ASSERT_EQUALS("\n\n##file 0\n"
"1: void f ( ) {\n"
"2: int a@1 ;\n"
"3: a@1 = x ( ) ; while ( a@1 ) { ; a@1 = x ( ) ; }\n"
"4: }\n", tokenizeDebugListing(code, true, "test.c"));
}
void doWhileAssign() {
ASSERT_EQUALS("; do { a = b ; } while ( a ) ;", simplifyIfAndWhileAssign(";do { } while(a=b);"));
ASSERT_EQUALS("; do { a . a = 0 ; a . b = c ; } while ( a . b ) ;", simplifyIfAndWhileAssign(";do { a.a = 0; } while(a.b=c);"));
ASSERT_EQUALS("struct hfs_bnode * node ; "
"struct hfs_btree * tree ; "
"do { node = tree . node_hash [ i ++ ] ; } while ( node ) ;",
tok("struct hfs_bnode *node;"
"struct hfs_btree *tree;"
"do { } while((node = tree->node_hash[i++]));"));
ASSERT_EQUALS("char * s ; do { s = new char [ 10 ] ; } while ( ! s ) ;",
tok("char *s; do { } while (0 == (s=new char[10]));"));
// #4911
ASSERT_EQUALS("; do { current = f ( ) ; } while ( current ) ;", simplifyIfAndWhileAssign(";do { } while((current=f()) != NULL);"));
}
void ifnot() {
ASSERT_EQUALS("if ( ! x ) { ; }", tok("if(0==x);", false));
ASSERT_EQUALS("if ( ! x ) { ; }", tok("if(x==0);", false));
ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", tok("if(0==(a=b));", false));
ASSERT_EQUALS("if ( ! a && b ( ) ) { ; }", tok("if( 0 == a && b() );", false));
ASSERT_EQUALS("if ( b ( ) && ! a ) { ; }", tok("if( b() && 0 == a );", false));
ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", tok("if((a=b)==0);", false));
ASSERT_EQUALS("if ( ! x . y ) { ; }", tok("if(x.y==0);", false));
ASSERT_EQUALS("if ( ! x ) { ; }", tok("if((x==0));", false));
ASSERT_EQUALS("if ( ( ! x ) && ! y ) { ; }", tok("if((x==0) && y==0);", false));
ASSERT_EQUALS("if ( ! ( ! fclose ( fd ) ) ) { ; }", tok("if(!(fclose(fd) == 0));", false));
}
void not1() {
ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (not p);", false));
ASSERT_EQUALS("if ( p && ! q ) { ; }", tok("if (p && not q);", false));
ASSERT_EQUALS("void foo ( not i )", tok("void foo ( not i )", false));
}
void and1() {
ASSERT_EQUALS("if ( p && q ) { ; }",
tok("if (p and q) ;", false));
ASSERT_EQUALS("if ( foo ( ) && q ) { ; }",
tok("if (foo() and q) ;", false));
ASSERT_EQUALS("if ( foo ( ) && bar ( ) ) { ; }",
tok("if (foo() and bar()) ;", false));
ASSERT_EQUALS("if ( p && bar ( ) ) { ; }",
tok("if (p and bar()) ;", false));
ASSERT_EQUALS("if ( p && ! q ) { ; }",
tok("if (p and not q) ;", false));
}
void or1() {
ASSERT_EQUALS("if ( p || q ) { ; }",
tok("if (p or q) ;", false));
ASSERT_EQUALS("if ( foo ( ) || q ) { ; }",
tok("if (foo() or q) ;", false));
ASSERT_EQUALS("if ( foo ( ) || bar ( ) ) { ; }",
tok("if (foo() or bar()) ;", false));
ASSERT_EQUALS("if ( p || bar ( ) ) { ; }",
tok("if (p or bar()) ;", false));
ASSERT_EQUALS("if ( p || ! q ) { ; }",
tok("if (p or not q) ;", false));
}
void comma_keyword() {
{
const char code[] = "void foo()\n"
"{\n"
" char *a, *b;\n"
" delete a, delete b;\n"
"}\n";
ASSERT_EQUALS("void foo ( ) { char * a ; char * b ; delete a ; delete b ; }", tok(code));
}
{
const char code[] = "void foo()\n"
"{\n"
" struct A *a, *b;\n"
"}\n";
ASSERT_EQUALS("void foo ( ) { struct A * a ; struct A * b ; }", tok(code));
}
{
const char code[] = "void foo()\n"
"{\n"
" struct A **a, **b;\n"
"}\n";
ASSERT_EQUALS("void foo ( ) { struct A * * a ; struct A * * b ; }", tok(code));
}
{
const char code[] = "void foo()\n"
"{\n"
" char *a, *b;\n"
" delete a, b;\n"
"}\n";
ASSERT_EQUALS("void foo ( ) { char * a ; char * b ; delete a ; delete b ; }", tok(code));
}
{
const char code[] = "void foo()\n"
"{\n"
" char **a, **b, **c;\n"
"}\n";
ASSERT_EQUALS("void foo ( ) { char * * a ; char * * b ; char * * c ; }", tok(code));
}
{
const char code[] = "int f()\n"
"{\n"
" if (something)\n"
" return a(2, c(3, 4)), b(3), 10;\n"
" return a(), b(0, 0, 0), 10;\n"
"}\n";
ASSERT_EQUALS("int f ( )"
" {"
" if ( something )"
" {"
" a ( 2 , c ( 3 , 4 ) ) ;"
" b ( 3 ) ;"
" return 10 ;"
" }"
" a ( ) ;"
" b ( 0 , 0 , 0 ) ;"
" return 10 ; "
"}", tok(code));
}
{
const char code[] = "void foo()\n"
"{\n"
" delete [] a, a = 0;\n"
"}\n";
ASSERT_EQUALS("void foo ( ) { delete [ ] a ; a = 0 ; }", tok(code));
}
{
const char code[] = "void foo()\n"
"{\n"
" delete a, a = 0;\n"
"}\n";
ASSERT_EQUALS("void foo ( ) { delete a ; a = 0 ; }", tok(code));
}
{
const char code[] = "void f()\n"
"{\n"
" for(int a,b; a < 10; a = a + 1, b = b + 1);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { for ( int a , b ; a < 10 ; a = a + 1 , b = b + 1 ) { ; } }", tok(code));
}
{
const char code[] = "void f()\n"
"{\n"
" char buf[BUFSIZ], **p;\n"
" char *ptrs[BUFSIZ], **pp;\n"
"}\n";
ASSERT_EQUALS("void f ( ) { char buf [ BUFSIZ ] ; char * * p ; char * ptrs [ BUFSIZ ] ; char * * pp ; }", tok(code));
}
{
// #4786 - don't replace , with ; in ".. : public B, C .." code
const char code[] = "template < class T = X > class A : public B , C { } ;";
ASSERT_EQUALS(code, tok(code));
}
}
void remove_comma() {
{
const char code[] = "void f()\n"
"{\n"
" int a,b;\n"
" if( a )\n"
" a=0,\n"
" b=0;\n"
"}\n";
ASSERT_EQUALS("void f ( ) { int a ; int b ; if ( a ) { a = 0 ; b = 0 ; } }", tok(code));
}
{
const char code[] = "void f()\n"
"{\n"
" A a,b;\n"
" if( a.f )\n"
" a.f=b.f,\n"
" a.g=b.g;\n"
"}\n";
ASSERT_EQUALS("void f ( ) { A a ; A b ; if ( a . f ) { a . f = b . f ; a . g = b . g ; } }", tok(code));
}
// keep the comma in template specifiers..
{
const char code[] = "void f()\n"
"{\n"
" int a = b, int>();\n"
"}\n";
ASSERT_EQUALS("void f ( ) { int a ; a = b < T < char , 3 > , int > ( ) ; }", tok(code));
}
{
// ticket #1327
const char code[] = "const C<1,2,3> foo ()\n"
"{\n"
" return C<1,2,3>(x,y);\n"
"}\n";
const char expected[] = "const C < 1 , 2 , 3 > foo ( ) "
"{"
" return C < 1 , 2 , 3 > ( x , y ) ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "int foo ()\n"
"{\n"
" return doSomething(), 0;\n"
"}\n";
const char expected[] = "int foo ( ) "
"{"
" doSomething ( ) ; return 0 ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
}
void simplifyConditionOperator() {
{
const char code[] = "; x = a ? b : c;";
ASSERT_EQUALS("; if ( a ) { x = b ; } else { x = c ; }", tok(code));
}
{
const char code[] = "(0?(false?1:2):3)";
ASSERT_EQUALS("( 3 )", tok(code));
}
{
const char code[] = "(1?(false?1:2):3)";
ASSERT_EQUALS("( 2 )", tok(code));
}
{
const char code[] = "int a = (1?0:1 == 1?0:1);";
ASSERT_EQUALS("int a ; a = 0 ;", tok(code));
}
{
const char code[] = "(1?0:foo())";
ASSERT_EQUALS("( 0 )", tok(code));
}
{
const char code[] = "void f () { switch(n) { case 1?0:foo(): break; }}";
ASSERT_EQUALS("void f ( ) { switch ( n ) { case 0 : ; break ; } }", tok(code));
}
{
const char code[] = "void f () { switch(n) { case 1?0?1:0:foo(): break; }}";
ASSERT_EQUALS("void f ( ) { switch ( n ) { case 0 : ; break ; } }", tok(code));
}
{
const char code[] = "void f () { switch(n) { case 0?foo():1: break; }}";
ASSERT_EQUALS("void f ( ) { switch ( n ) { case 1 : ; break ; } }", tok(code));
}
{
const char code[] = "( true ? a ( ) : b ( ) )";
ASSERT_EQUALS("( a ( ) )", tok(code));
}
{
const char code[] = "( true ? abc . a : abc . b )";
ASSERT_EQUALS("( abc . a )", tok(code));
}
{
const char code[] = "void f()\n"
"{\n"
" bool x = false;\n"
" int b = x ? 44 : 3;\n"
"}\n";
ASSERT_EQUALS("void f ( ) { }", tok(code));
}
{
const char code[] = "int vals[] = { 0x13, 1?0x01:0x00 };";
ASSERT_EQUALS("int vals [ 2 ] = { 19 , 1 } ;", tok(code));
}
{
const char code[] = "int vals[] = { 0x13, 0?0x01:0x00 };";
ASSERT_EQUALS("int vals [ 2 ] = { 19 , 0 } ;", tok(code));
}
{
const char code[] = "= 1 ? 0 : ({ 0; });";
ASSERT_EQUALS("= 0 ;", tok(code));
}
//GNU extension: "x ?: y" <-> "x ? x : y"
{
const char code[] = "; a = 1 ? : x; b = 0 ? : 2;";
ASSERT_EQUALS("; a = 1 ; b = 2 ;", tok(code));
}
{
const char code[] = "int f(int b, int d)\n"
"{\n"
" d = b ? b : 10;\n"
" return d;\n"
"}\n";
ASSERT_EQUALS("int f ( int b , int d ) { if ( b ) { d = b ; } else { d = 10 ; } return d ; }", tok(code));
}
{
const char code[] = "int f(int b, int *d)\n"
"{\n"
" *d = b ? b : 10;\n"
" return *d;\n"
"}\n";
ASSERT_EQUALS("int f ( int b , int * d ) { if ( b ) { * d = b ; } else { * d = 10 ; } return * d ; }", tok(code));
}
{
const char code[] = "int f(int b, int *d)\n"
"{\n"
" if(b) {b++;}"
" *d = b ? b : 10;\n"
" return *d;\n"
"}\n";
ASSERT_EQUALS("int f ( int b , int * d ) { if ( b ) { b ++ ; } if ( b ) { * d = b ; } else { * d = 10 ; } return * d ; }", tok(code));
}
{
// Ticket #2885
const char code[] = "; const char *cx16 = has_cmpxchg16b ? \" -mcx16\" : \" -mno-cx16\";";
const char expected[] = "; const char * cx16 ; if ( has_cmpxchg16b ) { cx16 = \" -mcx16\" ; } else { cx16 = \" -mno-cx16\" ; }";
ASSERT_EQUALS(expected, tok(code));
}
// Ticket #3572 (segmentation fault)
ASSERT_EQUALS("0 ; x = { ? y : z ; }", tok("0; x = { ? y : z; }"));
{
// #4019 - varid
const char code[] = "; char *p; *p = a ? 1 : 0;";
const char expected[] = "\n\n##file 0\n"
"1: ; char * p@1 ; if ( a ) { * p@1 = 1 ; } else { * p@1 = 0 ; }\n";
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
}
{
// #3922 - (true)
ASSERT_EQUALS("; x = 2 ;", tok("; x = (true)?2:4;"));
ASSERT_EQUALS("; x = 4 ;", tok("; x = (false)?2:4;"));
ASSERT_EQUALS("; x = * a ;", tok("; x = (true)?*a:*b;"));
ASSERT_EQUALS("; x = * b ;", tok("; x = (false)?*a:*b;"));
ASSERT_EQUALS("void f ( ) { return 1 ; }", tok("void f() { char *p=0; return (p==0)?1:2; }"));
}
// 4225 - varid gets lost
ASSERT_EQUALS("\n\n##file 0\n"
"1: int a@1 ; int b@2 ; int c@3 ; int d@4 ; if ( b@2 ) { a@1 = c@3 ; } else { a@1 = d@4 ; }\n",
tokenizeDebugListing("int a, b, c, d; a = b ? (int *)c : d;", true));
}
void calculations() {
{
const char code[] = "a[i+8+2]";
ASSERT_EQUALS("a [ i + 10 ]", tok(code));
}
{
const char code[] = "a[8+2+i]";
ASSERT_EQUALS("a [ 10 + i ]", tok(code));
}
{
const char code[] = "a[i + 2 * (2 * 4)]";
ASSERT_EQUALS("a [ i + 16 ]", tok(code));
}
{
const char code[] = "a[i + 100 - 90]";
ASSERT_EQUALS("a [ i + 10 ]", tok(code));
}
{
const char code[] = "a[1+1+1+1+1+1+1+1+1+1-2+5-3]";
ASSERT_EQUALS("a [ 10 ]", tok(code));
}
{
const char code[] = "a[10+10-10-10]";
ASSERT_EQUALS("a [ 0 ]", tok(code));
}
ASSERT_EQUALS("a [ 4 ] ;", tok("a[1+3|4];"));
ASSERT_EQUALS("x = 1 + 2 * y ;", tok("x=1+2*y;"));
ASSERT_EQUALS("x = 7 ;", tok("x=1+2*3;"));
ASSERT_EQUALS("x = 47185 ;", tok("x=(65536*72/100);"));
ASSERT_EQUALS("x = 900 ;", tok("x = 1500000 / ((145000 - 55000) * 1000 / 54000);"));
ASSERT_EQUALS("int a [ 8 ] ;", tok("int a[5+6/2];"));
ASSERT_EQUALS("int a [ 4 ] ;", tok("int a[(10)-1-5];"));
ASSERT_EQUALS("int a [ i - 9 ] ;", tok("int a[i - 10 + 1];"));
ASSERT_EQUALS("x = y ;", tok("x=0+y+0-0;"));
ASSERT_EQUALS("x = 0 ;", tok("x=0*y;"));
ASSERT_EQUALS("x = 501 ;", tok("x = 1000 + 2 >> 1;"));
ASSERT_EQUALS("x = 125 ;", tok("x = 1000 / 2 >> 2;"));
{
// Ticket #1997
const char code[] = "void * operator new[](size_t);";
ASSERT_EQUALS("void * operatornew[] ( long ) ;", tok(code, true, Settings::Win32A));
}
ASSERT_EQUALS("; a [ 0 ] ;", tok(";a[0*(*p)];"));
ASSERT_EQUALS(";", tok("; x = x + 0;"));
ASSERT_EQUALS("if ( a == 2 ) { ; }", tok("if (a==1+1);"));
ASSERT_EQUALS("if ( a + 2 != 6 ) { ; }", tok("if (a+1+1!=1+2+3);"));
ASSERT_EQUALS("if ( 4 < a ) { ; }", tok("if (14-2*5 2 && 3 > 4 ? 5 : 6 )"));
}
void goto1() {
{
const char code[] = "void foo()\n"
"{\n"
" if (a())\n"
" {\n"
" goto out;\n"
" }\n"
" b();\n"
"out:\n"
" c();\n"
"}";
errout.str("");
Settings settings;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList();
const char expect[] = "\n\n##file 0\n"
"1: void foo ( )\n"
"2: {\n"
"3: if ( a ( ) )\n"
"4: {\n"
"5:\n|\n8:\n"
"9: c ( ) ; return ; }\n"
"7: b ( ) ;\n"
"8:\n"
"9: c ( ) ;\n"
"10: }\n";
ASSERT_EQUALS(expect, tokenizer.tokens()->stringifyList());
}
{
const char code[] = "void foo()\n"
"{\n"
" if (a())\n"
" goto out;\n"
" b();\n"
"out:\n"
" if (c())\n"
" d();\n"
"}";
errout.str("");
Settings settings;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList();
const char expect[] = "\n\n##file 0\n"
"1: void foo ( )\n"
"2: {\n"
"3: if ( a ( ) ) {\n"
"4:\n5:\n6:\n"
"7: if ( c ( ) ) {\n"
"8: d ( ) ; } return ; }\n"
"5: b ( ) ;\n"
"6:\n"
"7: if ( c ( ) ) {\n"
"8: d ( ) ; }\n"
"9: }\n";
ASSERT_EQUALS(expect, tokenizer.tokens()->stringifyList());
}
{
const char code[] = "void foo()\n"
"{\n"
" if (a())\n"
" goto out;\n"
" b();\n"
"out:\n"
" if (c())\n"
" {\n"
" d();\n"
" }\n"
"}";
const char expect[] = "void foo ( ) "
"{ "
"if ( a ( ) ) "
"{ "
"if ( c ( ) ) "
"{ d ( ) ; } "
"return ; "
"} "
"b ( ) ; "
"if ( c ( ) ) "
"{ d ( ) ; } "
"}";
ASSERT_EQUALS(expect, tok(code));
}
{
const char code[] = "void foo(int x)\n"
"{\n"
" if (a())\n"
" goto out;\n"
" b();\n"
"out:\n"
" if (x)\n"
" {\n"
" x++; b[0]=x;\n"
" }\n"
"}";
const char expect[] = "void foo ( int x ) "
"{ "
"if ( a ( ) ) "
"{ "
"if ( x ) "
"{ x ++ ; b [ 0 ] = x ; } "
"return ; "
"} "
"b ( ) ; "
"if ( x ) "
"{ x ++ ; b [ 0 ] = x ; } "
"}";
ASSERT_EQUALS(expect, tok(code));
}
{
const char code[] = "class NoLabels { bool varOne : 1 ; bool varTwo : 1 ; } ;";
const char expect[] = "class NoLabels { bool varOne ; bool varTwo ; } ;";
ASSERT_EQUALS(expect, tok(code));
}
{
const char code[] = "void foo ( ) { int var ; var = x < y ? y : z ; } ;";
ASSERT_EQUALS(code, tok(code));
}
}
void goto2() {
// Don't simplify goto inside function call (macro)
const char code[] = "void f ( ) { slist_iter ( if ( a ) { goto dont_write ; } dont_write : ; x ( ) ; ) ; }";
ASSERT_EQUALS(code, tok(code));
//ticket #3229 (segmentation fault)
ASSERT_EQUALS("void f ( ) { MACRO ( return ; ) return ; }",tok("void f ( ) {goto label; label: MACRO(return;)}"));
}
void goto3() {
// Simplify goto inside the namespace|struct|class|union block
{
const char code[] = "namespace A1"
"{"
" void foo()"
" {"
" goto source ;"
" bleeh;"
" source:"
" boo();"
" }"
"}";
const char expected[] = "namespace A1 "
"{"
" void foo ( )"
" {"
" boo ( ) ; return ;"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "class A"
"{"
" int n,m;"
" A()"
" {"
" goto source ;"
" bleeh;"
" source:"
" boo();"
" }"
" void boo();"
"}";
const char expected[] = "class A "
"{"
" int n ; int m ;"
" A ( )"
" {"
" boo ( ) ; return ;"
" }"
" void boo ( ) ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "struct A"
"{"
" int n,m;"
" A() : m(0)"
" {"
" goto source;"
" bleeh;"
" source:"
" n=10;"
" }"
"}";
const char expected[] = "struct A "
"{"
" int n ; int m ;"
" A ( ) : m ( 0 )"
" {"
" n = 10 ; return ;"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "namespace A1"
"{"
" class A"
" {"
" int n,m;"
" A()"
" {"
" goto source ;"
" bleeh;"
" source:"
" boo();"
" }"
" void boo();"
" }"
"}";
const char expected[] = "namespace A1 "
"{"
" class A"
" {"
" int n ; int m ;"
" A ( )"
" {"
" boo ( ) ; return ;"
" }"
" void boo ( ) ;"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "namespace A1"
"{"
" namespace AA1"
" {"
" void foo1()"
" {"
" goto source1 ;"
" bleeh;"
" source1:"
" boo1();"
" }"
" }"
" namespace AA2"
" {"
" void foo2()"
" {"
" goto source2 ;"
" bleeh;"
" source2:"
" boo2();"
" }"
" }"
"}";
const char expected[] = "namespace A1 "
"{"
" namespace AA1"
" {"
" void foo1 ( )"
" {"
" boo1 ( ) ; return ;"
" }"
" }"
" namespace AA2"
" {"
" void foo2 ( )"
" {"
" boo2 ( ) ; return ;"
" }"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "union A1"
"{"
" int a; "
" double b; "
" A1() : b(3.22)"
" {"
" goto source ;"
" bleeh;"
" source:"
" a = 322;"
" }"
"}";
const char expected[] = "union A1 "
"{"
" int a ;"
" double b ;"
" A1 ( ) : b ( 3.22 )"
" {"
" a = 322 ; return ;"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "class A"
"{"
" int a; "
" double b; "
" A() : b(3.22)"
" {"
" goto source ;"
" bleeh;"
" source:"
" a = 322;"
" }"
"}"
"class A1 : public A"
"{"
" int a1; "
" double b1; "
" A1() : b1(3.22)"
" {"
" goto source1 ;"
" bleeh1;"
" source1:"
" a = 322;"
" }"
"}";
const char expected[] = "class A "
"{"
" int a ;"
" double b ;"
" A ( ) : b ( 3.22 )"
" {"
" a = 322 ;"
" return ;"
" } "
"} "
"class A1 : public A "
"{"
" int a1 ;"
" double b1 ;"
" A1 ( ) : b1 ( 3.22 )"
" {"
" a = 322 ;"
" return ;"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
}
void goto4() {
const char code[] = "int main()\n"
"{\n"
" goto SkipIncr;\n"
" do {\n"
" f();\n"
" SkipIncr:\n"
" printf(\".\");\n"
" } while (bar());\n"
"}\n";
const char expected[] = "int main ( ) "
"{"
" goto SkipIncr ;"
" do {"
" f ( ) ;"
" SkipIncr : ;"
" printf ( \".\" ) ;"
" } while ( bar ( ) ) ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
void goto5() {
const char code[] = "int foo() {\n"
" goto err;\n"
"err:\n"
" return ( { __asm__(X); } ); "
"}\n";
ASSERT_EQUALS("int foo ( ) {"
" return { asm ( \"X\" ) ; } ;"
" return { asm ( \"X\" ) ; } ; "
"}", tok(code));
}
void goto6() { // from code in linux that wasn't handled well
const char code1[] = "static void a() {\n"
"unlock:\n"
"}\n"
"\n"
"static void b() {\n"
" if (c)\n"
" goto defer;\n"
"defer:\n"
"}\n";
ASSERT_EQUALS("static void a ( ) { } "
"static void b ( ) { if ( c ) { return ; } }", tok(code1));
const char code2[] = "void a()\n"
"{\n"
" if (x) {}\n"
"unlock:\n"
"}\n"
"\n"
"void b()\n"
"{\n"
" { goto defer; }\n"
"defer:\n"
"}";
ASSERT_EQUALS("void a ( ) { if ( x ) { } } void b ( ) { return ; }", tok(code2));
}
void flowControl() {
std::list beforedead;
//beforedead.push_back("return");
//beforedead.push_back("throw ( 10 )");
beforedead.push_back("exit ( 0 )");
//beforedead.push_back("abort ( )");
//beforedead.push_back("goto labels");
//beforedead.push_back("break");
//beforedead.push_back("continue");
for (std::list::iterator it = beforedead.begin(); it != beforedead.end(); ++it) {
{
ASSERT_EQUALS("void f ( ) { " + *it + " ; }", tok("void f() { " + *it + "; foo(); }"));
ASSERT_EQUALS("void f ( ) { " + *it + " ; }", tok("void f() { " + *it + "; if (m) foo(); }"));
ASSERT_EQUALS("void f ( int n ) { if ( n ) { " + *it + " ; } foo ( ) ; }",tok("void f(int n) { if (n) { " + *it + "; } foo(); }"));
ASSERT_EQUALS("void f ( ) { " + *it + " ; }", tok("void f() { " + *it + "; dead(); switch (n) { case 1: deadcode () ; default: deadcode (); } }"));
ASSERT_EQUALS("int f ( int n ) { switch ( n ) { case 0 : ; " + *it + " ; default : ; " + *it + " ; } " + *it + " ; }",
tok("int f(int n) { switch (n) {case 0: " + *it + "; n*=2; default: " + *it + "; n*=6;} " + *it + "; foo();}"));
//ticket #3132
ASSERT_EQUALS("void f ( int i ) { goto label ; { label : ; " + *it + " ; } }",tok("void f (int i) { goto label; switch(i) { label: " + *it + "; } }"));
//ticket #3148
ASSERT_EQUALS("void f ( ) { MACRO ( " + *it + " ) }",tok("void f() { MACRO(" + *it + ") }"));
ASSERT_EQUALS("void f ( ) { MACRO ( " + *it + " ; , NULL ) }",tok("void f() { MACRO(" + *it + ";, NULL) }"));
ASSERT_EQUALS("void f ( ) { MACRO ( bar1 , " + *it + " ) }",tok("void f() { MACRO(bar1, " + *it + ") }"));
ASSERT_EQUALS("void f ( ) { MACRO ( " + *it + " ; bar2 , foo ) }",tok("void f() { MACRO(" + *it + "; bar2, foo) }"));
}
{
std::string code = "void f(){ "
" if (k>0) goto label; "
" " + *it + "; "
" if (tnt) "
" { "
" { "
" check(); "
" k=0; "
" } "
" label: "
" bar(); "
" } "
"}";
ASSERT_EQUALS("void f ( ) { if ( 0 < k ) { goto label ; } " + *it + " ; { label : ; bar ( ) ; } }",tok(code));
}
{
std::string code = "void foo () {"
" " + *it + ";"
" {"
" boo();"
" while (n) { --n; }"
" {"
" label:"
" ok();"
" }"
" }"
"}";
ASSERT_EQUALS("void foo ( ) { " + *it + " ; { label : ; ok ( ) ; } }", tok(code));
}
{
std::string code = "void foo () {"
" " + *it + ";"
" switch (n) {"
" case 1:"
" label:"
" foo(); break;"
" default:"
" break;"
" }"
"}";
std::string expected = "void foo ( ) { " + *it + " ; { label : ; foo ( ) ; break ; } }";
ASSERT_EQUALS(expected, tok(code));
}
{
std::string code = "void foo () {"
" " + *it + ";"
" switch (n) {"
" case 1:"
" {"
" foo();"
" }"
" label:"
" bar();"
" }"
"}";
std::string expected = "void foo ( ) { " + *it + " ; { label : ; bar ( ) ; } }";
ASSERT_EQUALS(expected, tok(code));
}
{
std::string code = "void foo () {"
" " + *it + ";"
" switch (n) {"
" case a:"
" {"
" foo();"
" }"
" case b|c:"
" bar();"
" }"
"}";
std::string expected = "void foo ( ) { " + *it + " ; }";
ASSERT_EQUALS(expected, tok(code));
}
{
std::string code = "void foo () {"
" " + *it + ";"
" switch (n) {"
" case 1:"
" label:"
" foo(); break;"
" default:"
" break; break;"
" }"
"}";
std::string expected = "void foo ( ) { " + *it + " ; { label : ; foo ( ) ; break ; } }";
ASSERT_EQUALS(expected, tok(code));
}
{
std::string code = "void foo () {"
" " + *it + ";"
" switch (n) {"
" case 1:"
" label:"
" foo(); break; break;"
" default:"
" break;"
" }"
"}";
std::string expected = "void foo ( ) { " + *it + " ; { label : ; foo ( ) ; break ; } }";
ASSERT_EQUALS(expected, tok(code));
}
{
std::string code = "void foo () {"
" " + *it + ";"
" switch (n) {"
" case 1:"
" label:"
" foo(); break; break;"
" default:"
" break; break;"
" }"
"}";
std::string expected = "void foo ( ) { " + *it + " ; { label : ; foo ( ) ; break ; } }";
ASSERT_EQUALS(expected, tok(code));
}
{
std::string code = "int f() { "
"switch (x) { case 1: " + *it + "; bar(); tack; { ticak(); " + *it + " } " + *it + ";"
"case 2: " + *it + "; { random(); } tack(); "
"switch(y) { case 1: " + *it + "; case 2: " + *it + "; } "
"" + *it + "; } " + *it + "; }";
ASSERT_EQUALS("int f ( ) { switch ( x ) { case 1 : ; " + *it + " ; case 2 : ; " + *it + " ; } " + *it + " ; }",tok(code));
}
{
std::string code = "int f() {"
"switch (x) { case 1: " + *it + "; bar(); tack; { ticak(); " + *it + "; } " + *it + ";"
"case 2: switch(y) { case 1: " + *it + "; bar2(); foo(); case 2: " + *it + "; }"
"" + *it + "; } " + *it + "; }";
std::string expected = "int f ( ) {"
" switch ( x ) { case 1 : ; " + *it + " ;"
" case 2 : ; switch ( y ) { case 1 : ; " + *it + " ; case 2 : ; " + *it + " ; }"
" " + *it + " ; } " + *it + " ; }";
ASSERT_EQUALS(expected,tok(code));
}
{
std::string code = "void foo () {"
" switch (i) { case 0: switch (j) { case 0: " + *it + "; }"
" case 1: switch (j) { case -1: " + *it + "; }"
" case 2: switch (j) { case -2: " + *it + "; }"
" case 3: if (blah6) {" + *it + ";} break; } }";
std::string expected = "void foo ( ) {"
" switch ( i ) { case 0 : ; switch ( j ) { case 0 : ; " + *it + " ; }"
" case 1 : ; switch ( j ) { case -1 : ; " + *it + " ; }"
" case 2 : ; switch ( j ) { case -2 : ; " + *it + " ; }"
" case 3 : ; if ( blah6 ) { " + *it + " ; } break ; } }";
ASSERT_EQUALS(expected, tok(code));
}
{
std::string code = "void foo () {"
" " + *it + ";"
" switch (i) { case 0: switch (j) { case 0: foo(); }"
" case 1: switch (j) { case -1: bar(); label:; ok(); }"
" case 3: if (blah6) { boo(); break; } } }";
std::string expected = "void foo ( ) { " + *it + " ; { { label : ; ok ( ) ; } case 3 : ; if ( blah6 ) { boo ( ) ; break ; } } }";
ASSERT_EQUALS(expected, tok(code));
}
{
std::string code = "void foo() {"
" switch ( t ) {"
" case 0:"
" if ( t ) switch ( b ) {}"
" break;"
" case 1:"
" " + *it + ";"
" return 0;"
" }"
" return 0;"
"}";
std::string expected = "void foo ( ) {"
" switch ( t ) {"
" case 0 : ;"
" if ( t ) { switch ( b ) { } }"
" break ;"
" case 1 : ;"
" " + *it + " ;"
" }"
" return 0 ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
}
{
const char code[] = "void foo()\n"
"{\n"
" A *a = 0;\n"
" if (!a) {\n"
" nondeadcode;\n"
" return;\n"
" dead;\n"
" }\n"
" stilldead;\n"
" a->_a;\n"
"}\n";
const char expected[] = "void foo ( ) "
"{"
" A * a ; a = 0 ; {"
" nondeadcode ;"
" return ;"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "class Fred\n"
"{\n"
"public:\n"
" bool foo() const { return f; }\n"
" bool exit();\n"
"\n"
"private:\n"
" bool f;\n"
"};\n";
const char expected[] = "class Fred "
"{"
" public:"
" bool foo ( ) const { return f ; }"
" bool exit ( ) ;"
""
" private:"
" bool f ; "
"} ;";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "class abort { };\n"
"\n"
"class Fred\n"
"{\n"
" public:\n"
" bool foo() const { return f; }\n"
" abort exit();\n"
"\n"
" private:\n"
"bool f;\n"
"};\n";
const char expected[] = "class abort { } ; "
"class Fred "
"{"
" public:"
" bool foo ( ) const { return f ; }"
" abort exit ( ) ;"
""
" private:"
" bool f ; "
"} ;";
ASSERT_EQUALS(expected, tok(code));
}
}
void strcat1() {
const char code[] = "; strcat(strcat(strcat(strcat(strcat(strcat(dst, \"this \"), \"\"), \"is \"), \"a \"), \"test\"), \".\");";
const char expect[] = "; "
"strcat ( dst , \"this \" ) ; "
"strcat ( dst , \"\" ) ; "
"strcat ( dst , \"is \" ) ; "
"strcat ( dst , \"a \" ) ; "
"strcat ( dst , \"test\" ) ; "
"strcat ( dst , \".\" ) ;";
ASSERT_EQUALS(expect, tok(code));
}
void strcat2() {
const char code[] = "; strcat(strcat(dst, foo[0]), \" \");";
const char expect[] = "; "
"strcat ( dst , foo [ 0 ] ) ; "
"strcat ( dst , \" \" ) ;";
ASSERT_EQUALS(expect, tok(code));
}
void simplifyAtol() {
ASSERT_EQUALS("a = std :: atol ( x ) ;", tok("a = std::atol(x);"));
ASSERT_EQUALS("a = atol ( \"text\" ) ;", tok("a = atol(\"text\");"));
ASSERT_EQUALS("a = 0 ;", tok("a = std::atol(\"0\");"));
ASSERT_EQUALS("a = 10 ;", tok("a = atol(\"0xa\");"));
}
std::string simplifyTypedef(const char code[]) {
errout.str("");
Settings settings;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.list.createTokens(istr);
tokenizer.createLinks();
tokenizer.simplifyTypedef();
return tokenizer.tokens()->stringifyList(0, false);
}
void simplifyTypedef1() {
const char code[] = "class A\n"
"{\n"
"public:\n"
" typedef wchar_t duplicate;\n"
" void foo() {}\n"
"};\n"
"typedef A duplicate;\n"
"int main()\n"
"{\n"
" duplicate a;\n"
" a.foo();\n"
" A::duplicate c = 0;\n"
"}\n";
const std::string expected =
"class A "
"{ "
"public: "
""
"void foo ( ) { } "
"} ; "
"int main ( ) "
"{ "
"A a ; "
"a . foo ( ) ; "
"wchar_t c ; c = 0 ; "
"}";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef2() {
const char code[] = "class A;\n"
"typedef A duplicate;\n"
"class A\n"
"{\n"
"public:\n"
"typedef wchar_t duplicate;\n"
"duplicate foo() { wchar_t b; return b; }\n"
"};\n";
const std::string expected =
"class A ; "
"class A "
"{ "
"public: "
""
"wchar_t foo ( ) { wchar_t b ; return b ; } "
"} ;";
ASSERT_EQUALS(expected, tok(code));
}
void simplifyTypedef3() {
const char code[] = "class A {};\n"
"typedef A duplicate;\n"
"wchar_t foo()\n"
"{\n"
"typedef wchar_t duplicate;\n"
"duplicate b;\n"
"return b;\n"
"}\n"
"int main()\n"
"{\n"
"duplicate b;\n"
"}\n";
const std::string expected =
"class A { } ; "
"wchar_t foo ( ) "
"{ "
""
"wchar_t b ; "
"return b ; "
"} "
"int main ( ) "
"{ "
"A b ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
void simplifyTypedef4() {
const char code[] = "typedef int s32;\n"
"typedef unsigned int u32;\n"
"void f()\n"
"{\n"
" s32 ivar = -2;\n"
" u32 uvar = 2;\n"
" return uvar / ivar;\n"
"}\n";
const std::string expected =
"void f ( ) "
"{ "
"int ivar ; ivar = -2 ; "
"unsigned int uvar ; uvar = 2 ; "
"return uvar / ivar ; "
"}";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef5() {
// ticket #780
const char code[] =
"typedef struct yy_buffer_state *YY_BUFFER_STATE;\n"
"void f()\n"
"{\n"
" YY_BUFFER_STATE state;\n"
"}\n";
const char expected[] =
"void f ( ) "
"{ "
"struct yy_buffer_state * state ; "
"}";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef6() {
// ticket #983
const char code[] =
"namespace VL {\n"
" typedef float float_t ;\n"
" inline VL::float_t fast_atan2(VL::float_t y, VL::float_t x){}\n"
"}\n";
const char expected[] =
"namespace VL { "
""
"float fast_atan2 ( float y , float x ) { } "
"}";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef7() {
const char code[] = "typedef int abc ; "
"Fred :: abc f ;";
const char expected[] = "Fred :: abc f ;";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef8() {
const char code[] = "typedef int INT;\n"
"typedef unsigned int UINT;\n"
"typedef int * PINT;\n"
"typedef unsigned int * PUINT;\n"
"typedef int & RINT;\n"
"typedef unsigned int & RUINT;\n"
"typedef const int & RCINT;\n"
"typedef const unsigned int & RCUINT;\n"
"INT ti;\n"
"UINT tui;\n"
"PINT tpi;\n"
"PUINT tpui;\n"
"RINT tri;\n"
"RUINT trui;\n"
"RCINT trci;\n"
"RCUINT trcui;";
const char expected[] =
"int ti ; "
"unsigned int tui ; "
"int * tpi ; "
"unsigned int * tpui ; "
"int & tri ; "
"unsigned int & trui ; "
"const int & trci ; "
"const unsigned int & trcui ;";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef9() {
const char code[] = "typedef struct s S, * PS;\n"
"typedef struct t { int a; } T, *TP;\n"
"typedef struct { int a; } U;\n"
"typedef struct { int a; } * V;\n"
"S s;\n"
"PS ps;\n"
"T t;\n"
"TP tp;\n"
"U u;\n"
"V v;";
const char expected[] =
"struct t { int a ; } ; "
"struct U { int a ; } ; "
"struct Unnamed0 { int a ; } ; "
"struct s s ; "
"struct s * ps ; "
"struct t t ; "
"struct t * tp ; "
"struct U u ; "
"struct Unnamed0 * v ;";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef10() {
const char code[] = "typedef union s S, * PS;\n"
"typedef union t { int a; float b ; } T, *TP;\n"
"typedef union { int a; float b; } U;\n"
"typedef union { int a; float b; } * V;\n"
"S s;\n"
"PS ps;\n"
"T t;\n"
"TP tp;\n"
"U u;\n"
"V v;";
const char expected[] =
"union t { int a ; float b ; } ; "
"union U { int a ; float b ; } ; "
"union Unnamed1 { int a ; float b ; } ; "
"union s s ; "
"union s * ps ; "
"union t t ; "
"union t * tp ; "
"union U u ; "
"union Unnamed1 * v ;";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef11() {
const char code[] = "typedef enum { a = 0 , b = 1 , c = 2 } abc;\n"
"typedef enum xyz { x = 0 , y = 1 , z = 2 } XYZ;\n"
"abc e1;\n"
"XYZ e2;";
const char expected[] = "int e1 ; "
"int e2 ;";
ASSERT_EQUALS(expected, tok(code, false));
}
void simplifyTypedef12() {
const char code[] = "typedef vector