8714 lines
394 KiB
C++
8714 lines
394 KiB
C++
/*
|
||
* Cppcheck - A tool for static C/C++ code analysis
|
||
* Copyright (C) 2007-2020 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
#include "platform.h"
|
||
#include "preprocessor.h" // usually tests here should not use preprocessor...
|
||
#include "settings.h"
|
||
#include "standards.h"
|
||
#include "testsuite.h"
|
||
#include "token.h"
|
||
#include "tokenize.h"
|
||
#include "tokenlist.h"
|
||
|
||
#include <list>
|
||
#include <set>
|
||
#include <sstream>
|
||
#include <string>
|
||
|
||
struct InternalError;
|
||
|
||
class TestTokenizer : public TestFixture {
|
||
public:
|
||
TestTokenizer() : TestFixture("TestTokenizer") {
|
||
}
|
||
|
||
private:
|
||
Settings settings0;
|
||
Settings settings1;
|
||
Settings settings2;
|
||
Settings settings_windows;
|
||
|
||
void run() OVERRIDE {
|
||
LOAD_LIB_2(settings_windows.library, "windows.cfg");
|
||
|
||
// If there are unused templates, keep those
|
||
settings0.checkUnusedTemplates = true;
|
||
settings1.checkUnusedTemplates = true;
|
||
settings2.checkUnusedTemplates = true;
|
||
settings_windows.checkUnusedTemplates = true;
|
||
|
||
TEST_CASE(tokenize1);
|
||
TEST_CASE(tokenize2);
|
||
TEST_CASE(tokenize4);
|
||
TEST_CASE(tokenize5);
|
||
TEST_CASE(tokenize6); // array access. replace "*(p+1)" => "p[1]"
|
||
TEST_CASE(tokenize7);
|
||
TEST_CASE(tokenize8);
|
||
TEST_CASE(tokenize9);
|
||
TEST_CASE(tokenize11);
|
||
TEST_CASE(tokenize13); // bailout if the code contains "@" - that is not handled well.
|
||
TEST_CASE(tokenize14); // tokenize "0X10" => 16
|
||
TEST_CASE(tokenizeHexWithSuffix); // tokenize 0xFFFFFFul
|
||
TEST_CASE(tokenize15); // tokenize ".123"
|
||
TEST_CASE(tokenize17); // #2759
|
||
TEST_CASE(tokenize18); // tokenize "(X&&Y)" into "( X && Y )" instead of "( X & & Y )"
|
||
TEST_CASE(tokenize19); // #3006 (segmentation fault)
|
||
TEST_CASE(tokenize21); // tokenize 0x0E-7
|
||
TEST_CASE(tokenize22); // special marker $ from preprocessor
|
||
TEST_CASE(tokenize25); // #4239 (segmentation fault)
|
||
TEST_CASE(tokenize26); // #4245 (segmentation fault)
|
||
TEST_CASE(tokenize27); // #4525 (segmentation fault)
|
||
TEST_CASE(tokenize31); // #3503 (Wrong handling of member function taking function pointer as argument)
|
||
TEST_CASE(tokenize32); // #5884 (fsanitize=undefined: left shift of negative value -10000 in lib/templatesimplifier.cpp:852:46)
|
||
TEST_CASE(tokenize33); // #5780 Various crashes on valid template code
|
||
TEST_CASE(tokenize34); // #8031
|
||
TEST_CASE(tokenize35); // #8361
|
||
TEST_CASE(tokenize36); // #8436
|
||
TEST_CASE(tokenize37); // #8550
|
||
TEST_CASE(tokenize38); // #9569
|
||
TEST_CASE(tokenize39); // #9771
|
||
|
||
TEST_CASE(validate);
|
||
|
||
TEST_CASE(objectiveC); // Syntax error should be written for objective C/C++ code.
|
||
|
||
TEST_CASE(syntax_case_default);
|
||
|
||
TEST_CASE(removePragma);
|
||
|
||
TEST_CASE(foreach); // #3690
|
||
TEST_CASE(ifconstexpr);
|
||
|
||
TEST_CASE(combineOperators);
|
||
|
||
TEST_CASE(concatenateNegativeNumber);
|
||
|
||
TEST_CASE(longtok);
|
||
|
||
TEST_CASE(simplifyHeadersAndUnusedTemplates1);
|
||
TEST_CASE(simplifyHeadersAndUnusedTemplates2);
|
||
|
||
TEST_CASE(simplifyCasts1);
|
||
TEST_CASE(simplifyCasts2);
|
||
TEST_CASE(simplifyCasts3);
|
||
TEST_CASE(simplifyCasts4);
|
||
TEST_CASE(simplifyCasts5);
|
||
TEST_CASE(simplifyCasts7);
|
||
TEST_CASE(simplifyCasts8);
|
||
TEST_CASE(simplifyCasts9);
|
||
TEST_CASE(simplifyCasts10);
|
||
TEST_CASE(simplifyCasts11);
|
||
TEST_CASE(simplifyCasts12);
|
||
TEST_CASE(simplifyCasts13);
|
||
TEST_CASE(simplifyCasts14);
|
||
TEST_CASE(simplifyCasts15); // #5996 - don't remove cast in 'a+static_cast<int>(b?60:0)'
|
||
TEST_CASE(simplifyCasts16); // #6278
|
||
TEST_CASE(simplifyCasts17); // #6110 - don't remove any parentheses in 'a(b)(c)'
|
||
|
||
TEST_CASE(simplifyAt);
|
||
|
||
TEST_CASE(inlineasm);
|
||
TEST_CASE(simplifyAsm2); // #4725 (writing asm() around "^{}")
|
||
|
||
TEST_CASE(ifAddBraces1);
|
||
TEST_CASE(ifAddBraces2);
|
||
TEST_CASE(ifAddBraces3);
|
||
TEST_CASE(ifAddBraces4);
|
||
TEST_CASE(ifAddBraces5);
|
||
TEST_CASE(ifAddBraces7);
|
||
TEST_CASE(ifAddBraces9);
|
||
TEST_CASE(ifAddBraces11);
|
||
TEST_CASE(ifAddBraces12);
|
||
TEST_CASE(ifAddBraces13);
|
||
TEST_CASE(ifAddBraces15); // #2616 - unknown macro before if
|
||
TEST_CASE(ifAddBraces16);
|
||
TEST_CASE(ifAddBraces17); // '} else' should be in the same line
|
||
TEST_CASE(ifAddBraces18); // #3424 - if if { } else else
|
||
TEST_CASE(ifAddBraces19); // #3928 - if for if else
|
||
TEST_CASE(ifAddBraces20); // #5012 - syntax error 'else }'
|
||
TEST_CASE(ifAddBraces21); // #5332 - if (x) label: {} ..
|
||
|
||
TEST_CASE(whileAddBraces);
|
||
TEST_CASE(doWhileAddBraces);
|
||
|
||
TEST_CASE(forAddBraces1);
|
||
TEST_CASE(forAddBraces2); // #5088
|
||
|
||
TEST_CASE(simplifyKnownVariables1);
|
||
TEST_CASE(simplifyKnownVariables2);
|
||
TEST_CASE(simplifyKnownVariables3);
|
||
TEST_CASE(simplifyKnownVariables4);
|
||
TEST_CASE(simplifyKnownVariables5);
|
||
TEST_CASE(simplifyKnownVariables6);
|
||
TEST_CASE(simplifyKnownVariables7);
|
||
TEST_CASE(simplifyKnownVariables8);
|
||
TEST_CASE(simplifyKnownVariables9);
|
||
TEST_CASE(simplifyKnownVariables10);
|
||
TEST_CASE(simplifyKnownVariables11);
|
||
TEST_CASE(simplifyKnownVariables13);
|
||
TEST_CASE(simplifyKnownVariables14);
|
||
TEST_CASE(simplifyKnownVariables15);
|
||
TEST_CASE(simplifyKnownVariables16);
|
||
TEST_CASE(simplifyKnownVariables17);
|
||
TEST_CASE(simplifyKnownVariables18);
|
||
TEST_CASE(simplifyKnownVariables19);
|
||
TEST_CASE(simplifyKnownVariables20);
|
||
TEST_CASE(simplifyKnownVariables21);
|
||
TEST_CASE(simplifyKnownVariables22);
|
||
TEST_CASE(simplifyKnownVariables23);
|
||
TEST_CASE(simplifyKnownVariables25);
|
||
TEST_CASE(simplifyKnownVariables27);
|
||
TEST_CASE(simplifyKnownVariables28);
|
||
TEST_CASE(simplifyKnownVariables29); // ticket #1811
|
||
TEST_CASE(simplifyKnownVariables30);
|
||
TEST_CASE(simplifyKnownVariables31);
|
||
TEST_CASE(simplifyKnownVariables32); // const
|
||
TEST_CASE(simplifyKnownVariables33); // struct variable
|
||
TEST_CASE(simplifyKnownVariables34);
|
||
TEST_CASE(simplifyKnownVariables35); // ticket #2353 - False positive: Division by zero 'if (x == 0) return 0; return 10 / x;'
|
||
TEST_CASE(simplifyKnownVariables36); // ticket #2304 - known value for strcpy parameter
|
||
TEST_CASE(simplifyKnownVariables37); // ticket #2398 - false positive caused by no simplification in for loop
|
||
TEST_CASE(simplifyKnownVariables38); // ticket #2399 - simplify conditions
|
||
TEST_CASE(simplifyKnownVariables39);
|
||
TEST_CASE(simplifyKnownVariables40);
|
||
TEST_CASE(simplifyKnownVariables41); // p=&x; if (p) ..
|
||
TEST_CASE(simplifyKnownVariables42); // ticket #2031 - known string value after strcpy
|
||
TEST_CASE(simplifyKnownVariables43);
|
||
TEST_CASE(simplifyKnownVariables44); // ticket #3117 - don't simplify static variables
|
||
TEST_CASE(simplifyKnownVariables45); // ticket #3281 - static constant variable not simplified
|
||
TEST_CASE(simplifyKnownVariables46); // ticket #3587 - >>
|
||
TEST_CASE(simplifyKnownVariables47); // ticket #3627 - >>
|
||
TEST_CASE(simplifyKnownVariables48); // ticket #3754 - wrong simplification in for loop header
|
||
TEST_CASE(simplifyKnownVariables49); // #3691 - continue in switch
|
||
TEST_CASE(simplifyKnownVariables50); // #4066 sprintf changes
|
||
TEST_CASE(simplifyKnownVariables51); // #4409 hang
|
||
TEST_CASE(simplifyKnownVariables52); // #4728 "= x %cop%"
|
||
TEST_CASE(simplifyKnownVariables53); // references
|
||
TEST_CASE(simplifyKnownVariables54); // #4913 'x' is not 0 after *--x=0;
|
||
TEST_CASE(simplifyKnownVariables55); // pointer alias
|
||
TEST_CASE(simplifyKnownVariables56); // ticket #5301 - >>
|
||
TEST_CASE(simplifyKnownVariables57); // ticket #4724
|
||
TEST_CASE(simplifyKnownVariables58); // ticket #5268
|
||
TEST_CASE(simplifyKnownVariables59); // skip for header
|
||
TEST_CASE(simplifyKnownVariables60); // #6829
|
||
TEST_CASE(simplifyKnownVariables61); // #7805
|
||
TEST_CASE(simplifyKnownVariables62); // #5666 - p=&str[0]
|
||
TEST_CASE(simplifyKnownVariablesBailOutAssign1);
|
||
TEST_CASE(simplifyKnownVariablesBailOutAssign2);
|
||
TEST_CASE(simplifyKnownVariablesBailOutAssign3); // #4395 - nested assignments
|
||
TEST_CASE(simplifyKnownVariablesBailOutFor1);
|
||
TEST_CASE(simplifyKnownVariablesBailOutFor2);
|
||
TEST_CASE(simplifyKnownVariablesBailOutFor3);
|
||
TEST_CASE(simplifyKnownVariablesBailOutMemberFunction);
|
||
TEST_CASE(simplifyKnownVariablesBailOutConditionalIncrement);
|
||
TEST_CASE(simplifyKnownVariablesBailOutSwitchBreak); // ticket #2324
|
||
TEST_CASE(simplifyKnownVariablesFloat); // #2454 - float variable
|
||
TEST_CASE(simplifyKnownVariablesClassMember); // #2815 - value of class member may be changed by function call
|
||
TEST_CASE(simplifyKnownVariablesFunctionCalls); // Function calls (don't assume pass by reference)
|
||
TEST_CASE(simplifyKnownVariablesGlobalVars);
|
||
TEST_CASE(simplifyKnownVariablesReturn); // 3500 - return
|
||
TEST_CASE(simplifyKnownVariablesPointerAliasFunctionCall); // #7440
|
||
TEST_CASE(simplifyExternC);
|
||
TEST_CASE(simplifyKeyword); // #5842 - remove C99 static keyword between []
|
||
|
||
TEST_CASE(isZeroNumber);
|
||
TEST_CASE(isOneNumber);
|
||
TEST_CASE(isTwoNumber);
|
||
|
||
TEST_CASE(simplifyFunctionParameters);
|
||
TEST_CASE(simplifyFunctionParameters1); // #3721
|
||
TEST_CASE(simplifyFunctionParameters2); // #4430
|
||
TEST_CASE(simplifyFunctionParameters3); // #4436
|
||
TEST_CASE(simplifyFunctionParameters4); // #9421
|
||
TEST_CASE(simplifyFunctionParametersMultiTemplate);
|
||
TEST_CASE(simplifyFunctionParametersErrors);
|
||
|
||
TEST_CASE(removeParentheses1); // Ticket #61
|
||
TEST_CASE(removeParentheses3);
|
||
TEST_CASE(removeParentheses4); // Ticket #390
|
||
TEST_CASE(removeParentheses5); // Ticket #392
|
||
TEST_CASE(removeParentheses6);
|
||
TEST_CASE(removeParentheses7);
|
||
TEST_CASE(removeParentheses8); // Ticket #1865
|
||
TEST_CASE(removeParentheses9); // Ticket #1962
|
||
TEST_CASE(removeParentheses10); // Ticket #2320
|
||
TEST_CASE(removeParentheses11); // Ticket #2505
|
||
TEST_CASE(removeParentheses12); // Ticket #2760 ',(b)='
|
||
TEST_CASE(removeParentheses13);
|
||
TEST_CASE(removeParentheses14); // Ticket #3309
|
||
TEST_CASE(removeParentheses15); // Ticket #4142
|
||
TEST_CASE(removeParentheses16); // Ticket #4423 '*(x.y)='
|
||
TEST_CASE(removeParentheses17); // Don't remove parentheses in 'a ? b : (c>0 ? d : e);'
|
||
TEST_CASE(removeParentheses18); // 'float(*a)[2]' => 'float *a[2]'
|
||
TEST_CASE(removeParentheses19); // ((typeof(x) *)0)
|
||
TEST_CASE(removeParentheses20); // Ticket #5479: a<b<int>>(2);
|
||
TEST_CASE(removeParentheses21); // Don't "simplify" casts
|
||
TEST_CASE(removeParentheses22);
|
||
TEST_CASE(removeParentheses23); // Ticket #6103 - Infinite loop upon valid input
|
||
TEST_CASE(removeParentheses24); // Ticket #7040
|
||
TEST_CASE(removeParentheses25); // daca@home - a=(b,c)
|
||
|
||
TEST_CASE(tokenize_double);
|
||
TEST_CASE(tokenize_strings);
|
||
TEST_CASE(simplify_constants);
|
||
TEST_CASE(simplify_constants2);
|
||
TEST_CASE(simplify_constants3);
|
||
TEST_CASE(simplify_constants4);
|
||
TEST_CASE(simplify_constants5);
|
||
TEST_CASE(simplify_constants6); // Ticket #5625: Ternary operator as template parameter
|
||
TEST_CASE(simplifyMulAndParens); // Ticket #2784 + #3184
|
||
|
||
TEST_CASE(simplifyStructDecl);
|
||
|
||
TEST_CASE(vardecl1);
|
||
TEST_CASE(vardecl2);
|
||
TEST_CASE(vardecl3);
|
||
TEST_CASE(vardecl4);
|
||
TEST_CASE(vardecl5); // #7048
|
||
TEST_CASE(vardec_static);
|
||
TEST_CASE(vardecl6);
|
||
TEST_CASE(vardecl7);
|
||
TEST_CASE(vardecl8);
|
||
TEST_CASE(vardecl9);
|
||
TEST_CASE(vardecl10);
|
||
TEST_CASE(vardecl11);
|
||
TEST_CASE(vardecl12);
|
||
TEST_CASE(vardecl13);
|
||
TEST_CASE(vardecl14);
|
||
TEST_CASE(vardecl15);
|
||
TEST_CASE(vardecl16);
|
||
TEST_CASE(vardecl17);
|
||
TEST_CASE(vardecl18);
|
||
TEST_CASE(vardecl19);
|
||
TEST_CASE(vardecl20); // #3700 - register const int H = 0;
|
||
TEST_CASE(vardecl21); // #4042 - a::b const *p = 0;
|
||
TEST_CASE(vardecl22); // #4211 - segmentation fault
|
||
TEST_CASE(vardecl23); // #4276 - segmentation fault
|
||
TEST_CASE(vardecl24); // #4187 - variable declaration within lambda function
|
||
TEST_CASE(vardecl25); // #4799 - segmentation fault
|
||
TEST_CASE(vardecl26); // #5907 - incorrect handling of extern declarations
|
||
TEST_CASE(vardecl27); // #7850 - crash on valid C code
|
||
TEST_CASE(vardecl_stl_1);
|
||
TEST_CASE(vardecl_stl_2);
|
||
TEST_CASE(vardecl_template_1);
|
||
TEST_CASE(vardecl_template_2);
|
||
TEST_CASE(vardecl_union);
|
||
TEST_CASE(vardecl_par); // #2743 - set links if variable type contains parentheses
|
||
TEST_CASE(vardecl_par2); // #3912 - set correct links
|
||
TEST_CASE(vardecl_par3); // #6556 - Fred x1(a), x2(b);
|
||
TEST_CASE(vardecl_class_ref);
|
||
TEST_CASE(volatile_variables);
|
||
|
||
// unsigned i; => unsigned int i;
|
||
TEST_CASE(unsigned1);
|
||
TEST_CASE(unsigned2);
|
||
TEST_CASE(unsigned3); // template arguments
|
||
|
||
TEST_CASE(simplifyStdType); // #4947, #4950, #4951
|
||
|
||
TEST_CASE(createLinks);
|
||
TEST_CASE(createLinks2);
|
||
TEST_CASE(signed1);
|
||
|
||
TEST_CASE(simplifyString);
|
||
TEST_CASE(simplifyConst);
|
||
TEST_CASE(switchCase);
|
||
|
||
TEST_CASE(simplifyPointerToStandardType);
|
||
TEST_CASE(functionpointer1);
|
||
TEST_CASE(functionpointer2);
|
||
TEST_CASE(functionpointer3);
|
||
TEST_CASE(functionpointer4);
|
||
TEST_CASE(functionpointer5);
|
||
TEST_CASE(functionpointer6);
|
||
TEST_CASE(functionpointer7);
|
||
TEST_CASE(functionpointer8); // #7410 - throw
|
||
TEST_CASE(functionpointer9); // #6113 - function call with function pointer
|
||
|
||
TEST_CASE(removeRedundantAssignment);
|
||
|
||
TEST_CASE(removedeclspec);
|
||
TEST_CASE(removeattribute);
|
||
TEST_CASE(functionAttributeBefore);
|
||
TEST_CASE(functionAttributeAfter);
|
||
|
||
TEST_CASE(cpp03template1);
|
||
TEST_CASE(cpp0xtemplate1);
|
||
TEST_CASE(cpp0xtemplate2);
|
||
TEST_CASE(cpp0xtemplate3);
|
||
TEST_CASE(cpp0xtemplate4); // Ticket #6181: Mishandled C++11 syntax
|
||
TEST_CASE(cpp0xtemplate5); // Ticket #9154 change >> to > >
|
||
TEST_CASE(cpp14template); // Ticket #6708
|
||
|
||
TEST_CASE(arraySize);
|
||
|
||
TEST_CASE(labels);
|
||
TEST_CASE(simplifyInitVar);
|
||
TEST_CASE(simplifyInitVar2);
|
||
TEST_CASE(simplifyInitVar3);
|
||
|
||
TEST_CASE(bitfields1);
|
||
TEST_CASE(bitfields2);
|
||
TEST_CASE(bitfields3);
|
||
TEST_CASE(bitfields4); // ticket #1956
|
||
TEST_CASE(bitfields5); // ticket #1956
|
||
TEST_CASE(bitfields6); // ticket #2595
|
||
TEST_CASE(bitfields7); // ticket #1987
|
||
TEST_CASE(bitfields8);
|
||
TEST_CASE(bitfields9); // ticket #2706
|
||
TEST_CASE(bitfields10);
|
||
TEST_CASE(bitfields12); // ticket #3485 (segmentation fault)
|
||
TEST_CASE(bitfields13); // ticket #3502 (segmentation fault)
|
||
TEST_CASE(bitfields14); // ticket #4561 (segfault for 'class a { signals: };')
|
||
TEST_CASE(bitfields15); // ticket #7747 (enum Foo {A,B}:4;)
|
||
TEST_CASE(bitfields16); // Save bitfield bit count
|
||
|
||
TEST_CASE(simplifyNamespaceStd);
|
||
|
||
TEST_CASE(microsoftMemory);
|
||
TEST_CASE(microsoftString);
|
||
|
||
TEST_CASE(borland);
|
||
|
||
TEST_CASE(simplifyQtSignalsSlots1);
|
||
TEST_CASE(simplifyQtSignalsSlots2);
|
||
|
||
TEST_CASE(simplifySQL);
|
||
|
||
TEST_CASE(simplifyCAlternativeTokens);
|
||
|
||
TEST_CASE(simplifyCalculations);
|
||
|
||
// x = ({ 123; }); => { x = 123; }
|
||
TEST_CASE(simplifyRoundCurlyParentheses);
|
||
|
||
TEST_CASE(simplifyOperatorName1);
|
||
TEST_CASE(simplifyOperatorName2);
|
||
TEST_CASE(simplifyOperatorName3);
|
||
TEST_CASE(simplifyOperatorName4);
|
||
TEST_CASE(simplifyOperatorName5);
|
||
TEST_CASE(simplifyOperatorName6); // ticket #3194
|
||
TEST_CASE(simplifyOperatorName7); // ticket #4619
|
||
TEST_CASE(simplifyOperatorName8); // ticket #5706
|
||
TEST_CASE(simplifyOperatorName9); // ticket #5709 - comma operator not properly tokenized
|
||
TEST_CASE(simplifyOperatorName10); // #8746 - using a::operator=
|
||
TEST_CASE(simplifyOperatorName11); // #8889
|
||
TEST_CASE(simplifyOperatorName12); // #9110
|
||
TEST_CASE(simplifyOperatorName13); // user defined literal
|
||
TEST_CASE(simplifyOperatorName14); // std::complex operator "" if
|
||
TEST_CASE(simplifyOperatorName15); // ticket #9468 syntaxError
|
||
TEST_CASE(simplifyOperatorName16); // ticket #9472
|
||
TEST_CASE(simplifyOperatorName17);
|
||
TEST_CASE(simplifyOperatorName18); // global namespace
|
||
TEST_CASE(simplifyOperatorName19);
|
||
TEST_CASE(simplifyOperatorName20);
|
||
TEST_CASE(simplifyOperatorName21);
|
||
TEST_CASE(simplifyOperatorName22);
|
||
TEST_CASE(simplifyOperatorName23);
|
||
TEST_CASE(simplifyOperatorName24);
|
||
TEST_CASE(simplifyOperatorName25);
|
||
TEST_CASE(simplifyOperatorName26);
|
||
TEST_CASE(simplifyOperatorName27);
|
||
|
||
TEST_CASE(simplifyOverloadedOperators1);
|
||
TEST_CASE(simplifyOverloadedOperators2); // (*this)(123)
|
||
TEST_CASE(simplifyOverloadedOperators3); // #9881 - hang
|
||
|
||
TEST_CASE(simplifyNullArray);
|
||
|
||
// Some simple cleanups of unhandled macros in the global scope
|
||
TEST_CASE(removeMacrosInGlobalScope);
|
||
TEST_CASE(removeMacroInVarDecl);
|
||
|
||
TEST_CASE(addSemicolonAfterUnknownMacro);
|
||
|
||
// a = b = 0;
|
||
TEST_CASE(multipleAssignment);
|
||
|
||
TEST_CASE(sizeOfCharLiteral);
|
||
TEST_CASE(platformWin);
|
||
TEST_CASE(platformWin32);
|
||
TEST_CASE(platformWin32A);
|
||
TEST_CASE(platformWin32W);
|
||
TEST_CASE(platformWin64);
|
||
TEST_CASE(platformUnix32);
|
||
TEST_CASE(platformUnix64);
|
||
TEST_CASE(platformWin32AStringCat); // ticket #5015
|
||
TEST_CASE(platformWin32WStringCat); // ticket #5015
|
||
TEST_CASE(platformWinWithNamespace);
|
||
|
||
TEST_CASE(simplifyStaticConst);
|
||
|
||
TEST_CASE(simplifyCPPAttribute);
|
||
|
||
TEST_CASE(simplifyCaseRange);
|
||
|
||
TEST_CASE(simplifyEmptyNamespaces);
|
||
|
||
TEST_CASE(compileLimits); // #5592 crash: gcc: testsuit: gcc.c-torture/compile/limits-declparen.c
|
||
|
||
TEST_CASE(prepareTernaryOpForAST);
|
||
|
||
// AST data
|
||
TEST_CASE(astexpr);
|
||
TEST_CASE(astexpr2); // limit large expressions
|
||
TEST_CASE(astpar);
|
||
TEST_CASE(astnewdelete);
|
||
TEST_CASE(astbrackets);
|
||
TEST_CASE(astunaryop);
|
||
TEST_CASE(astfunction);
|
||
TEST_CASE(asttemplate);
|
||
TEST_CASE(astcast);
|
||
TEST_CASE(astlambda);
|
||
TEST_CASE(astcase);
|
||
TEST_CASE(astrefqualifier);
|
||
TEST_CASE(astvardecl);
|
||
TEST_CASE(astnewscoped);
|
||
|
||
TEST_CASE(startOfExecutableScope);
|
||
|
||
TEST_CASE(removeMacroInClassDef); // #6058
|
||
|
||
TEST_CASE(sizeofAddParentheses);
|
||
|
||
TEST_CASE(reportUnknownMacros);
|
||
|
||
// Make sure the Tokenizer::findGarbageCode() does not have false positives
|
||
// The TestGarbage ensures that there are true positives
|
||
TEST_CASE(findGarbageCode);
|
||
TEST_CASE(checkEnableIf);
|
||
TEST_CASE(checkTemplates);
|
||
TEST_CASE(checkNamespaces);
|
||
TEST_CASE(checkLambdas);
|
||
TEST_CASE(checkIfCppCast);
|
||
TEST_CASE(checkRefQualifiers);
|
||
TEST_CASE(checkConditionBlock);
|
||
|
||
// #9052
|
||
TEST_CASE(noCrash1);
|
||
TEST_CASE(noCrash2);
|
||
|
||
TEST_CASE(noCrash3);
|
||
|
||
// --check-config
|
||
TEST_CASE(checkConfiguration);
|
||
|
||
TEST_CASE(unknownType); // #8952
|
||
|
||
TEST_CASE(unknownMacroBeforeReturn);
|
||
|
||
TEST_CASE(cppcast);
|
||
|
||
TEST_CASE(checkHeader1);
|
||
}
|
||
|
||
std::string tokenizeAndStringify(const char code[], bool simplify = false, bool expand = true, Settings::PlatformType platform = Settings::Native, const char* filename = "test.cpp", bool cpp11 = true) {
|
||
errout.str("");
|
||
|
||
settings1.debugwarnings = true;
|
||
settings1.platform(platform);
|
||
settings1.standards.cpp = cpp11 ? Standards::CPP11 : Standards::CPP03;
|
||
|
||
// tokenize..
|
||
Tokenizer tokenizer(&settings1, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, filename);
|
||
if (simplify)
|
||
tokenizer.simplifyTokenList2();
|
||
|
||
// filter out ValueFlow messages..
|
||
const std::string debugwarnings = errout.str();
|
||
errout.str("");
|
||
std::istringstream istr2(debugwarnings);
|
||
std::string line;
|
||
while (std::getline(istr2,line)) {
|
||
if (line.find("valueflow.cpp") == std::string::npos)
|
||
errout << line << "\n";
|
||
}
|
||
|
||
if (tokenizer.tokens())
|
||
return tokenizer.tokens()->stringifyList(false, expand, false, true, false, nullptr, nullptr);
|
||
else
|
||
return "";
|
||
}
|
||
|
||
std::string tokenizeAndStringifyWindows(const char code[], bool simplify = false, bool expand = true, Settings::PlatformType platform = Settings::Native, const char* filename = "test.cpp", bool cpp11 = true) {
|
||
errout.str("");
|
||
|
||
settings_windows.debugwarnings = true;
|
||
settings_windows.platform(platform);
|
||
settings_windows.standards.cpp = cpp11 ? Standards::CPP11 : Standards::CPP03;
|
||
|
||
// tokenize..
|
||
Tokenizer tokenizer(&settings_windows, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, filename);
|
||
if (simplify)
|
||
tokenizer.simplifyTokenList2();
|
||
|
||
// filter out ValueFlow messages..
|
||
const std::string debugwarnings = errout.str();
|
||
errout.str("");
|
||
std::istringstream istr2(debugwarnings);
|
||
std::string line;
|
||
while (std::getline(istr2,line)) {
|
||
if (line.find("valueflow.cpp") == std::string::npos)
|
||
errout << line << "\n";
|
||
}
|
||
|
||
if (tokenizer.tokens())
|
||
return tokenizer.tokens()->stringifyList(false, expand, false, true, false, nullptr, nullptr);
|
||
else
|
||
return "";
|
||
}
|
||
|
||
std::string tokenizeAndStringify(const char code[], const Settings &settings, const char filename[] = "test.cpp") {
|
||
errout.str("");
|
||
|
||
// tokenize..
|
||
Tokenizer tokenizer(&settings, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, filename);
|
||
if (!tokenizer.tokens())
|
||
return "";
|
||
return tokenizer.tokens()->stringifyList(false, true, false, true, false, nullptr, nullptr);
|
||
}
|
||
|
||
std::string tokenizeDebugListing(const char code[], bool simplify = false, const char filename[] = "test.cpp") {
|
||
errout.str("");
|
||
|
||
settings2.standards.c = Standards::C89;
|
||
settings2.standards.cpp = Standards::CPP03;
|
||
|
||
Tokenizer tokenizer(&settings2, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, filename);
|
||
|
||
if (simplify)
|
||
tokenizer.simplifyTokenList2();
|
||
|
||
// result..
|
||
return tokenizer.tokens()->stringifyList(true,true,true,true,false);
|
||
}
|
||
|
||
void tokenize1() {
|
||
const char code[] = "void f ( )\n"
|
||
"{ if ( p . y ( ) > yof ) { } }";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void tokenize2() {
|
||
const char code[] = "{ sizeof a, sizeof b }";
|
||
ASSERT_EQUALS("{ sizeof ( a ) , sizeof ( b ) }", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void tokenize4() {
|
||
const char code[] = "class foo\n"
|
||
"{\n"
|
||
"public:\n"
|
||
" const int i;\n"
|
||
"}";
|
||
ASSERT_EQUALS("class foo\n"
|
||
"{\n"
|
||
"public:\n"
|
||
"const int i ;\n"
|
||
"}", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
void tokenize5() {
|
||
// Tokenize values
|
||
ASSERT_EQUALS("; + 1E3 ;", tokenizeAndStringify("; +1E3 ;"));
|
||
ASSERT_EQUALS("; 1E-2 ;", tokenizeAndStringify("; 1E-2 ;"));
|
||
}
|
||
|
||
void tokenize6() {
|
||
// "&p[1]" => "p+1"
|
||
/*
|
||
ASSERT_EQUALS("; x = p + n ;", tokenizeAndStringify("; x = & p [ n ] ;", true));
|
||
ASSERT_EQUALS("; x = ( p + n ) [ m ] ;", tokenizeAndStringify("; x = & p [ n ] [ m ] ;", true));
|
||
ASSERT_EQUALS("; x = y & p [ n ] ;", tokenizeAndStringify("; x = y & p [ n ] ;", true));
|
||
ASSERT_EQUALS("; x = 10 & p [ n ] ;", tokenizeAndStringify("; x = 10 & p [ n ] ;", true));
|
||
ASSERT_EQUALS("; x = y [ 10 ] & p [ n ] ;", tokenizeAndStringify("; x = y [ 10 ] & p [ n ] ;", true));
|
||
ASSERT_EQUALS("; x = ( a + m ) & p [ n ] ;", tokenizeAndStringify("; x = ( a + m ) & p [ n ] ;", true));*/
|
||
// "*(p+1)" => "p[1]"
|
||
ASSERT_EQUALS("; x = p [ 1 ] ;", tokenizeAndStringify("; x = * ( p + 1 ) ;", true));
|
||
ASSERT_EQUALS("; x = p [ 0xA ] ;", tokenizeAndStringify("; x = * ( p + 0xA ) ;", true));
|
||
ASSERT_EQUALS("; x = p [ n ] ;", tokenizeAndStringify("; x = * ( p + n ) ;", true));
|
||
ASSERT_EQUALS("; x = y * ( p + n ) ;", tokenizeAndStringify("; x = y * ( p + n ) ;", true));
|
||
ASSERT_EQUALS("; x = 10 * ( p + n ) ;", tokenizeAndStringify("; x = 10 * ( p + n ) ;", true));
|
||
ASSERT_EQUALS("; x = y [ 10 ] * ( p + n ) ;", tokenizeAndStringify("; x = y [ 10 ] * ( p + n ) ;", true));
|
||
ASSERT_EQUALS("; x = ( a + m ) * ( p + n ) ;", tokenizeAndStringify("; x = ( a + m ) * ( p + n ) ;", true));
|
||
|
||
// "*(p-1)" => "p[-1]" and "*(p-n)" => "p[-n]"
|
||
ASSERT_EQUALS("; x = p [ -1 ] ;", tokenizeAndStringify("; x = *(p - 1);", true));
|
||
ASSERT_EQUALS("; x = p [ -0xA ] ;", tokenizeAndStringify("; x = *(p - 0xA);", true));
|
||
ASSERT_EQUALS("; x = p [ - n ] ;", tokenizeAndStringify("; x = *(p - n);", true));
|
||
ASSERT_EQUALS("; x = y * ( p - 1 ) ;", tokenizeAndStringify("; x = y * (p - 1);", true));
|
||
ASSERT_EQUALS("; x = 10 * ( p - 1 ) ;", tokenizeAndStringify("; x = 10 * (p - 1);", true));
|
||
ASSERT_EQUALS("; x = y [ 10 ] * ( p - 1 ) ;", tokenizeAndStringify("; x = y[10] * (p - 1);", true));
|
||
ASSERT_EQUALS("; x = ( a - m ) * ( p - n ) ;", tokenizeAndStringify("; x = (a - m) * (p - n);", true));
|
||
|
||
// Test that the array-index simplification is not applied when there's no dereference:
|
||
// "(x-y)" => "(x-y)" and "(x+y)" => "(x+y)"
|
||
ASSERT_EQUALS("; a = b * ( x - y ) ;", tokenizeAndStringify("; a = b * (x - y);", true));
|
||
ASSERT_EQUALS("; a = b * x [ - y ] ;", tokenizeAndStringify("; a = b * *(x - y);", true));
|
||
ASSERT_EQUALS("; a = a * ( x - y ) ;", tokenizeAndStringify("; a *= (x - y);", true));
|
||
ASSERT_EQUALS("; z = a ++ * ( x - y ) ;", tokenizeAndStringify("; z = a++ * (x - y);", true));
|
||
ASSERT_EQUALS("; z = a ++ * ( x + y ) ;", tokenizeAndStringify("; z = a++ * (x + y);", true));
|
||
ASSERT_EQUALS("; z = a -- * ( x - y ) ;", tokenizeAndStringify("; z = a-- * (x - y);", true));
|
||
ASSERT_EQUALS("; z = a -- * ( x + y ) ;", tokenizeAndStringify("; z = a-- * (x + y);", true));
|
||
ASSERT_EQUALS("; z = 'a' * ( x - y ) ;", tokenizeAndStringify("; z = 'a' * (x - y);", true));
|
||
ASSERT_EQUALS("; z = \"a\" * ( x - y ) ;", tokenizeAndStringify("; z = \"a\" * (x - y);", true));
|
||
ASSERT_EQUALS("; z = 'a' * ( x + y ) ;", tokenizeAndStringify("; z = 'a' * (x + y);", true));
|
||
ASSERT_EQUALS("; z = \"a\" * ( x + y ) ;", tokenizeAndStringify("; z = \"a\" * (x + y);", true));
|
||
ASSERT_EQUALS("; z = foo ( ) * ( x + y ) ;", tokenizeAndStringify("; z = foo() * (x + y);", true));
|
||
}
|
||
|
||
void tokenize7() {
|
||
const char code[] = "void f() {\n"
|
||
" int x1 = 1;\n"
|
||
" int x2(x1);\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void f ( ) {\nint x1 ; x1 = 1 ;\nint x2 ; x2 = x1 ;\n}",
|
||
tokenizeAndStringify(code, false));
|
||
}
|
||
|
||
void tokenize8() {
|
||
const char code[] = "void f() {\n"
|
||
" int x1(g());\n"
|
||
" int x2(x1);\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("1: void f ( ) {\n"
|
||
"2: int x1@1 ; x1@1 = g ( ) ;\n"
|
||
"3: int x2@2 ; x2@2 = x1@1 ;\n"
|
||
"4: }\n",
|
||
tokenizeDebugListing(code, false));
|
||
}
|
||
|
||
void tokenize9() {
|
||
const char code[] = "typedef void (*fp)();\n"
|
||
"typedef fp (*fpp)();\n"
|
||
"void f() {\n"
|
||
" fpp x = (fpp)f();\n"
|
||
"}";
|
||
tokenizeAndStringify(code, false);
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
void tokenize11() {
|
||
ASSERT_EQUALS("X * sizeof ( Y ( ) ) ;", tokenizeAndStringify("X * sizeof(Y());", false));
|
||
}
|
||
|
||
// bailout if there is "@" - it is not handled well
|
||
void tokenize13() {
|
||
const char code[] = "@implementation\n"
|
||
"-(Foo *)foo: (Bar *)bar\n"
|
||
"{ }\n"
|
||
"@end\n";
|
||
ASSERT_THROW(tokenizeAndStringify(code), InternalError);
|
||
}
|
||
|
||
// Ticket #2361: 0X10 => 16
|
||
void tokenize14() {
|
||
ASSERT_EQUALS("; 0x10 ;", tokenizeAndStringify(";0x10;"));
|
||
ASSERT_EQUALS("; 0X10 ;", tokenizeAndStringify(";0X10;"));
|
||
ASSERT_EQUALS("; 0444 ;", tokenizeAndStringify(";0444;"));
|
||
}
|
||
|
||
// Ticket #8050
|
||
void tokenizeHexWithSuffix() {
|
||
ASSERT_EQUALS("; 0xFFFFFF ;", tokenizeAndStringify(";0xFFFFFF;"));
|
||
ASSERT_EQUALS("; 0xFFFFFFu ;", tokenizeAndStringify(";0xFFFFFFu;"));
|
||
ASSERT_EQUALS("; 0xFFFFFFul ;", tokenizeAndStringify(";0xFFFFFFul;"));
|
||
|
||
// Number of digits decides about internal representation...
|
||
ASSERT_EQUALS("; 0xFFFFFFFF ;", tokenizeAndStringify(";0xFFFFFFFF;"));
|
||
ASSERT_EQUALS("; 0xFFFFFFFFu ;", tokenizeAndStringify(";0xFFFFFFFFu;"));
|
||
ASSERT_EQUALS("; 0xFFFFFFFFul ;", tokenizeAndStringify(";0xFFFFFFFFul;"));
|
||
}
|
||
|
||
// Ticket #2429: 0.125
|
||
void tokenize15() {
|
||
ASSERT_EQUALS("0.125 ;", tokenizeAndStringify(".125;"));
|
||
ASSERT_EQUALS("005.125 ;", tokenizeAndStringify("005.125;")); // Don't confuse with octal values
|
||
}
|
||
|
||
void tokenize17() { // #2759
|
||
ASSERT_EQUALS("class B : private :: A { } ;", tokenizeAndStringify("class B : private ::A { };"));
|
||
}
|
||
|
||
void tokenize18() { // tokenize "(X&&Y)" into "( X && Y )" instead of "( X & & Y )"
|
||
ASSERT_EQUALS("( X && Y ) ;", tokenizeAndStringify("(X&&Y);"));
|
||
}
|
||
|
||
void tokenize19() {
|
||
// #3006 - added hasComplicatedSyntaxErrorsInTemplates to avoid segmentation fault
|
||
ASSERT_THROW(tokenizeAndStringify("x < () <"), InternalError);
|
||
|
||
// #3496 - make sure hasComplicatedSyntaxErrorsInTemplates works
|
||
ASSERT_EQUALS("void a ( Fred * f ) { for ( ; n < f . x ( ) ; ) { } }",
|
||
tokenizeAndStringify("void a(Fred* f) MACRO { for (;n < f->x();) {} }"));
|
||
|
||
// #6216 - make sure hasComplicatedSyntaxErrorsInTemplates works
|
||
ASSERT_EQUALS("C :: C ( )\n"
|
||
": v { }\n"
|
||
"{\n"
|
||
"for ( int dim = 0 ; dim < v . size ( ) ; ++ dim ) {\n"
|
||
"v [ dim ] . f ( ) ;\n"
|
||
"}\n"
|
||
"} ;",
|
||
tokenizeAndStringify("C::C()\n"
|
||
":v{}\n"
|
||
"{\n"
|
||
" for (int dim = 0; dim < v.size(); ++dim) {\n"
|
||
" v[dim]->f();\n"
|
||
" }\n"
|
||
"};"));
|
||
}
|
||
|
||
void tokenize21() { // tokenize 0x0E-7
|
||
ASSERT_EQUALS("0x0E - 7 ;", tokenizeAndStringify("0x0E-7;"));
|
||
}
|
||
|
||
void tokenize22() { // tokenize special marker $ from preprocessor
|
||
ASSERT_EQUALS("a$b", tokenizeAndStringify("a$b"));
|
||
ASSERT_EQUALS("a $b\nc", tokenizeAndStringify("a $b\nc"));
|
||
ASSERT_EQUALS("a = $0 ;", tokenizeAndStringify("a = $0;"));
|
||
ASSERT_EQUALS("a$ ++ ;", tokenizeAndStringify("a$++;"));
|
||
ASSERT_EQUALS("$if ( ! p )", tokenizeAndStringify("$if(!p)"));
|
||
}
|
||
|
||
// #4239 - segfault for "f ( struct { int typedef T x ; } ) { }"
|
||
void tokenize25() {
|
||
ASSERT_THROW(tokenizeAndStringify("f ( struct { int typedef T x ; } ) { }"), InternalError);
|
||
}
|
||
|
||
// #4245 - segfault
|
||
void tokenize26() {
|
||
ASSERT_THROW(tokenizeAndStringify("class x { protected : template < int y = } ;"), InternalError); // Garbage code
|
||
}
|
||
|
||
void tokenize27() {
|
||
// #4525 - segfault
|
||
tokenizeAndStringify("struct except_spec_d_good : except_spec_a, except_spec_b {\n"
|
||
"~except_spec_d_good();\n"
|
||
"};\n"
|
||
"struct S { S(); };\n"
|
||
"S::S() __attribute((pure)) = default;"
|
||
);
|
||
|
||
// original code: glibc-2.18/posix/bug-regex20.c
|
||
tokenizeAndStringify("static unsigned int re_string_context_at (const re_string_t *input, int idx, int eflags) internal_function __attribute__ ((pure));");
|
||
}
|
||
|
||
// #3503 - don't "simplify" SetFunction member function to a variable
|
||
void tokenize31() {
|
||
ASSERT_EQUALS("struct TTestClass { TTestClass ( ) { }\n"
|
||
"void SetFunction ( Other ( * m_f ) ( ) ) { }\n"
|
||
"} ;",
|
||
tokenizeAndStringify("struct TTestClass { TTestClass() { }\n"
|
||
" void SetFunction(Other(*m_f)()) { }\n"
|
||
"};"));
|
||
|
||
ASSERT_EQUALS("struct TTestClass { TTestClass ( ) { }\n"
|
||
"void SetFunction ( Other ( * m_f ) ( ) ) ;\n"
|
||
"} ;",
|
||
tokenizeAndStringify("struct TTestClass { TTestClass() { }\n"
|
||
" void SetFunction(Other(*m_f)());\n"
|
||
"};"));
|
||
}
|
||
|
||
// #5884 - Avoid left shift of negative integer value.
|
||
void tokenize32() {
|
||
// Do not simplify negative integer left shifts.
|
||
const char * code = "void f ( ) { int max_x ; max_x = -10000 << 16 ; }";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
// #5780 Various crashes on valid template code in Tokenizer::setVarId()
|
||
void tokenize33() {
|
||
const char * code = "template<typename T, typename A = Alloc<T>> struct vector {};\n"
|
||
"void z() {\n"
|
||
" vector<int> VI;\n"
|
||
"}\n";
|
||
tokenizeAndStringify(code, true);
|
||
}
|
||
|
||
void tokenize34() { // #8031
|
||
{
|
||
const char code[] = "struct Container {\n"
|
||
" Container();\n"
|
||
" int* mElements;\n"
|
||
"};\n"
|
||
"Container::Container() : mElements(nullptr) {}\n"
|
||
"Container intContainer;";
|
||
const char exp [] = "1: struct Container {\n"
|
||
"2: Container ( ) ;\n"
|
||
"3: int * mElements@1 ;\n"
|
||
"4: } ;\n"
|
||
"5: Container :: Container ( ) : mElements@1 ( nullptr ) { }\n"
|
||
"6: Container intContainer@2 ;\n";
|
||
ASSERT_EQUALS(exp, tokenizeDebugListing(code));
|
||
}
|
||
{
|
||
const char code[] = "template<class T> struct Container {\n"
|
||
" Container();\n"
|
||
" int* mElements;\n"
|
||
"};\n"
|
||
"template <class T> Container<T>::Container() : mElements(nullptr) {}\n"
|
||
"Container<int> intContainer;";
|
||
const char exp [] = "1: struct Container<int> ;\n"
|
||
"2:\n"
|
||
"|\n"
|
||
"5:\n"
|
||
"6: Container<int> intContainer@1 ; struct Container<int> {\n"
|
||
"2: Container<int> ( ) ;\n"
|
||
"3: int * mElements@2 ;\n"
|
||
"4: } ;\n"
|
||
"5: Container<int> :: Container<int> ( ) : mElements@2 ( nullptr ) { }\n";
|
||
ASSERT_EQUALS(exp, tokenizeDebugListing(code));
|
||
}
|
||
}
|
||
|
||
void tokenize35() { // #8361
|
||
tokenizeAndStringify("typedef int CRCWord; "
|
||
"template<typename T> ::CRCWord const Compute(T const t) { return 0; }");
|
||
}
|
||
|
||
void tokenize36() { // #8436
|
||
const char code[] = "int foo ( int i ) { return i ? * new int { 5 } : int { i ? 0 : 1 } ; }";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void tokenize37() { // #8550
|
||
const char codeC[] = "class name { public: static void init ( ) {} } ; "
|
||
"typedef class name N; "
|
||
"void foo ( ) { return N :: init ( ) ; }";
|
||
const char expC [] = "class name { public: static void init ( ) { } } ; "
|
||
"void foo ( ) { return name :: init ( ) ; }";
|
||
ASSERT_EQUALS(expC, tokenizeAndStringify(codeC));
|
||
const char codeS[] = "class name { public: static void init ( ) {} } ; "
|
||
"typedef struct name N; "
|
||
"void foo ( ) { return N :: init ( ) ; }";
|
||
const char expS [] = "class name { public: static void init ( ) { } } ; "
|
||
"void foo ( ) { return name :: init ( ) ; }";
|
||
ASSERT_EQUALS(expS, tokenizeAndStringify(codeS));
|
||
}
|
||
|
||
void tokenize38() { // #9569
|
||
const char code[] = "using Binary = std::vector<char>; enum Type { Binary };";
|
||
const char exp[] = "enum Type { Binary } ;";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void tokenize39() { // #9771
|
||
const char code[] = "template <typename T> class Foo;"
|
||
"template <typename T> bool operator!=(const Foo<T> &, const Foo<T> &);"
|
||
"template <typename T> class Foo { friend bool operator!= <> (const Foo<T> &, const Foo<T> &); };";
|
||
const char exp[] = "template < typename T > class Foo ; "
|
||
"template < typename T > bool operator!= ( const Foo < T > & , const Foo < T > & ) ; "
|
||
"template < typename T > class Foo { friend bool operator!= < > ( const Foo < T > & , const Foo < T > & ) ; } ;";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void validate() {
|
||
// C++ code in C file
|
||
ASSERT_THROW(tokenizeAndStringify(";using namespace std;",false,false,Settings::Native,"test.c"), InternalError);
|
||
ASSERT_THROW(tokenizeAndStringify(";std::map<int,int> m;",false,false,Settings::Native,"test.c"), InternalError);
|
||
ASSERT_THROW(tokenizeAndStringify(";template<class T> class X { };",false,false,Settings::Native,"test.c"), InternalError);
|
||
ASSERT_THROW(tokenizeAndStringify("int X<Y>() {};",false,false,Settings::Native,"test.c"), InternalError);
|
||
ASSERT_THROW(tokenizeAndStringify("void foo(int i) { reinterpret_cast<char>(i) };",false,false,Settings::Native,"test.h"), InternalError);
|
||
}
|
||
|
||
void objectiveC() {
|
||
ASSERT_THROW(tokenizeAndStringify("void f() { [foo bar]; }"), InternalError);
|
||
}
|
||
|
||
void syntax_case_default() { // correct syntax
|
||
tokenizeAndStringify("void f() {switch (n) { case 0: z(); break;}}");
|
||
ASSERT_EQUALS("", errout.str());
|
||
|
||
tokenizeAndStringify("void f() {switch (n) { case 0:; break;}}");
|
||
ASSERT_EQUALS("", errout.str());
|
||
|
||
// TODO: Do not throw AST validation exception
|
||
TODO_ASSERT_THROW(tokenizeAndStringify("void f() {switch (n) { case 0?1:2 : z(); break;}}"), InternalError);
|
||
//ASSERT_EQUALS("", errout.str());
|
||
|
||
// TODO: Do not throw AST validation exception
|
||
TODO_ASSERT_THROW(tokenizeAndStringify("void f() {switch (n) { case 0?(1?3:4):2 : z(); break;}}"), InternalError);
|
||
ASSERT_EQUALS("", errout.str());
|
||
|
||
//allow GCC '({ %name%|%num%|%bool% ; })' statement expression extension
|
||
// TODO: Do not throw AST validation exception
|
||
TODO_ASSERT_THROW(tokenizeAndStringify("void f() {switch (n) { case 0?({0;}):1: z(); break;}}"), InternalError);
|
||
ASSERT_EQUALS("", errout.str());
|
||
|
||
//'b' can be or a macro or an undefined enum
|
||
tokenizeAndStringify("void f() {switch (n) { case b: z(); break;}}");
|
||
ASSERT_EQUALS("", errout.str());
|
||
|
||
//valid, when there's this declaration: 'constexpr int g() { return 2; }'
|
||
tokenizeAndStringify("void f() {switch (n) { case g(): z(); break;}}");
|
||
ASSERT_EQUALS("", errout.str());
|
||
|
||
//valid, when there's also this declaration: 'constexpr int g[1] = {0};'
|
||
tokenizeAndStringify("void f() {switch (n) { case g[0]: z(); break;}}");
|
||
ASSERT_EQUALS("", errout.str());
|
||
|
||
//valid, similar to above case
|
||
tokenizeAndStringify("void f() {switch (n) { case *g: z(); break;}}");
|
||
ASSERT_EQUALS("", errout.str());
|
||
|
||
//valid, when 'x' and 'y' are constexpr.
|
||
tokenizeAndStringify("void f() {switch (n) { case sqrt(x+y): z(); break;}}");
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
void removePragma() {
|
||
const char code[] = "_Pragma(\"abc\") int x;";
|
||
Settings s;
|
||
|
||
s.standards.c = Standards::C89;
|
||
ASSERT_EQUALS("_Pragma ( \"abc\" ) int x ;", tokenizeAndStringify(code, s, "test.c"));
|
||
s.standards.c = Standards::CLatest;
|
||
ASSERT_EQUALS("int x ;", tokenizeAndStringify(code, s, "test.c"));
|
||
|
||
s.standards.cpp = Standards::CPP03;
|
||
ASSERT_EQUALS("_Pragma ( \"abc\" ) int x ;", tokenizeAndStringify(code, s, "test.cpp"));
|
||
s.standards.cpp = Standards::CPPLatest;
|
||
ASSERT_EQUALS("int x ;", tokenizeAndStringify(code, s, "test.cpp"));
|
||
}
|
||
|
||
void foreach () {
|
||
// #3690,#5154
|
||
const char code[] ="void f() { for each ( char c in MyString ) { Console::Write(c); } }";
|
||
ASSERT_EQUALS("void f ( ) { asm ( \"char c in MyString\" ) { Console :: Write ( c ) ; } }", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void ifconstexpr() {
|
||
ASSERT_EQUALS("void f ( ) { if ( FOO ) { bar ( c ) ; } }", tokenizeAndStringify("void f() { if constexpr ( FOO ) { bar(c); } }"));
|
||
}
|
||
|
||
void combineOperators() {
|
||
ASSERT_EQUALS("; private: ;", tokenizeAndStringify(";private:;", false));
|
||
ASSERT_EQUALS("; protected: ;", tokenizeAndStringify(";protected:;", false));
|
||
ASSERT_EQUALS("; public: ;", tokenizeAndStringify(";public:;", false));
|
||
ASSERT_EQUALS("; __published: ;", tokenizeAndStringify(";__published:;", false));
|
||
ASSERT_EQUALS("a . public : ;", tokenizeAndStringify("a.public:;", false));
|
||
ASSERT_EQUALS("void f ( x & = 2 ) ;", tokenizeAndStringify("void f(x &= 2);", false));
|
||
ASSERT_EQUALS("const_cast < a * > ( & e )", tokenizeAndStringify("const_cast<a*>(&e)", false));
|
||
}
|
||
|
||
void concatenateNegativeNumber() {
|
||
ASSERT_EQUALS("i = -12 ;", tokenizeAndStringify("i = -12;"));
|
||
ASSERT_EQUALS("1 - 2 ;", tokenizeAndStringify("1-2;"));
|
||
ASSERT_EQUALS("foo ( -1 ) - 2 ;", tokenizeAndStringify("foo(-1)-2;"));
|
||
ASSERT_EQUALS("int f ( ) { return -2 ; }", tokenizeAndStringify("int f(){return -2;}"));
|
||
ASSERT_EQUALS("int x [ 2 ] = { -2 , 1 }", tokenizeAndStringify("int x[2] = {-2,1}"));
|
||
|
||
ASSERT_EQUALS("f ( 123 )", tokenizeAndStringify("f(+123)"));
|
||
}
|
||
|
||
|
||
|
||
void longtok() {
|
||
const std::string filedata(10000, 'a');
|
||
ASSERT_EQUALS(filedata, tokenizeAndStringify(filedata.c_str(), true));
|
||
}
|
||
|
||
|
||
void simplifyHeadersAndUnusedTemplates1() {
|
||
Settings s;
|
||
s.checkUnusedTemplates = false;
|
||
ASSERT_EQUALS(";",
|
||
tokenizeAndStringify("; template <typename... a> uint8_t b(std::tuple<uint8_t> d) {\n"
|
||
" std::tuple<a...> c{std::move(d)};\n"
|
||
" return std::get<0>(c);\n"
|
||
"}", s));
|
||
ASSERT_EQUALS("int g ( int ) ;",
|
||
tokenizeAndStringify("int g(int);\n"
|
||
"template <class F, class... Ts> auto h(F f, Ts... xs) {\n"
|
||
" auto e = f(g(xs)...);\n"
|
||
" return e;\n"
|
||
"}", s));
|
||
}
|
||
|
||
void simplifyHeadersAndUnusedTemplates2() {
|
||
const char code[] = "; template< typename T, u_int uBAR = 0 >\n"
|
||
"class Foo {\n"
|
||
"public:\n"
|
||
" void FooBar() {\n"
|
||
" new ( (uBAR ? uBAR : sizeof(T))) T;\n"
|
||
" }\n"
|
||
"};";
|
||
|
||
Settings s;
|
||
s.checkUnusedTemplates = false;
|
||
ASSERT_EQUALS(";", tokenizeAndStringify(code, s));
|
||
|
||
s.checkUnusedTemplates = true;
|
||
ASSERT_EQUALS("; template < typename T , u_int uBAR = 0 >\n"
|
||
"class Foo {\n"
|
||
"public:\n"
|
||
"void FooBar ( ) {\n"
|
||
"new ( uBAR ? uBAR : sizeof ( T ) ) T ;\n"
|
||
"}\n"
|
||
"} ;", tokenizeAndStringify(code, s));
|
||
}
|
||
|
||
// Don’t remove "(int *)"..
|
||
void simplifyCasts1() {
|
||
const char code[] = "int *f(int *);";
|
||
ASSERT_EQUALS("int * f ( int * ) ;", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
// remove static_cast..
|
||
void simplifyCasts2() {
|
||
const char code[] = "t = (static_cast<std::vector<int> *>(&p));\n";
|
||
ASSERT_EQUALS("t = & p ;", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyCasts3() {
|
||
// ticket #961
|
||
const char code[] = "assert (iplen >= (unsigned) ipv4->ip_hl * 4 + 20);";
|
||
const char expected[] = "assert ( iplen >= ipv4 . ip_hl * 4 + 20 ) ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyCasts4() {
|
||
// ticket #970
|
||
const char code[] = "{if (a >= (unsigned)(b)) {}}";
|
||
const char expected[] = "{ if ( a >= ( unsigned int ) ( b ) ) { } }";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyCasts5() {
|
||
// ticket #1817
|
||
ASSERT_EQUALS("a . data = f ;", tokenizeAndStringify("a->data = reinterpret_cast<void*>(static_cast<intptr_t>(f));", true));
|
||
}
|
||
|
||
void simplifyCasts7() {
|
||
ASSERT_EQUALS("str = malloc ( 3 )", tokenizeAndStringify("str=(char **)malloc(3)", true));
|
||
}
|
||
|
||
void simplifyCasts8() {
|
||
ASSERT_EQUALS("ptr1 = ptr2", tokenizeAndStringify("ptr1=(int * **)ptr2", true));
|
||
}
|
||
|
||
void simplifyCasts9() {
|
||
ASSERT_EQUALS("f ( ( double ) ( v1 ) * v2 )", tokenizeAndStringify("f((double)(v1)*v2)", true));
|
||
ASSERT_EQUALS("int v1 ; f ( ( double ) ( v1 ) * v2 )", tokenizeAndStringify("int v1; f((double)(v1)*v2)", true));
|
||
ASSERT_EQUALS("f ( ( A ) ( B ) & x )", tokenizeAndStringify("f((A)(B)&x)", true)); // #4439
|
||
}
|
||
|
||
void simplifyCasts10() {
|
||
ASSERT_EQUALS("; ( * f ) ( p ) ;", tokenizeAndStringify("; (*(void (*)(char *))f)(p);", true));
|
||
}
|
||
|
||
void simplifyCasts11() {
|
||
ASSERT_EQUALS("; x = 0 ;", tokenizeAndStringify("; *(int *)&x = 0;", true));
|
||
}
|
||
|
||
void simplifyCasts12() {
|
||
// #3935 - don't remove this cast
|
||
ASSERT_EQUALS("; ( ( short * ) data ) [ 5 ] = 0 ;", tokenizeAndStringify("; ((short*)data)[5] = 0;", true));
|
||
}
|
||
|
||
void simplifyCasts13() {
|
||
// casting deref / address of
|
||
ASSERT_EQUALS("; int x ; x = * y ;", tokenizeAndStringify(";int x=(int)*y;",true));
|
||
ASSERT_EQUALS("; int x ; x = & y ;", tokenizeAndStringify(";int x=(int)&y;",true));
|
||
TODO_ASSERT_EQUALS("; int x ; x = ( INT ) * y ;",
|
||
"; int x ; x = * y ;",
|
||
tokenizeAndStringify(";int x=(INT)*y;",true)); // INT might be a variable
|
||
TODO_ASSERT_EQUALS("; int x ; x = ( INT ) & y ;",
|
||
"; int x ; x = & y ;",
|
||
tokenizeAndStringify(";int x=(INT)&y;",true)); // INT might be a variable
|
||
|
||
// #4899 - False positive on unused variable
|
||
ASSERT_EQUALS("; float angle ; angle = tilt ;", tokenizeAndStringify("; float angle = (float) tilt;", true)); // status quo
|
||
ASSERT_EQUALS("; float angle ; angle = ( float ) - tilt ;", tokenizeAndStringify("; float angle = (float) -tilt;", true));
|
||
ASSERT_EQUALS("; float angle ; angle = ( float ) + tilt ;", tokenizeAndStringify("; float angle = (float) +tilt;", true));
|
||
ASSERT_EQUALS("; int a ; a = ( int ) ~ c ;", tokenizeAndStringify("; int a = (int)~c;", true));
|
||
}
|
||
|
||
void simplifyCasts14() { // const
|
||
// #5081
|
||
ASSERT_EQUALS("( ! ( & s ) . a ) ;", tokenizeAndStringify("(! ( (struct S const *) &s)->a);", true));
|
||
// #5244
|
||
ASSERT_EQUALS("bar ( & ptr ) ;", tokenizeAndStringify("bar((const X**)&ptr);",true));
|
||
}
|
||
|
||
void simplifyCasts15() { // #5996 - don't remove cast in 'a+static_cast<int>(b?60:0)'
|
||
ASSERT_EQUALS("a + ( b ? 60 : 0 ) ;",
|
||
tokenizeAndStringify("a + static_cast<int>(b ? 60 : 0);", true));
|
||
}
|
||
|
||
void simplifyCasts16() { // #6278
|
||
ASSERT_EQUALS("Get ( pArray ) ;",
|
||
tokenizeAndStringify("Get((CObject*&)pArray);", true));
|
||
}
|
||
|
||
void simplifyCasts17() { // #6110 - don't remove any parentheses in 'a(b)(c)'
|
||
ASSERT_EQUALS("{ if ( a ( b ) ( c ) >= 3 ) { } }",
|
||
tokenizeAndStringify("{ if (a(b)(c) >= 3) { } }", true));
|
||
}
|
||
|
||
void simplifyAt() {
|
||
ASSERT_EQUALS("int x ;", tokenizeAndStringify("int x@123;"));
|
||
ASSERT_EQUALS("bool x ;", tokenizeAndStringify("bool x@123:1;"));
|
||
ASSERT_EQUALS("char PORTB ; bool PB3 ;", tokenizeAndStringify("char PORTB @ 0x10; bool PB3 @ PORTB:3;\n"));
|
||
ASSERT_EQUALS("int x ;", tokenizeAndStringify("int x @ (0x1000 + 18);"));
|
||
|
||
ASSERT_EQUALS("int x [ 10 ] ;", tokenizeAndStringify("int x[10]@0x100;"));
|
||
|
||
ASSERT_EQUALS("interrupt@ f ( ) { }", tokenizeAndStringify("@interrupt f() {}"));
|
||
}
|
||
|
||
void inlineasm() {
|
||
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("asm { mov ax,bx };"));
|
||
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("_asm { mov ax,bx };"));
|
||
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("_asm mov ax,bx"));
|
||
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("__asm { mov ax,bx };"));
|
||
ASSERT_EQUALS("asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify("__asm__ __volatile__ ( \"mov ax,bx\" );"));
|
||
ASSERT_EQUALS("asm ( \"_emit 12h\" ) ;", tokenizeAndStringify("__asm _emit 12h ;"));
|
||
ASSERT_EQUALS("asm ( \"mov a , b\" ) ;", tokenizeAndStringify("__asm mov a, b ;"));
|
||
ASSERT_EQUALS("asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify("asm volatile (\"fnstcw %0\" : \"= m\" (old_cw));"));
|
||
ASSERT_EQUALS("asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify(" __asm__ (\"fnstcw %0\" : \"= m\" (old_cw));"));
|
||
ASSERT_EQUALS("asm ( \"\"ddd\"\" ) ;", tokenizeAndStringify(" __asm __volatile__ (\"ddd\") ;"));
|
||
ASSERT_EQUALS("asm ( \"\"ddd\"\" ) ;", tokenizeAndStringify(" __asm __volatile (\"ddd\") ;"));
|
||
ASSERT_EQUALS("asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify("__asm__ volatile ( \"mov ax,bx\" );"));
|
||
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ; int a ;", tokenizeAndStringify("asm { mov ax,bx } int a;"));
|
||
ASSERT_EQUALS("asm\n\n( \"mov ax , bx\" ) ;", tokenizeAndStringify("__asm\nmov ax,bx\n__endasm;"));
|
||
ASSERT_EQUALS("asm\n\n( \"push b ; for if\" ) ;", tokenizeAndStringify("__asm\npush b ; for if\n__endasm;"));
|
||
|
||
// 'asm ( ) ;' should be in the same line
|
||
ASSERT_EQUALS(";\n\nasm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";\n\n__asm__ volatile ( \"mov ax,bx\" );", true));
|
||
}
|
||
|
||
// #4725 - ^{}
|
||
void simplifyAsm2() {
|
||
ASSERT_THROW(ASSERT_EQUALS("void f ( ) { asm ( \"^{}\" ) ; }", tokenizeAndStringify("void f() { ^{} }")), InternalError);
|
||
ASSERT_THROW(ASSERT_EQUALS("void f ( ) { x ( asm ( \"^{}\" ) ) ; }", tokenizeAndStringify("void f() { x(^{}); }")), InternalError);
|
||
ASSERT_THROW(ASSERT_EQUALS("void f ( ) { foo ( A ( ) , asm ( \"^{bar();}\" ) ) ; }", tokenizeAndStringify("void f() { foo(A(), ^{ bar(); }); }")), InternalError);
|
||
ASSERT_THROW(ASSERT_EQUALS("int f0 ( Args args ) { asm ( \"asm(\"return^{returnsizeof...(Args);}()\")+^{returnsizeof...(args);}()\" )\n"
|
||
"2:\n"
|
||
"|\n"
|
||
"5:\n"
|
||
"6: ;\n"
|
||
"} ;", tokenizeAndStringify("int f0(Args args) {\n"
|
||
" return ^{\n"
|
||
" return sizeof...(Args);\n"
|
||
" }() + ^ {\n"
|
||
" return sizeof...(args);\n"
|
||
" }();\n"
|
||
"};")), InternalError);
|
||
ASSERT_THROW(ASSERT_EQUALS("int ( ^ block ) ( void ) = asm ( \"^{staticinttest=0;returntest;}\" )\n\n\n;",
|
||
tokenizeAndStringify("int(^block)(void) = ^{\n"
|
||
" static int test = 0;\n"
|
||
" return test;\n"
|
||
"};")), InternalError);
|
||
|
||
ASSERT_THROW(ASSERT_EQUALS("; return f ( a [ b = c ] , asm ( \"^{}\" ) ) ;",
|
||
tokenizeAndStringify("; return f(a[b=c],^{});")), InternalError); // #7185
|
||
ASSERT_EQUALS("{ return f ( asm ( \"^(void){somecode}\" ) ) ; }",
|
||
tokenizeAndStringify("{ return f(^(void){somecode}); }"));
|
||
ASSERT_THROW(ASSERT_EQUALS("; asm ( \"a?(b?(c,asm(\"^{}\")):0):^{}\" ) ;",
|
||
tokenizeAndStringify(";a?(b?(c,^{}):0):^{};")), InternalError);
|
||
ASSERT_EQUALS("template < typename T > "
|
||
"CImg < T > operator| ( const char * const expression , const CImg < T > & img ) { "
|
||
"return img | expression ; "
|
||
"} "
|
||
"template < typename T > "
|
||
"CImg < T > operator^ ( const char * const expression , const CImg < T > & img ) { "
|
||
"return img ^ expression ; "
|
||
"} "
|
||
"template < typename T > "
|
||
"CImg < T > operator== ( const char * const expression , const CImg < T > & img ) { "
|
||
"return img == expression ; "
|
||
"}",
|
||
tokenizeAndStringify("template < typename T >"
|
||
"inline CImg<T> operator|(const char *const expression, const CImg<T>& img) {"
|
||
" return img | expression ;"
|
||
"}"
|
||
"template<typename T>"
|
||
"inline CImg<T> operator^(const char *const expression, const CImg<T>& img) {"
|
||
" return img ^ expression;"
|
||
"}"
|
||
"template<typename T>"
|
||
"inline CImg<T> operator==(const char *const expression, const CImg<T>& img) {"
|
||
" return img == expression;"
|
||
"}"));
|
||
}
|
||
|
||
void ifAddBraces1() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" if (a);\n"
|
||
" else ;\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void f ( )\n"
|
||
"{\n"
|
||
"if ( a ) { ; }\n"
|
||
"else { ; }\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces2() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" if (a) if (b) { }\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void f ( )\n"
|
||
"{\n"
|
||
"if ( a ) { if ( b ) { } }\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces3() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" if (a) for (;;) { }\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void f ( )\n"
|
||
"{\n"
|
||
"if ( a ) { for ( ; ; ) { } }\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces4() {
|
||
const char code[] = "char * foo ()\n"
|
||
"{\n"
|
||
" char *str = malloc(10);\n"
|
||
" if (somecondition)\n"
|
||
" for ( ; ; )\n"
|
||
" { }\n"
|
||
" return str;\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("char * foo ( )\n"
|
||
"{\n"
|
||
"char * str ; str = malloc ( 10 ) ;\n"
|
||
"if ( somecondition ) {\n"
|
||
"for ( ; ; )\n"
|
||
"{ } }\n"
|
||
"return str ;\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces5() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
"for(int i = 0; i < 2; i++)\n"
|
||
"if(true)\n"
|
||
"return;\n"
|
||
"\n"
|
||
"return;\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS("void f ( )\n"
|
||
"{\n"
|
||
"for ( int i = 0 ; i < 2 ; i ++ ) {\n"
|
||
"\n"
|
||
"return ; }\n\n"
|
||
"return ;\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces7() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
"int a;\n"
|
||
"if( a )\n"
|
||
" ({a=4;}),({a=5;});\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void f ( )\n"
|
||
"{\n"
|
||
"int a ;\n"
|
||
"if ( a ) {\n"
|
||
"( { a = 4 ; } ) , ( { a = 5 ; } ) ; }\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces9() {
|
||
// ticket #990
|
||
const char code[] =
|
||
"void f() {"
|
||
" for (int k=0; k<VectorSize; k++)"
|
||
" LOG_OUT(ID_Vector[k])"
|
||
"}";
|
||
const char expected[] =
|
||
"void f ( ) { "
|
||
"for ( int k = 0 ; k < VectorSize ; k ++ ) "
|
||
"LOG_OUT ( ID_Vector [ k ] ) "
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces11() {
|
||
const char code[] = "{ if (x) if (y) ; else ; }";
|
||
const char expected[] = "{ if ( x ) { if ( y ) { ; } else { ; } } }";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces12() {
|
||
// ticket #1424
|
||
const char code[] = "{ if (x) do { } while(x); }";
|
||
const char expected[] = "{ if ( x ) { do { } while ( x ) ; } }";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces13() {
|
||
// ticket #1809
|
||
const char code[] = "{ if (x) if (y) { } else { } else { } }";
|
||
const char expected[] = "{ if ( x ) { if ( y ) { } else { } } else { } }";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
|
||
// ticket #1809
|
||
const char code2[] = "{ if (x) while (y) { } else { } }";
|
||
const char expected2[] = "{ if ( x ) { while ( y ) { } } else { } }";
|
||
ASSERT_EQUALS(expected2, tokenizeAndStringify(code2, true));
|
||
}
|
||
|
||
void ifAddBraces15() {
|
||
// ticket #2616 - unknown macro before if
|
||
// TODO: Remove "A" or change it to ";A;". Then cleanup Tokenizer::ifAddBraces().
|
||
ASSERT_EQUALS("{ A if ( x ) { y ( ) ; } }", tokenizeAndStringify("{A if(x)y();}", false));
|
||
}
|
||
|
||
void ifAddBraces16() {
|
||
// ticket #2873 - the fix is not needed anymore.
|
||
{
|
||
const char code[] = "void f() { "
|
||
"(void) ( { if(*p) (*p) = x(); } ) "
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) { ( void ) ( { if ( * p ) { ( * p ) = x ( ) ; } } ) }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void ifAddBraces17() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" if (a)\n"
|
||
" bar1 ();\n"
|
||
"\n"
|
||
" else\n"
|
||
" bar2 ();\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void f ( )\n"
|
||
"{\n"
|
||
"if ( a ) {\n"
|
||
"bar1 ( ) ; }\n"
|
||
"\n"
|
||
"else {\n"
|
||
"bar2 ( ) ; }\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces18() {
|
||
// ticket #3424 - if if { } else else
|
||
ASSERT_EQUALS("{ if ( x ) { if ( y ) { } else { ; } } else { ; } }",
|
||
tokenizeAndStringify("{ if(x) if(y){}else;else;}", false));
|
||
|
||
ASSERT_EQUALS("{ if ( x ) { if ( y ) { if ( z ) { } else { ; } } else { ; } } else { ; } }",
|
||
tokenizeAndStringify("{ if(x) if(y) if(z){}else;else;else;}", false));
|
||
}
|
||
|
||
void ifAddBraces19() {
|
||
// #3928 - if for if else
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" if (a)\n"
|
||
" for (;;)\n"
|
||
" if (b)\n"
|
||
" bar1();\n"
|
||
" else\n"
|
||
" bar2();\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void f ( )\n"
|
||
"{\n"
|
||
"if ( a ) {\n"
|
||
"for ( ; ; ) {\n"
|
||
"if ( b ) {\n"
|
||
"bar1 ( ) ; }\n"
|
||
"else {\n"
|
||
"bar2 ( ) ; } } }\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void ifAddBraces20() { // #5012 - syntax error 'else }'
|
||
const char code[] = "void f() { if(x) {} else }";
|
||
ASSERT_THROW(tokenizeAndStringify(code, true), InternalError);
|
||
}
|
||
|
||
void ifAddBraces21() { // #5332 - if (x) label: {} ...
|
||
const char code[] = "void f() { if(x) label: {} a=1; }";
|
||
ASSERT_EQUALS("void f ( ) { if ( x ) { label : ; { } } a = 1 ; }", tokenizeAndStringify(code, false));
|
||
}
|
||
|
||
void whileAddBraces() {
|
||
const char code[] = "{while(a);}";
|
||
ASSERT_EQUALS("{ while ( a ) { ; } }", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void doWhileAddBraces() {
|
||
{
|
||
const char code[] = "{do ; while (0);}";
|
||
const char result[] = "{ do { ; } while ( 0 ) ; }";
|
||
|
||
ASSERT_EQUALS(result, tokenizeAndStringify(code, false));
|
||
}
|
||
|
||
{
|
||
const char code[] = "{ UNKNOWN_MACRO ( do ) ; while ( a -- ) ; }";
|
||
const char result[] = "{ UNKNOWN_MACRO ( do ) ; while ( a -- ) { ; } }";
|
||
|
||
ASSERT_EQUALS(result, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "{ UNKNOWN_MACRO ( do , foo ) ; while ( a -- ) ; }";
|
||
const char result[] = "{ UNKNOWN_MACRO ( do , foo ) ; while ( a -- ) { ; } }";
|
||
|
||
ASSERT_EQUALS(result, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void foo ( int c , int d ) {\n"
|
||
" do\n"
|
||
" if ( c ) {\n"
|
||
" while ( c ) { c -- ; }\n"
|
||
" }\n"
|
||
" while ( -- d > 0 ) ;\n"
|
||
" return 0 ;\n"
|
||
"}\n";
|
||
const char result[] = "void foo ( int c , int d ) {\n"
|
||
"do {\n"
|
||
"if ( c ) {\n"
|
||
"while ( c ) { c -- ; }\n"
|
||
"} }\n"
|
||
"while ( -- d > 0 ) ;\n"
|
||
"return 0 ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(result, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void foo ( int c , int d ) {\n"
|
||
" do\n"
|
||
" do c -- ; while ( c ) ;\n"
|
||
" while ( -- d > 0 ) ;\n"
|
||
" return 0 ;\n"
|
||
"}\n";
|
||
const char result[] = "void foo ( int c , int d ) {\n"
|
||
"do {\n"
|
||
"do { c -- ; } while ( c ) ; }\n"
|
||
"while ( -- d > 0 ) ;\n"
|
||
"return 0 ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(result, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
// #8148 - while inside the do-while body
|
||
const char code[] = "void foo() {\n"
|
||
" do { while (x) f(); } while (y);\n"
|
||
"}";
|
||
const char result[] = "void foo ( ) {\n"
|
||
"do { while ( x ) { f ( ) ; } } while ( y ) ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(result, tokenizeAndStringify(code, true));
|
||
}
|
||
}
|
||
|
||
void forAddBraces1() {
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" for(;;)\n"
|
||
" if (a) { }\n"
|
||
" else { }\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"for ( ; ; ) {\n"
|
||
"if ( a ) { }\n"
|
||
"else { } }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" for(;;)\n"
|
||
" if (a) { }\n"
|
||
" else if (b) { }\n"
|
||
" else { }\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"for ( ; ; ) {\n"
|
||
"if ( a ) { }\n"
|
||
"else { if ( b ) { }\n"
|
||
"else { } } }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
}
|
||
|
||
void forAddBraces2() { // #5088
|
||
const char code[] = "void f() {\n"
|
||
" for(;;) try { } catch (...) { }\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"for ( ; ; ) { try { } catch ( ... ) { } }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
std::string simplifyKnownVariables(const char code[]) {
|
||
errout.str("");
|
||
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
|
||
tokenizer.simplifyKnownVariables();
|
||
|
||
return tokenizer.tokens()->stringifyList(nullptr, false);
|
||
}
|
||
|
||
void simplifyKnownVariables1() {
|
||
{
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" int a = 10;\n"
|
||
" if (a);\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { int a ; a = 10 ; if ( 10 ) { ; } }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" int a = 10;\n"
|
||
" if (!a);\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { int a ; a = 10 ; if ( ! 10 ) { ; } }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables2() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" int a = 10;\n"
|
||
" a = g();\n"
|
||
" if (a);\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { int a ; a = 10 ; a = g ( ) ; if ( a ) { ; } }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables3() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" int a = 4;\n"
|
||
" while(true){\n"
|
||
" break;\n"
|
||
" a = 10;\n"
|
||
" }\n"
|
||
" if (a);\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { int a ; a = 4 ; while ( true ) { break ; a = 10 ; } if ( a ) { ; } }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables4() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" int a = 4;\n"
|
||
" if ( g(a));\n"
|
||
"}\n";
|
||
|
||
// TODO: if a is passed by value is is ok to simplify..
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { int a ; a = 4 ; if ( g ( a ) ) { ; } }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables5() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" int a = 4;\n"
|
||
" if ( a = 5 );\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { int a ; a = 4 ; if ( a = 5 ) { ; } }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables6() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" char str[2];"
|
||
" int a = 4;\n"
|
||
" str[a] = 0;\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { char str [ 2 ] ; int a ; a = 4 ; str [ 4 ] = 0 ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables7() {
|
||
const char code[] = "void foo()\n"
|
||
"{\n"
|
||
" int i = 22;\n"
|
||
" abc[i++] = 1;\n"
|
||
" abc[++i] = 2;\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void foo ( ) { int i ; i = 24 ; abc [ 22 ] = 1 ; abc [ 24 ] = 2 ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables8() {
|
||
const char code[] = "void foo()\n"
|
||
"{\n"
|
||
" int i = 22;\n"
|
||
" i++;\n"
|
||
" abc[i] = 0;\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void foo ( ) { int i ; i = 23 ; abc [ 23 ] = 0 ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables9() {
|
||
const char code[] = "void foo()\n"
|
||
"{\n"
|
||
" int a = 1, b = 2;\n"
|
||
" if (a < b)\n"
|
||
" ;\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void foo ( ) { int a ; a = 1 ; int b ; b = 2 ; if ( 1 < 2 ) { ; } }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables10() {
|
||
{
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" bool b=false;\n"
|
||
"\n"
|
||
" {\n"
|
||
" b = true;\n"
|
||
" }\n"
|
||
"\n"
|
||
" if( b )\n"
|
||
" {\n"
|
||
" a();\n"
|
||
" }\n"
|
||
"}\n";
|
||
|
||
const std::string expected1("void f ( ) {"
|
||
" bool b ; b = false ;"
|
||
" { b = true ; }");
|
||
|
||
TODO_ASSERT_EQUALS(
|
||
expected1 + " if ( true ) { a ( ) ; } }",
|
||
expected1 + " if ( b ) { a ( ) ; } }",
|
||
simplifyKnownVariables(code));
|
||
|
||
}
|
||
|
||
{
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" bool b=false;\n"
|
||
" { b = false; }\n"
|
||
" {\n"
|
||
" b = true;\n"
|
||
" }\n"
|
||
"\n"
|
||
" if( b )\n"
|
||
" {\n"
|
||
" a();\n"
|
||
" }\n"
|
||
"}\n";
|
||
|
||
TODO_ASSERT_EQUALS(
|
||
"void f ( ) { bool b ; b = false ; { b = false ; } { b = true ; } if ( true ) { a ( ) ; } }",
|
||
"void f ( ) { bool b ; b = false ; { b = false ; } { b = true ; } if ( b ) { a ( ) ; } }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" int b=0;\n"
|
||
" b = 1;\n"
|
||
" for( int i = 0; i < 10; i++ )"
|
||
" {\n"
|
||
" }\n"
|
||
"\n"
|
||
" return b;\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { int b ; b = 0 ; b = 1 ; for ( int i = 0 ; i < 10 ; i ++ ) { } return 1 ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables11() {
|
||
const char code[] = "const int foo = 0;\n"
|
||
"int main()\n"
|
||
"{\n"
|
||
" int foo=0;\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"int main ( ) { int foo ; foo = 0 ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables13() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" int i = 10;\n"
|
||
" while(--i) {}\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { int i ; i = 10 ; while ( -- i ) { } }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables14() {
|
||
// ticket #753
|
||
const char code[] = "void f ( ) { int n ; n = 1 ; do { ++ n ; } while ( n < 10 ) ; }";
|
||
ASSERT_EQUALS(code, simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables15() {
|
||
{
|
||
const char code[] = "int main()\n"
|
||
"{\n"
|
||
" int x=5;\n"
|
||
" std::cout << 10 / x << std::endl;\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"int main ( ) { int x ; x = 5 ; std :: cout << 10 / 5 << std :: endl ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "int main()\n"
|
||
"{\n"
|
||
" int x=5;\n"
|
||
" std::cout << x / ( x == 1 ) << std::endl;\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"int main ( ) { int x ; x = 5 ; std :: cout << 5 / ( 5 == 1 ) << std :: endl ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables16() {
|
||
// ticket #807 - segmentation fault when macro isn't found
|
||
const char code[] = "void f ( ) { int n = 1; DISPATCH(while); }";
|
||
ASSERT_THROW(simplifyKnownVariables(code), InternalError);
|
||
}
|
||
|
||
void simplifyKnownVariables17() {
|
||
// ticket #807 - segmentation fault when macro isn't found
|
||
const char code[] = "void f ( ) { char *s = malloc(100);mp_ptr p = s; p++; }";
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { char * s ; s = malloc ( 100 ) ; mp_ptr p ; p = s ; p ++ ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables18() {
|
||
const char code[] = "void f ( ) { char *s = malloc(100);mp_ptr p = s; ++p; }";
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { char * s ; s = malloc ( 100 ) ; mp_ptr p ; p = s ; ++ p ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables19() {
|
||
const char code[] = "void f ( ) { int i=0; do { if (i>0) { a(); } i=b(); } while (i != 12); }";
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { int i ; i = 0 ; do { if ( i > 0 ) { a ( ) ; } i = b ( ) ; } while ( i != 12 ) ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables20() {
|
||
const char code[] = "void f()\n"
|
||
"{\n"
|
||
" int i = 0;\n"
|
||
" if (x) {\n"
|
||
" if (i) i=0;\n"
|
||
" }\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void f ( ) { int i ; i = 0 ; if ( x ) { if ( 0 ) { i = 0 ; } } }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables21() {
|
||
const char code[] = "void foo() { int n = 10; for (int i = 0; i < n; ++i) { } }";
|
||
|
||
ASSERT_EQUALS(
|
||
"void foo ( ) { int n ; n = 10 ; for ( int i = 0 ; i < 10 ; ++ i ) { } }",
|
||
simplifyKnownVariables(code));
|
||
|
||
ASSERT_EQUALS(
|
||
"void foo ( int i ) { int n ; n = i ; for ( i = 0 ; i < n ; ++ i ) { } }",
|
||
simplifyKnownVariables("void foo(int i) { int n = i; for (i = 0; i < n; ++i) { } }"));
|
||
}
|
||
|
||
void simplifyKnownVariables22() {
|
||
// This testcase is related to ticket #1169
|
||
{
|
||
const char code[] = "void foo()\n"
|
||
"{\n"
|
||
" int n = 10;\n"
|
||
" i = (n >> 1);\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void foo ( ) { int n ; n = 10 ; i = 10 >> 1 ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
{
|
||
const char code[] = "void foo()\n"
|
||
"{\n"
|
||
" int n = 10;\n"
|
||
" i = (n << 1);\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void foo ( ) { int n ; n = 10 ; i = 10 << 1 ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
{
|
||
const char code[] = "void foo()\n"
|
||
"{\n"
|
||
" int n = 10;\n"
|
||
" i = (1 << n);\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void foo ( ) { int n ; n = 10 ; i = 1 << 10 ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
{
|
||
const char code[] = "void foo()\n"
|
||
"{\n"
|
||
" int n = 10;\n"
|
||
" i = (1 >> n);\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS(
|
||
"void foo ( ) { int n ; n = 10 ; i = 1 >> 10 ; }",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables23() {
|
||
// This testcase is related to ticket #1596
|
||
const char code[] = "void foo(int x)\n"
|
||
"{\n"
|
||
" int a[10], c = 0;\n"
|
||
" if (x) {\n"
|
||
" a[c] = 0;\n"
|
||
" c++;\n"
|
||
" } else {\n"
|
||
" a[c] = 0;\n"
|
||
" }\n"
|
||
"}\n";
|
||
|
||
TODO_ASSERT_EQUALS(
|
||
"void foo ( int x ) "
|
||
"{"
|
||
" int a [ 10 ] ; int c ; c = 0 ;"
|
||
" if ( x ) { a [ 0 ] = 0 ; c = 1 ; }"
|
||
" else { a [ 0 ] = 0 ; } "
|
||
"}",
|
||
|
||
"void foo ( int x ) "
|
||
"{"
|
||
" int a [ 10 ] ; int c ; c = 0 ;"
|
||
" if ( x ) { a [ 0 ] = 0 ; c ++ ; }"
|
||
" else { a [ c ] = 0 ; } "
|
||
"}",
|
||
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables25() {
|
||
{
|
||
// This testcase is related to ticket #1646
|
||
const char code[] = "void foo(char *str)\n"
|
||
"{\n"
|
||
" int i;\n"
|
||
" for (i=0;i<10;++i) {\n"
|
||
" if (*str == 0) goto label;\n"
|
||
" }\n"
|
||
" return;\n"
|
||
"label:\n"
|
||
" str[i] = 0;\n"
|
||
"}\n";
|
||
|
||
// Current result
|
||
ASSERT_EQUALS(
|
||
"void foo ( char * str ) "
|
||
"{"
|
||
" int i ;"
|
||
" for ( i = 0 ; i < 10 ; ++ i ) {"
|
||
" if ( * str == 0 ) { goto label ; }"
|
||
" }"
|
||
" return ;"
|
||
" label : ;"
|
||
" str [ i ] = 0 ; "
|
||
"}",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
{
|
||
// This testcase is related to ticket #1646
|
||
const char code[] = "void foo(char *str)\n"
|
||
"{\n"
|
||
" int i;\n"
|
||
" for (i=0;i<10;++i) { }\n"
|
||
" return;\n"
|
||
" str[i] = 0;\n"
|
||
"}\n";
|
||
|
||
// Current result
|
||
ASSERT_EQUALS(
|
||
"void foo ( char * str ) "
|
||
"{"
|
||
" int i ;"
|
||
" for ( i = 0 ; i < 10 ; ++ i ) { }"
|
||
" return ;"
|
||
" str [ i ] = 0 ; "
|
||
"}",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables27() {
|
||
// This testcase is related to ticket #1633
|
||
const char code[] = "void foo()\n"
|
||
"{\n"
|
||
" int i1 = 1;\n"
|
||
" int i2 = 2;\n"
|
||
" int i3 = (i1 + i2) * 3;\n"
|
||
"}\n";
|
||
ASSERT_EQUALS(
|
||
"void foo ( ) "
|
||
"{"
|
||
" int i1 ; i1 = 1 ;"
|
||
" int i2 ; i2 = 2 ;"
|
||
" int i3 ; i3 = ( 1 + 2 ) * 3 ; "
|
||
"}",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables28() {
|
||
const char code[] = "void foo(int g)\n"
|
||
"{\n"
|
||
" int i = 2;\n"
|
||
" if (g) {\n"
|
||
" }\n"
|
||
" if (i > 0) {\n"
|
||
" }\n"
|
||
"}\n";
|
||
ASSERT_EQUALS(
|
||
"void foo ( int g ) "
|
||
"{"
|
||
" int i ; i = 2 ;"
|
||
" if ( g ) { }"
|
||
" if ( 2 > 0 ) { } "
|
||
"}",
|
||
simplifyKnownVariables(code));
|
||
}
|
||
|
||
void simplifyKnownVariables29() { // ticket #1811
|
||
{
|
||
const char code[] = "int foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h + i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: int foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 + v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "int foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h - i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: int foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 - v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "int foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h * i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: int foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 * v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "int foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h / i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: int foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 / v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "int foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h & i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: int foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 & v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "int foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h | i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: int foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 | v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "int foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h ^ i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: int foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 ^ v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "int foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h % i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: int foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 % v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "int foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h >> i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: int foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 >> v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "int foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h << i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: int foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 << v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "bool foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h == i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: bool foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 == v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "bool foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h != i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: bool foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 != v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "bool foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h > i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: bool foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 > v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "bool foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h >= i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: bool foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 >= v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "bool foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h < i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: bool foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 < v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "bool foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h <= i;\n"
|
||
"}\n";
|
||
const char expected[] = "1: bool foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 <= v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "bool foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h && i;\n"
|
||
"}\n";
|
||
const char wanted[] = "1: bool foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 && v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(wanted, tokenizeDebugListing(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "bool foo(int u, int v)\n"
|
||
"{\n"
|
||
" int h = u;\n"
|
||
" int i = v;\n"
|
||
" return h || i;\n"
|
||
"}\n";
|
||
const char wanted[] = "1: bool foo ( int u@1 , int v@2 )\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4:\n"
|
||
"5: return u@1 || v@2 ;\n"
|
||
"6: }\n";
|
||
ASSERT_EQUALS(wanted, tokenizeDebugListing(code, true));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables30() {
|
||
const char code[] = "int foo() {\n"
|
||
" iterator it1 = ints.begin();\n"
|
||
" iterator it2 = it1;\n"
|
||
" for (++it2;it2!=ints.end();++it2);\n"
|
||
"}\n";
|
||
const char expected[] = "int foo ( ) {\n"
|
||
"iterator it1 ; it1 = ints . begin ( ) ;\n"
|
||
"iterator it2 ; it2 = it1 ;\n"
|
||
"for ( ++ it2 ; it2 != ints . end ( ) ; ++ it2 ) { ; }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables31() {
|
||
const char code[] = "void foo(const char str[]) {\n"
|
||
" const char *p = str;\n"
|
||
" if (p[0] == 0) {\n"
|
||
" }\n"
|
||
"}\n";
|
||
const char expected[] = "void foo ( const char str [ ] ) {\n"
|
||
"const char * p ; p = str ;\n"
|
||
"if ( str [ 0 ] == 0 ) {\n"
|
||
"}\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables32() {
|
||
{
|
||
const char code[] = "void foo() {\n"
|
||
" const int x = 0;\n"
|
||
" bar(0,x);\n"
|
||
"}\n";
|
||
const char expected[] = "void foo ( ) {\n\nbar ( 0 , 0 ) ;\n}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "static int const SZ = 22; char str[SZ];\n";
|
||
ASSERT_EQUALS("char str [ 22 ] ;", tokenizeAndStringify(code,true));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables33() {
|
||
const char code[] = "static void foo(struct Foo *foo) {\n"
|
||
" foo->a = 23;\n"
|
||
" x[foo->a] = 0;\n"
|
||
"}\n";
|
||
const char expected[] = "static void foo ( struct Foo * foo ) {\n"
|
||
"foo . a = 23 ;\n"
|
||
"x [ 23 ] = 0 ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables34() {
|
||
const char code[] = "void f() {\n"
|
||
" int x = 10;\n"
|
||
" do { cin >> x; } while (x > 5);\n"
|
||
" a[x] = 0;\n"
|
||
"}\n";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"int x ; x = 10 ;\n"
|
||
"do { cin >> x ; } while ( x > 5 ) ;\n"
|
||
"a [ x ] = 0 ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables35() {
|
||
// Ticket #2353
|
||
const char code[] = "int f() {"
|
||
" int x = 0;"
|
||
" if (x == 0) {"
|
||
" return 0;"
|
||
" }"
|
||
" return 10 / x;"
|
||
"}";
|
||
const char expected[] = "int f ( ) { int x ; x = 0 ; { return 0 ; } }";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables36() {
|
||
// Ticket #2304
|
||
const char code[] = "void f() {"
|
||
" const char *q = \"hello\";"
|
||
" strcpy(p, q);"
|
||
"}";
|
||
const char expected[] = "void f ( ) { const char * q ; q = \"hello\" ; strcpy ( p , \"hello\" ) ; }";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
|
||
// Ticket #5972
|
||
const char code2[] = "void f() {"
|
||
" char buf[10] = \"ab\";"
|
||
" memset(buf, 0, 10);"
|
||
"}";
|
||
const char expected2[] = "void f ( ) { char buf [ 10 ] = \"ab\" ; memset ( buf , 0 , 10 ) ; }";
|
||
ASSERT_EQUALS(expected2, tokenizeAndStringify(code2, true));
|
||
}
|
||
|
||
void simplifyKnownVariables37() {
|
||
// Ticket #2398 - no simplification in for loop
|
||
const char code[] = "void f() {\n"
|
||
" double x = 0;\n"
|
||
" for (int iter=0; iter<42; iter++) {\n"
|
||
" int EvaldF = 1;\n"
|
||
" if (EvaldF)\n"
|
||
" Eval (x);\n"
|
||
" }\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"double x ; x = 0 ;\n"
|
||
"for ( int iter = 0 ; iter < 42 ; iter ++ ) {\n"
|
||
"\n"
|
||
"\n"
|
||
"Eval ( x ) ;\n"
|
||
"}\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables38() {
|
||
// Ticket #2399 - simplify conditions
|
||
const char code[] = "void f() {\n"
|
||
" int x = 0;\n"
|
||
" int y = 1;\n"
|
||
" if (x || y);\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"\n"
|
||
"\n"
|
||
";\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables39() {
|
||
// Ticket #2296 - simplify pointer alias 'delete p;'
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" int *x;\n"
|
||
" int *y = x;\n"
|
||
" delete y;\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\nint * x ;\n\ndelete x ;\n}", tokenizeAndStringify(code, true));
|
||
}
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" int *x;\n"
|
||
" int *y = x;\n"
|
||
" delete [] y;\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\nint * x ;\n\ndelete [ ] x ;\n}", tokenizeAndStringify(code, true));
|
||
}
|
||
}
|
||
|
||
|
||
void simplifyKnownVariables40() {
|
||
const char code[] = "void f() {\n"
|
||
" char c1 = 'a';\n"
|
||
" char c2 = { c1 };\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\n\nchar c2 ; c2 = { 'a' } ;\n}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables41() {
|
||
const char code[] = "void f() {\n"
|
||
" int x = 0;\n"
|
||
" const int *p; p = &x;\n"
|
||
" if (p) { return 0; }\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\nint x ; x = 0 ;\nconst int * p ; p = & x ;\nif ( & x ) { return 0 ; }\n}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables42() {
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" char str1[10], str2[10];\n"
|
||
" strcpy(str1, \"abc\");\n"
|
||
" strcpy(str2, str1);\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"char str1 [ 10 ] ; char str2 [ 10 ] ;\n"
|
||
"strcpy ( str1 , \"abc\" ) ;\n"
|
||
"strcpy ( str2 , \"abc\" ) ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" char a[10];\n"
|
||
" strcpy(a, \"hello\");\n"
|
||
" strcat(a, \"!\");\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"char a [ 10 ] ;\n"
|
||
"strcpy ( a , \"hello\" ) ;\n"
|
||
"strcat ( a , \"!\" ) ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Native, "test.c"));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void f() {"
|
||
" char *s = malloc(10);"
|
||
" strcpy(s, \"\");"
|
||
" free(s);"
|
||
"}";
|
||
const char expected[] = "void f ( ) {"
|
||
" char * s ; s = malloc ( 10 ) ;"
|
||
" strcpy ( s , \"\" ) ;"
|
||
" free ( s ) ; "
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void f(char *p, char *q) {"
|
||
" strcpy(p, \"abc\");"
|
||
" q = p;"
|
||
"}";
|
||
const char expected[] = "void f ( char * p , char * q ) {"
|
||
" strcpy ( p , \"abc\" ) ;"
|
||
" q = p ; "
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
// 3538
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" char s[10];\n"
|
||
" strcpy(s, \"123\");\n"
|
||
" if (s[6] == ' ');\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"char s [ 10 ] ;\n"
|
||
"strcpy ( s , \"123\" ) ;\n"
|
||
"if ( s [ 6 ] == ' ' ) { ; }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code,true));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables43() {
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" int a, *p; p = &a;\n"
|
||
" { int a = *p; }\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"int a ; int * p ; p = & a ;\n"
|
||
"{ int a ; a = * p ; }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" int *a, **p; p = &a;\n"
|
||
" { int *a = *p; }\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"int * a ; int * * p ; p = & a ;\n"
|
||
"{ int * a ; a = * p ; }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables44() {
|
||
const char code[] = "void a() {\n"
|
||
" static int i = 10;\n"
|
||
" b(i++);\n"
|
||
"}";
|
||
const char expected[] = "void a ( ) {\n"
|
||
"static int i = 10 ;\n"
|
||
"b ( i ++ ) ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables45() {
|
||
const char code[] = "class Fred {\n"
|
||
"private:\n"
|
||
" const static int NUM = 2;\n"
|
||
" int array[NUM];\n"
|
||
"}";
|
||
const char expected[] = "class Fred {\n"
|
||
"private:\n"
|
||
"\n"
|
||
"int array [ 2 ] ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables46() {
|
||
const char code[] = "void f() {\n"
|
||
" int x = 0;\n"
|
||
" cin >> x;\n"
|
||
" return x;\n"
|
||
"}";
|
||
|
||
{
|
||
const char expected[] = "void f ( ) {\n"
|
||
"int x ; x = 0 ;\n"
|
||
"cin >> x ;\n"
|
||
"return x ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Native, "test.cpp"));
|
||
}
|
||
|
||
{
|
||
const char expected[] = "void f ( ) {\n"
|
||
"\n"
|
||
"cin >> 0 ;\n"
|
||
"return 0 ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Native, "test.c"));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables47() {
|
||
// #3621
|
||
const char code[] = "void f() {\n"
|
||
" int x = 0;\n"
|
||
" cin >> std::hex >> x;\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"int x ; x = 0 ;\n"
|
||
"cin >> std :: hex >> x ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Native, "test.cpp"));
|
||
}
|
||
|
||
void simplifyKnownVariables48() {
|
||
// #3754
|
||
const char code[] = "void f(int sz) {\n"
|
||
" int i;\n"
|
||
" for (i = 0; ((i<sz) && (sz>3)); ++i) { }\n"
|
||
"}";
|
||
const char expected[] = "void f ( int sz ) {\n"
|
||
"int i ;\n"
|
||
"for ( i = 0 ; ( i < sz ) && ( sz > 3 ) ; ++ i ) { }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Native, "test.c"));
|
||
}
|
||
|
||
void simplifyKnownVariables49() { // #3691
|
||
const char code[] = "void f(int sz) {\n"
|
||
" switch (x) {\n"
|
||
" case 1: sz = 2; continue;\n"
|
||
" case 2: x = sz; break;\n"
|
||
" }\n"
|
||
"}";
|
||
const char expected[] = "void f ( int sz ) {\n"
|
||
"switch ( x ) {\n"
|
||
"case 1 : ; sz = 2 ; continue ;\n"
|
||
"case 2 : ; x = sz ; break ;\n"
|
||
"}\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Native, "test.c"));
|
||
}
|
||
|
||
void simplifyKnownVariables50() { // #4066
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" char str1[10], str2[10];\n"
|
||
" sprintf(str1, \"%%\");\n"
|
||
" strcpy(str2, str1);\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"char str1 [ 10 ] ; char str2 [ 10 ] ;\n"
|
||
"sprintf ( str1 , \"%%\" ) ;\n"
|
||
"strcpy ( str2 , \"%\" ) ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" char str1[25], str2[25];\n"
|
||
" sprintf(str1, \"abcdef%%%% and %% and %\");\n"
|
||
" strcpy(str2, str1);\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"char str1 [ 25 ] ; char str2 [ 25 ] ;\n"
|
||
"sprintf ( str1 , \"abcdef%%%% and %% and %\" ) ;\n"
|
||
"strcpy ( str2 , \"abcdef%% and % and %\" ) ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
{
|
||
const char code[] = "void f() {\n"
|
||
" char str1[10], str2[10];\n"
|
||
" sprintf(str1, \"abc\");\n"
|
||
" strcpy(str2, str1);\n"
|
||
"}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"char str1 [ 10 ] ; char str2 [ 10 ] ;\n"
|
||
"sprintf ( str1 , \"abc\" ) ;\n"
|
||
"strcpy ( str2 , \"abc\" ) ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
{
|
||
//don't simplify '&x'!
|
||
const char code[] = "const char * foo ( ) {\n"
|
||
"const char x1 = 'b' ;\n"
|
||
"f ( & x1 ) ;\n"
|
||
"const char x2 = 'b' ;\n"
|
||
"f ( y , & x2 ) ;\n"
|
||
"const char x3 = 'b' ;\n"
|
||
"t = & x3 ;\n"
|
||
"const char x4 = 'b' ;\n"
|
||
"t = y + & x4 ;\n"
|
||
"const char x5 = 'b' ;\n"
|
||
"z [ & x5 ] = y ;\n"
|
||
"const char x6 = 'b' ;\n"
|
||
"v = { & x6 } ;\n"
|
||
"const char x7 = 'b' ;\n"
|
||
"return & x7 ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code, true));
|
||
}
|
||
{
|
||
//don't simplify '&x'!
|
||
const char code[] = "const int * foo ( ) {\n"
|
||
"const int x1 = 1 ;\n"
|
||
"f ( & x1 ) ;\n"
|
||
"const int x2 = 1 ;\n"
|
||
"f ( y , & x2 ) ;\n"
|
||
"const int x3 = 1 ;\n"
|
||
"t = & x3 ;\n"
|
||
"const int x4 = 1 ;\n"
|
||
"t = y + & x4 ;\n"
|
||
"const int x5 = 1 ;\n"
|
||
"z [ & x5 ] = y ;\n"
|
||
"const int x6 = 1 ;\n"
|
||
"v = { & x6 } ;\n"
|
||
"const int x7 = 1 ;\n"
|
||
"return & x7 ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code, true));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariables51() { // #4409 hang
|
||
const char code[] = "void mhz_M(int enough) {\n"
|
||
" TYPE *x=&x, **p=x, **q = NULL;\n"
|
||
" BENCH1(q = _mhz_M(n); n = 1;)\n"
|
||
" use_pointer(q);\n"
|
||
"}";
|
||
ASSERT_THROW(tokenizeAndStringify(code, true), InternalError);
|
||
}
|
||
|
||
void simplifyKnownVariables52() { // #4728 "= x %op%"
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 + z ; }", tokenizeAndStringify("void f() { int x=34; int y=x+z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 - z ; }", tokenizeAndStringify("void f() { int x=34; int y=x-z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 * z ; }", tokenizeAndStringify("void f() { int x=34; int y=x*z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 / z ; }", tokenizeAndStringify("void f() { int x=34; int y=x/z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 % z ; }", tokenizeAndStringify("void f() { int x=34; int y=x%z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 & z ; }", tokenizeAndStringify("void f() { int x=34; int y=x&z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 | z ; }", tokenizeAndStringify("void f() { int x=34; int y=x|z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 ^ z ; }", tokenizeAndStringify("void f() { int x=34; int y=x^z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 << z ; }", tokenizeAndStringify("void f() { int x=34; int y=x<<z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 >> z ; }", tokenizeAndStringify("void f() { int x=34; int y=x>>z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 && z ; }", tokenizeAndStringify("void f() { int x=34; int y=x&&z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 || z ; }", tokenizeAndStringify("void f() { int x=34; int y=x||z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 > z ; }", tokenizeAndStringify("void f() { int x=34; int y=x>z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 >= z ; }", tokenizeAndStringify("void f() { int x=34; int y=x>=z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 < z ; }", tokenizeAndStringify("void f() { int x=34; int y=x<z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 <= z ; }", tokenizeAndStringify("void f() { int x=34; int y=x<=z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 == z ; }", tokenizeAndStringify("void f() { int x=34; int y=x==z; }", true));
|
||
ASSERT_EQUALS("void f ( ) { int y ; y = 34 != z ; }", tokenizeAndStringify("void f() { int x=34; int y=x!=z; }", true));
|
||
|
||
// #4007
|
||
ASSERT_EQUALS("void f ( ) { }", tokenizeAndStringify("void f() { char *p = 0; int result = p && (!*p); }", true));
|
||
ASSERT_EQUALS("void f ( ) { }", tokenizeAndStringify("void f() { Foo *p = 0; bool b = (p && (p->type() == 1)); }", true));
|
||
}
|
||
|
||
void simplifyKnownVariables53() { // references
|
||
ASSERT_EQUALS("void f ( ) { int x ; x = abc ( ) ; }", tokenizeAndStringify("void f() { int x; int &ref=x; ref=abc(); }", true));
|
||
ASSERT_EQUALS("void f ( ) { int * p ; p = abc ( ) ; }", tokenizeAndStringify("void f() { int *p; int *&ref=p; ref=abc(); }", true));
|
||
}
|
||
|
||
void simplifyKnownVariables54() { // #4913
|
||
ASSERT_EQUALS("void f ( int * p ) { * -- p = 0 ; * p = 0 ; }", tokenizeAndStringify("void f(int*p) { *--p=0; *p=0; }", true));
|
||
}
|
||
|
||
void simplifyKnownVariables55() { // pointer alias
|
||
ASSERT_EQUALS("void f ( ) { int a ; if ( a > 0 ) { } }", tokenizeAndStringify("void f() { int a; int *p=&a; if (*p>0) {} }", true));
|
||
ASSERT_EQUALS("void f ( ) { int a ; struct AB ab ; ab . a = & a ; if ( a > 0 ) { } }", tokenizeAndStringify("void f() { int a; struct AB ab; ab.a = &a; if (*ab.a>0) {} }", true));
|
||
ASSERT_EQUALS("void f ( ) { int a ; if ( x > a ) { } }", tokenizeAndStringify("void f() { int a; int *p=&a; if (x>*p) {} }", true));
|
||
}
|
||
|
||
void simplifyKnownVariables56() { // ticket #5301 - >>
|
||
ASSERT_EQUALS("void f ( ) { int a ; a = 0 ; int b ; b = 0 ; * p >> a >> b ; return a / b ; }",
|
||
tokenizeAndStringify("void f() { int a=0,b=0; *p>>a>>b; return a/b; }", true));
|
||
}
|
||
|
||
void simplifyKnownVariables57() { // #4724
|
||
ASSERT_EQUALS("unsigned long long x ; x = 9223372036854775808UL ;", tokenizeAndStringify("unsigned long long x = 1UL << 63 ;", true));
|
||
ASSERT_EQUALS("long long x ; x = -9223372036854775808L ;", tokenizeAndStringify("long long x = 1L << 63 ;", true));
|
||
}
|
||
|
||
void simplifyKnownVariables58() { // #5268
|
||
const char code[] = "enum e { VAL1 = 1, VAL2 }; "
|
||
"typedef char arr_t[VAL2]; "
|
||
"int foo(int) ; "
|
||
"void bar () { "
|
||
" throw foo (VAL1); "
|
||
"} "
|
||
"int baz() { "
|
||
" return sizeof(arr_t); "
|
||
"}";
|
||
ASSERT_EQUALS("enum e { VAL1 = 1 , VAL2 } ; "
|
||
"int foo ( int ) ; "
|
||
"void bar ( ) { "
|
||
"throw foo ( VAL1 ) ; "
|
||
"} "
|
||
"int baz ( ) { "
|
||
"return sizeof ( char [ VAL2 ] ) ; "
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables59() { // #5062 - for head
|
||
const char code[] = "void f() {\n"
|
||
" int a[3], i, j;\n"
|
||
" for(i = 0, j = 1; i < 3, j < 12; i++,j++) {\n"
|
||
" a[i] = 0;\n"
|
||
" }\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\n"
|
||
"int a [ 3 ] ; int i ; int j ;\n"
|
||
"for ( i = 0 , j = 1 ; i < 3 , j < 12 ; i ++ , j ++ ) {\n"
|
||
"a [ i ] = 0 ;\n"
|
||
"}\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables60() { // #6829
|
||
const char code[] = "void f() {\n"
|
||
" int i = 1;\n"
|
||
" const int * const constPtrToConst = &i;\n"
|
||
" std::cout << *constPtrToConst << std::endl;\n"
|
||
" std::cout << constPtrToConst << std::endl;\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\n"
|
||
"int i ; i = 1 ;\n"
|
||
"const int * const constPtrToConst ; constPtrToConst = & i ;\n"
|
||
"std :: cout << i << std :: endl ;\n"
|
||
"std :: cout << & i << std :: endl ;\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariables61() { // #7805
|
||
tokenizeAndStringify("static const int XX = 0;\n"
|
||
"enum E { XX };\n"
|
||
"struct s {\n"
|
||
" enum Bar {\n"
|
||
" XX,\n"
|
||
" Other\n"
|
||
" };\n"
|
||
" enum { XX };\n"
|
||
"};", /*simplify=*/true);
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
void simplifyKnownVariables62() { // #5666
|
||
ASSERT_EQUALS("void foo ( std :: string str ) {\n"
|
||
"char * p ; p = & str [ 0 ] ;\n"
|
||
"* p = 0 ;\n"
|
||
"}",
|
||
tokenizeAndStringify("void foo(std::string str) {\n"
|
||
" char *p = &str[0];\n"
|
||
" *p = 0;\n"
|
||
"}", /*simplify=*/true));
|
||
}
|
||
|
||
void simplifyKnownVariablesBailOutAssign1() {
|
||
const char code[] = "int foo() {\n"
|
||
" int i; i = 0;\n"
|
||
" if (x) { i = 10; }\n"
|
||
" return i;\n"
|
||
"}\n";
|
||
const char expected[] = "int foo ( ) {\n"
|
||
"int i ; i = 0 ;\n"
|
||
"if ( x ) { i = 10 ; }\n"
|
||
"return i ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariablesBailOutAssign2() {
|
||
// ticket #3032 - assignment in condition
|
||
const char code[] = "void f(struct ABC *list) {\n"
|
||
" struct ABC *last = NULL;\n"
|
||
" nr = (last = list->prev)->nr;\n" // <- don't replace "last" with 0
|
||
"}\n";
|
||
const char expected[] = "void f ( struct ABC * list ) {\n"
|
||
"struct ABC * last ; last = NULL ;\n"
|
||
"nr = ( last = list . prev ) . nr ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariablesBailOutAssign3() { // #4395 - nested assignments
|
||
const char code[] = "void f() {\n"
|
||
" int *p = 0;\n"
|
||
" a = p = (VdbeCursor*)pMem->z;\n"
|
||
" return p ;\n"
|
||
"}\n";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"int * p ; p = 0 ;\n"
|
||
"a = p = pMem . z ;\n"
|
||
"return p ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariablesBailOutFor1() {
|
||
const char code[] = "void foo() {\n"
|
||
" for (int i = 0; i < 10; ++i) { }\n"
|
||
"}\n";
|
||
const char expected[] = "void foo ( ) {\n"
|
||
"for ( int i = 0 ; i < 10 ; ++ i ) { }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
ASSERT_EQUALS("", errout.str()); // debug warnings
|
||
}
|
||
|
||
void simplifyKnownVariablesBailOutFor2() {
|
||
const char code[] = "void foo() {\n"
|
||
" int i = 0;\n"
|
||
" while (i < 10) { ++i; }\n"
|
||
"}\n";
|
||
const char expected[] = "void foo ( ) {\n"
|
||
"int i ; i = 0 ;\n"
|
||
"while ( i < 10 ) { ++ i ; }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
ASSERT_EQUALS("", errout.str()); // debug warnings
|
||
}
|
||
|
||
void simplifyKnownVariablesBailOutFor3() {
|
||
const char code[] = "void foo() {\n"
|
||
" for (std::string::size_type pos = 0; pos < 10; ++pos)\n"
|
||
" { }\n"
|
||
"}\n";
|
||
const char expected[] = "void foo ( ) {\n"
|
||
"for ( std :: string :: size_type pos = 0 ; pos < 10 ; ++ pos )\n"
|
||
"{ }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
ASSERT_EQUALS("", errout.str()); // debug warnings
|
||
}
|
||
|
||
void simplifyKnownVariablesBailOutMemberFunction() {
|
||
const char code[] = "void foo(obj a) {\n"
|
||
" obj b = a;\n"
|
||
" b.f();\n"
|
||
"}\n";
|
||
const char expected[] = "void foo ( obj a ) {\n"
|
||
"obj b ; b = a ;\n"
|
||
"b . f ( ) ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplifyKnownVariablesBailOutConditionalIncrement() {
|
||
const char code[] = "int f() {\n"
|
||
" int a = 0;\n"
|
||
" if (x) {\n"
|
||
" ++a;\n" // conditional increment
|
||
" }\n"
|
||
" return a;\n"
|
||
"}\n";
|
||
tokenizeAndStringify(code,true);
|
||
ASSERT_EQUALS("", errout.str()); // no debug warnings
|
||
}
|
||
|
||
void simplifyKnownVariablesBailOutSwitchBreak() {
|
||
// Ticket #2324
|
||
const char code[] = "int f(char *x) {\n"
|
||
" char *p;\n"
|
||
" char *q;\n"
|
||
"\n"
|
||
" switch (x & 0x3)\n"
|
||
" {\n"
|
||
" case 1:\n"
|
||
" p = x;\n"
|
||
" x = p;\n"
|
||
" break;\n"
|
||
" case 2:\n"
|
||
" q = x;\n" // x is not equal with p
|
||
" x = q;\n"
|
||
" break;\n"
|
||
" }\n"
|
||
"}\n";
|
||
|
||
const char expected[] = "int f ( char * x ) {\n"
|
||
"char * p ;\n"
|
||
"char * q ;\n"
|
||
"\n"
|
||
"switch ( x & 0x3 )\n"
|
||
"{\n"
|
||
"case 1 : ;\n"
|
||
"p = x ;\n"
|
||
"x = p ;\n"
|
||
"break ;\n"
|
||
"case 2 : ;\n"
|
||
"q = x ;\n"
|
||
"x = q ;\n"
|
||
"break ;\n"
|
||
"}\n"
|
||
"}";
|
||
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code,true));
|
||
}
|
||
|
||
void simplifyKnownVariablesFloat() {
|
||
// Ticket #2454
|
||
const char code[] = "void f() {\n"
|
||
" float a = 40;\n"
|
||
" x(10 / a);\n"
|
||
"}\n";
|
||
|
||
const char expected[] = "void f ( ) {\n\nx ( 0.25 ) ;\n}";
|
||
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code,true));
|
||
|
||
// Ticket #4227
|
||
const char code2[] = "double f() {"
|
||
" double a = false;"
|
||
" return a;"
|
||
"}";
|
||
ASSERT_EQUALS("double f ( ) { return 0.0 ; }", tokenizeAndStringify(code2,true));
|
||
|
||
// Ticket #5485
|
||
const char code3[] = "void f() {"
|
||
" double a = 1e+007;\n"
|
||
" std::cout << a;\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\nstd :: cout << 1e+007 ;\n}", tokenizeAndStringify(code3,true));
|
||
|
||
const char code4[] = "void f() {"
|
||
" double a = 1;\n"
|
||
" std::cout << a;\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\nstd :: cout << 1.0 ;\n}", tokenizeAndStringify(code4,true));
|
||
}
|
||
|
||
void simplifyKnownVariablesFunctionCalls() {
|
||
{
|
||
const char code[] = "void a(int x);" // <- x is passed by value
|
||
"void b() {"
|
||
" int x = 123;"
|
||
" a(x);" // <- replace with a(123);
|
||
"}";
|
||
const char expected[] = "void a ( int x ) ; void b ( ) { a ( 123 ) ; }";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code,true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void a(int &x);" // <- x is passed by reference
|
||
"void b() {"
|
||
" int x = 123;"
|
||
" a(x);" // <- don't replace with a(123);
|
||
"}";
|
||
const char expected[] = "void a ( int & x ) ; void b ( ) { int x ; x = 123 ; a ( x ) ; }";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code,true));
|
||
}
|
||
}
|
||
|
||
void simplifyKnownVariablesGlobalVars() {
|
||
// #8054
|
||
const char code[] = "static int x;"
|
||
"void f() {"
|
||
" x = 123;"
|
||
" while (!x) { dostuff(); }"
|
||
"}";
|
||
ASSERT_EQUALS("static int x ; void f ( ) { x = 123 ; while ( ! x ) { dostuff ( ) ; } }", tokenizeAndStringify(code,true));
|
||
}
|
||
|
||
void simplifyKnownVariablesReturn() {
|
||
const char code[] = "int a() {"
|
||
" int x = 123;"
|
||
" return (x);"
|
||
"}";
|
||
ASSERT_EQUALS("int a ( ) { return 123 ; }", tokenizeAndStringify(code,true));
|
||
}
|
||
|
||
void simplifyKnownVariablesPointerAliasFunctionCall() { // #7440
|
||
const char code[] = "int main() {\n"
|
||
" char* data = new char[100];\n"
|
||
" char** dataPtr = &data;\n"
|
||
" printf(\"test\");\n"
|
||
" delete [] *dataPtr;\n"
|
||
"}";
|
||
const char exp[] = "int main ( ) {\n"
|
||
"char * data ; data = new char [ 100 ] ;\n"
|
||
"char * * dataPtr ; dataPtr = & data ;\n"
|
||
"printf ( \"test\" ) ;\n"
|
||
"delete [ ] data ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code, /*simplify=*/true));
|
||
}
|
||
|
||
void simplifyKnownVariablesClassMember() {
|
||
// Ticket #2815
|
||
{
|
||
const char code[] = "char *a;\n"
|
||
"void f(const char *s) {\n"
|
||
" a = NULL;\n"
|
||
" x();\n"
|
||
" memcpy(a, s, 10);\n" // <- don't simplify "a" here
|
||
"}\n";
|
||
|
||
const std::string s(tokenizeAndStringify(code, true));
|
||
ASSERT_EQUALS(true, s.find("memcpy ( a , s , 10 ) ;") != std::string::npos);
|
||
}
|
||
|
||
// If the variable is local then perform simplification..
|
||
{
|
||
const char code[] = "void f(const char *s) {\n"
|
||
" char *a = NULL;\n"
|
||
" x();\n"
|
||
" memcpy(a, s, 10);\n" // <- simplify "a"
|
||
"}\n";
|
||
|
||
const std::string s(tokenizeAndStringify(code, true));
|
||
TODO_ASSERT_EQUALS(true, false, s.find("memcpy ( 0 , s , 10 ) ;") != std::string::npos);
|
||
}
|
||
}
|
||
|
||
void simplifyExternC() {
|
||
ASSERT_EQUALS("int foo ( ) ;", tokenizeAndStringify("extern \"C\" int foo();"));
|
||
ASSERT_EQUALS("int foo ( ) ;", tokenizeAndStringify("extern \"C\" { int foo(); }"));
|
||
}
|
||
|
||
void simplifyFunctionParameters() {
|
||
{
|
||
const char code[] = "char a [ ABC ( DEF ) ] ;";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "module ( a , a , sizeof ( a ) , 0444 ) ;";
|
||
ASSERT_EQUALS("module ( a , a , sizeof ( a ) , 0444 ) ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
ASSERT_EQUALS("void f ( int x ) { }", tokenizeAndStringify("void f(x) int x; { }"));
|
||
ASSERT_EQUALS("void f ( int x , char y ) { }", tokenizeAndStringify("void f(x,y) int x; char y; { }"));
|
||
ASSERT_EQUALS("int main ( int argc , char * argv [ ] ) { }", tokenizeAndStringify("int main(argc,argv) int argc; char *argv[]; { }"));
|
||
ASSERT_EQUALS("int f ( int p , int w , float d ) { }", tokenizeAndStringify("int f(p,w,d) float d; { }"));
|
||
|
||
// #1067 - Not simplified. Feel free to fix so it is simplified correctly but this syntax is obsolescent.
|
||
ASSERT_EQUALS("int ( * d ( a , b , c ) ) ( ) int a ; int b ; int c ; { }", tokenizeAndStringify("int (*d(a,b,c))()int a,b,c; { }"));
|
||
|
||
{
|
||
// This is not a function but the pattern is similar..
|
||
const char code[] = "void foo()"
|
||
"{"
|
||
" if (x)"
|
||
" int x;"
|
||
" { }"
|
||
"}";
|
||
ASSERT_EQUALS("void foo ( ) { if ( x ) { } { } }", tokenizeAndStringify(code, true));
|
||
}
|
||
}
|
||
|
||
void simplifyFunctionParameters1() { // ticket #3721
|
||
|
||
const char code[] = "typedef float ufloat;\n"
|
||
"typedef short ftnlen;\n"
|
||
"int f(p,w,d,e,len) ufloat *p; ftnlen len;\n"
|
||
"{\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("int f ( float * p , int w , int d , int e , short len )\n"
|
||
"{\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyFunctionParameters2() { // #4430
|
||
const char code[] = "class Item { "
|
||
"int i ; "
|
||
"public: "
|
||
"Item ( int i ) ; "
|
||
"} ; "
|
||
"Item :: Item ( int i ) : i ( i ) { }";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyFunctionParameters3() { // #4436
|
||
const char code[] = "class Item { "
|
||
"int i ; "
|
||
"int j ; "
|
||
"public: "
|
||
"Item ( int i , int j ) ; "
|
||
"} ; "
|
||
"Item :: Item ( int i , int j ) : i ( i ) , j ( j ) { }";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyFunctionParameters4() { // #9421
|
||
const char code[] = "int foo :: bar ( int , int ) const ;";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyFunctionParametersMultiTemplate() {
|
||
const char code[] = "template < typename T1 > template < typename T2 > "
|
||
"void A < T1 > :: foo ( T2 ) { }";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyFunctionParametersErrors() {
|
||
//same parameters...
|
||
ASSERT_THROW(tokenizeAndStringify("void foo(x, x)\n"
|
||
" int x;\n"
|
||
" int x;\n"
|
||
"{}\n"), InternalError);
|
||
|
||
ASSERT_THROW(tokenizeAndStringify("void foo(x, y)\n"
|
||
" int x;\n"
|
||
" int x;\n"
|
||
"{}\n"), InternalError);
|
||
|
||
tokenizeAndStringify("void foo(int, int)\n"
|
||
"{}\n");
|
||
ASSERT_EQUALS("", errout.str());
|
||
|
||
// #3848 - Don't hang
|
||
tokenizeAndStringify("sal_Bool ShapeHasText(sal_uLong, sal_uLong) const {\n"
|
||
" return sal_True;\n"
|
||
"}\n"
|
||
"void CreateSdrOLEFromStorage() {\n"
|
||
" comphelper::EmbeddedObjectContainer aCnt( xDestStorage );\n"
|
||
" { }\n"
|
||
"}");
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
// Simplify "((..))" into "(..)"
|
||
void removeParentheses1() {
|
||
const char code[] = "void foo()"
|
||
"{"
|
||
" free(((void*)p));"
|
||
"}";
|
||
|
||
ASSERT_EQUALS("void foo ( ) { free ( p ) ; }", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void removeParentheses3() {
|
||
{
|
||
const char code[] = "void foo()"
|
||
"{"
|
||
" if (( true )==(true)){}"
|
||
"}";
|
||
ASSERT_EQUALS("void foo ( ) { }", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void foo()"
|
||
"{"
|
||
" if (( 2 )==(2)){}"
|
||
"}";
|
||
ASSERT_EQUALS("void foo ( ) { }", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
{
|
||
const char code[] = "void foo()"
|
||
"{"
|
||
" if( g(10)){}"
|
||
"}";
|
||
ASSERT_EQUALS("void foo ( ) { if ( g ( 10 ) ) { } }", tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
// Simplify "( function (..))" into "function (..)"
|
||
void removeParentheses4() {
|
||
const char code[] = "void foo()"
|
||
"{"
|
||
" (free(p));"
|
||
"}";
|
||
ASSERT_EQUALS("void foo ( ) { free ( p ) ; }", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void removeParentheses5() {
|
||
// Simplify "( delete x )" into "delete x"
|
||
{
|
||
const char code[] = "void foo()"
|
||
"{"
|
||
" (delete p);"
|
||
"}";
|
||
ASSERT_EQUALS("void foo ( ) { delete p ; }", tokenizeAndStringify(code));
|
||
}
|
||
|
||
// Simplify "( delete [] x )" into "delete [] x"
|
||
{
|
||
const char code[] = "void foo()"
|
||
"{"
|
||
" (delete [] p);"
|
||
"}";
|
||
ASSERT_EQUALS("void foo ( ) { delete [ ] p ; }", tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
// "!(abc.a)" => "!abc.a"
|
||
void removeParentheses6() {
|
||
{
|
||
const char code[] = "(!(abc.a));";
|
||
ASSERT_EQUALS("( ! abc . a ) ;", tokenizeAndStringify(code));
|
||
}
|
||
//handle more complex member selections
|
||
{
|
||
const char code[] = "(!(a.b.c.d));";
|
||
ASSERT_EQUALS("( ! a . b . c . d ) ;", tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void removeParentheses7() {
|
||
const char code[] = ";char *p; (delete(p), (p)=0);";
|
||
ASSERT_EQUALS("; char * p ; delete p ; p = 0 ;", tokenizeAndStringify(code,true));
|
||
}
|
||
|
||
void removeParentheses8() {
|
||
const char code[] = "struct foo {\n"
|
||
" void operator delete(void *obj, size_t sz);\n"
|
||
"}\n";
|
||
const std::string actual(tokenizeAndStringify(code, false, true, Settings::Win32A));
|
||
|
||
const char expected[] = "struct foo {\n"
|
||
"void operatordelete ( void * obj , unsigned long sz ) ;\n"
|
||
"}";
|
||
|
||
ASSERT_EQUALS(expected, actual);
|
||
}
|
||
|
||
void removeParentheses9() {
|
||
ASSERT_EQUALS("void delete ( double num ) ;", tokenizeAndStringify("void delete(double num);", false));
|
||
}
|
||
|
||
void removeParentheses10() {
|
||
ASSERT_EQUALS("p = buf + 8 ;", tokenizeAndStringify("p = (buf + 8);", false));
|
||
}
|
||
|
||
void removeParentheses11() {
|
||
// #2502
|
||
ASSERT_EQUALS("{ } x ( ) ;", tokenizeAndStringify("{}(x());", false));
|
||
}
|
||
|
||
void removeParentheses12() {
|
||
// #2760
|
||
ASSERT_EQUALS(", x = 0 ;", tokenizeAndStringify(",(x)=0;", false));
|
||
}
|
||
|
||
void removeParentheses13() {
|
||
ASSERT_EQUALS("; f ( a + b , c ) ;", tokenizeAndStringify(";f((a+b),c);", false));
|
||
ASSERT_EQUALS("; x = y [ a + b ] ;", tokenizeAndStringify(";x=y[(a+b)];", false));
|
||
}
|
||
|
||
void removeParentheses14() {
|
||
ASSERT_EQUALS("{ if ( ( i & 1 ) == 0 ) { ; } }", tokenizeAndStringify("{ if ( (i & 1) == 0 ); }", false));
|
||
}
|
||
|
||
void removeParentheses15() {
|
||
ASSERT_EQUALS("a = b ? c : 123 ;", tokenizeAndStringify("a = b ? c : (123);", false));
|
||
ASSERT_EQUALS("a = b ? c : ( 123 + 456 ) ;", tokenizeAndStringify("a = b ? c : ((123)+(456));", false));
|
||
ASSERT_EQUALS("a = b ? 123 : c ;", tokenizeAndStringify("a = b ? (123) : c;", false));
|
||
|
||
// #4316
|
||
ASSERT_EQUALS("a = b ? c : ( d = 1 , 0 ) ;", tokenizeAndStringify("a = b ? c : (d=1,0);", false));
|
||
}
|
||
|
||
void removeParentheses16() { // *(x.y)=
|
||
// #4423
|
||
ASSERT_EQUALS("; * x = 0 ;", tokenizeAndStringify(";*(x)=0;", false));
|
||
ASSERT_EQUALS("; * x . y = 0 ;", tokenizeAndStringify(";*(x.y)=0;", false));
|
||
}
|
||
|
||
void removeParentheses17() { // a ? b : (c > 0 ? d : e)
|
||
ASSERT_EQUALS("a ? b : ( c > 0 ? d : e ) ;", tokenizeAndStringify("a?b:(c>0?d:e);", false));
|
||
}
|
||
|
||
void removeParentheses18() {
|
||
ASSERT_EQUALS("float ( * a ) [ 2 ] ;", tokenizeAndStringify("float(*a)[2];", false));
|
||
}
|
||
|
||
void removeParentheses19() {
|
||
ASSERT_EQUALS("( ( ( typeof ( X ) ) * ) 0 ) ;", tokenizeAndStringify("(((typeof(X))*)0);", false));
|
||
}
|
||
|
||
void removeParentheses20() {
|
||
ASSERT_EQUALS("a < b < int > > ( 2 ) ;", tokenizeAndStringify("a<b<int>>(2);", false));
|
||
}
|
||
|
||
void removeParentheses21() {
|
||
ASSERT_EQUALS("a = ( int ) - b ;", tokenizeAndStringify("a = ((int)-b);", false));
|
||
}
|
||
|
||
void removeParentheses22() {
|
||
static char code[] = "struct S { "
|
||
"char *(a); "
|
||
"char &(b); "
|
||
"const static char *(c); "
|
||
"} ;";
|
||
static char exp[] = "struct S { "
|
||
"char * a ; "
|
||
"char & b ; "
|
||
"static const char * c ; "
|
||
"} ;";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void removeParentheses23() { // Ticket #6103
|
||
// Reported case
|
||
{
|
||
static char code[] = "; * * p f ( ) int = { new int ( * [ 2 ] ) ; void }";
|
||
static char exp[] = "; * * p f ( ) int = { new int ( * [ 2 ] ) ; void }";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code));
|
||
}
|
||
// Various valid cases
|
||
{
|
||
static char code[] = "int * f [ 1 ] = { new ( int ) } ;";
|
||
static char exp[] = "int * f [ 1 ] = { new int } ;";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
static char code[] = "int * * f [ 1 ] = { new ( int ) [ 1 ] } ;";
|
||
static char exp[] = "int * * f [ 1 ] = { new int [ 1 ] } ;";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
static char code[] = "list < int > * f [ 1 ] = { new ( list < int > ) } ;";
|
||
static char exp[] = "list < int > * f [ 1 ] = { new list < int > } ;";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code));
|
||
}
|
||
// don't remove parentheses in operator new overload
|
||
{
|
||
static char code[] = "void *operator new(__SIZE_TYPE__, int);";
|
||
static char exp[] = "void * operatornew ( __SIZE_TYPE__ , int ) ;";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void removeParentheses24() { // Ticket #7040
|
||
static char code[] = "std::hash<decltype(t._data)>()(t._data);";
|
||
static char exp[] = "std :: hash < decltype ( t . _data ) > ( ) ( t . _data ) ;";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void removeParentheses25() { // daca@home - a=(b,c)
|
||
static char code[] = "a=(b,c);";
|
||
static char exp[] = "a = ( b , c ) ;";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void tokenize_double() {
|
||
const char code[] = "void f() {\n"
|
||
" double a = 4.2;\n"
|
||
" float b = 4.2f;\n"
|
||
" double c = 4.2e+10;\n"
|
||
" double d = 4.2e-10;\n"
|
||
" int e = 4+2;\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\n"
|
||
"double a ; a = 4.2 ;\n"
|
||
"float b ; b = 4.2f ;\n"
|
||
"double c ; c = 4.2e+10 ;\n"
|
||
"double d ; d = 4.2e-10 ;\n"
|
||
"int e ; e = 4 + 2 ;\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void tokenize_strings() {
|
||
const char code[] = "void f() {\n"
|
||
"const char *a =\n"
|
||
"{\n"
|
||
"\"hello \"\n"
|
||
"\"more \"\n"
|
||
"\"world\"\n"
|
||
"};\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\n"
|
||
"const char * a ; a =\n"
|
||
"{\n"
|
||
"\"hello more world\"\n"
|
||
"\n"
|
||
"\n"
|
||
"} ;\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplify_constants() {
|
||
const char code[] =
|
||
"void f() {\n"
|
||
"const int a = 45;\n"
|
||
"if( a )\n"
|
||
"{ int b = a; }\n"
|
||
"}\n"
|
||
"void g() {\n"
|
||
"int a = 2;\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\n"
|
||
"\n"
|
||
"\n"
|
||
"\n"
|
||
"}\n"
|
||
"void g ( ) {\n"
|
||
"\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplify_constants2() {
|
||
const char code[] =
|
||
"void f( Foo &foo, Foo *foo2 ) {\n"
|
||
"const int a = 45;\n"
|
||
"foo.a=a+a;\n"
|
||
"foo2->a=a;\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( Foo & foo , Foo * foo2 ) {\n"
|
||
"\n"
|
||
"foo . a = 90 ;\n"
|
||
"foo2 . a = 45 ;\n"
|
||
"}", tokenizeAndStringify(code, true));
|
||
}
|
||
|
||
void simplify_constants3() {
|
||
const char code[] =
|
||
"static const char str[] = \"abcd\";\n"
|
||
"static const unsigned int SZ = sizeof(str);\n"
|
||
"void f() {\n"
|
||
"a = SZ;\n"
|
||
"}\n";
|
||
const char expected[] =
|
||
"static const char str [ 5 ] = \"abcd\" ;\n\nvoid f ( ) {\na = 5 ;\n}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code,true));
|
||
}
|
||
|
||
void simplify_constants4() {
|
||
const char code[] = "static const int bSize = 4;\n"
|
||
"static const int aSize = 50;\n"
|
||
"x = bSize;\n"
|
||
"y = aSize;\n";
|
||
ASSERT_EQUALS("x = 4 ;\ny = 50 ;", tokenizeAndStringify(code,true));
|
||
}
|
||
|
||
void simplify_constants5() {
|
||
const char code[] = "int buffer[10];\n"
|
||
"static const int NELEMS = sizeof(buffer)/sizeof(int);\n"
|
||
"static const int NELEMS2(sizeof(buffer)/sizeof(int));\n"
|
||
"x = NELEMS;\n"
|
||
"y = NELEMS2;\n";
|
||
ASSERT_EQUALS("int buffer [ 10 ] ;\n\n\nx = 10 ;\ny = 10 ;", tokenizeAndStringify(code,true));
|
||
}
|
||
|
||
void simplify_constants6() { // Ticket #5625
|
||
{
|
||
const char code[] = "template < class T > struct foo ;\n"
|
||
"void bar ( ) {\n"
|
||
"foo < 1 ? 0 ? 1 : 6 : 2 > x ;\n"
|
||
"foo < 1 ? 0 : 2 > y ;\n"
|
||
"}";
|
||
const char exp [] = "template < class T > struct foo ;\n"
|
||
"void bar ( ) {\n"
|
||
"foo < 6 > x ;\n"
|
||
"foo < 0 > y ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code, true));
|
||
}
|
||
{
|
||
const char code[] = "bool b = true ? false : 1 > 2 ;";
|
||
const char exp [] = "bool b ; b = false ;";
|
||
ASSERT_EQUALS(exp, tokenizeAndStringify(code, true));
|
||
}
|
||
}
|
||
|
||
void simplifyMulAndParens() {
|
||
// (error) Resource leak
|
||
const char code[] = "void f() {"
|
||
" *&n1=open();"
|
||
" *&(n2)=open();"
|
||
" *(&n3)=open();"
|
||
" *&*&n4=open();"
|
||
" *&*&*&(n5)=open();"
|
||
" *&*&(*&n6)=open();"
|
||
" *&*(&*&n7)=open();"
|
||
" *(&*&n8)=open();"
|
||
" *&(*&*&(*&n9))=open();"
|
||
" (n10) = open();"
|
||
" ((n11)) = open();"
|
||
" ((*&n12))=open();"
|
||
" *(&(*&n13))=open();"
|
||
" ((*&(*&n14)))=open();"
|
||
" ((*&(*&n15)))+=10;"
|
||
"}";
|
||
const char expected[] = "void f ( ) {"
|
||
" n1 = open ( ) ;"
|
||
" n2 = open ( ) ;"
|
||
" n3 = open ( ) ;"
|
||
" n4 = open ( ) ;"
|
||
" n5 = open ( ) ;"
|
||
" n6 = open ( ) ;"
|
||
" n7 = open ( ) ;"
|
||
" n8 = open ( ) ;"
|
||
" n9 = open ( ) ;"
|
||
" n10 = open ( ) ;"
|
||
" n11 = open ( ) ;"
|
||
" n12 = open ( ) ;"
|
||
" n13 = open ( ) ;"
|
||
" n14 = open ( ) ;"
|
||
" n15 += 10 ; "
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyStructDecl() {
|
||
const char code[] = "const struct A { int a; int b; } a;";
|
||
ASSERT_EQUALS("struct A { int a ; int b ; } ; const struct A a ;", tokenizeAndStringify(code));
|
||
|
||
// #9519
|
||
const char code2[] = "enum A {} (a);";
|
||
const char expected2[] = "enum A { } ; enum A a ;";
|
||
ASSERT_EQUALS(expected2, tokenizeAndStringify(code2));
|
||
}
|
||
|
||
void vardecl1() {
|
||
const char code[] = "unsigned int a, b;";
|
||
|
||
const std::string actual(tokenizeAndStringify(code));
|
||
|
||
ASSERT_EQUALS("unsigned int a ; unsigned int b ;", actual);
|
||
}
|
||
|
||
void vardecl2() {
|
||
const char code[] = "void foo(a,b) unsigned int a, b; { }";
|
||
|
||
const std::string actual(tokenizeAndStringify(code));
|
||
|
||
ASSERT_EQUALS("void foo ( unsigned int a , unsigned int b ) { }", actual);
|
||
}
|
||
|
||
void vardecl3() {
|
||
const char code[] = "void f() { char * p = foo<10,char>(); }";
|
||
const std::string actual(tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("void f ( ) { char * p ; p = foo < 10 , char > ( ) ; }", actual);
|
||
}
|
||
|
||
void vardecl4() {
|
||
// ticket #346
|
||
|
||
const char code1[] = "void *p = NULL;";
|
||
const char res1[] = "void * p ; p = NULL ;";
|
||
ASSERT_EQUALS(res1, tokenizeAndStringify(code1));
|
||
|
||
const char code2[] = "const void *p = NULL;";
|
||
const char res2[] = "const void * p ; p = NULL ;";
|
||
ASSERT_EQUALS(res2, tokenizeAndStringify(code2));
|
||
|
||
const char code3[] = "void * const p = NULL;";
|
||
const char res3[] = "void * const p ; p = NULL ;";
|
||
ASSERT_EQUALS(res3, tokenizeAndStringify(code3));
|
||
|
||
const char code4[] = "const void * const p = NULL;";
|
||
const char res4[] = "const void * const p ; p = NULL ;";
|
||
ASSERT_EQUALS(res4, tokenizeAndStringify(code4));
|
||
|
||
const char code5[] = "const void * volatile p = NULL;";
|
||
const char res5[] = "const void * volatile p ; p = NULL ;";
|
||
ASSERT_EQUALS(res5, tokenizeAndStringify(code5));
|
||
}
|
||
|
||
void vardecl5() {
|
||
ASSERT_EQUALS("void foo ( int nX ) {\n"
|
||
"int addI ; addI = frontPoint == 2 || frontPoint == 1 ? ( i = 0 , 1 ) : ( i = nX - 2 , -1 ) ;\n"
|
||
"}", tokenizeAndStringify("void foo(int nX) {\n"
|
||
" int addI = frontPoint == 2 || frontPoint == 1 ? i = 0, 1 : (i = nX - 2, -1);\n"
|
||
"}"));
|
||
}
|
||
|
||
void vardecl_stl_1() {
|
||
// ticket #520
|
||
|
||
const char code1[] = "std::vector<std::string>a, b;";
|
||
const char res1[] = "std :: vector < std :: string > a ; std :: vector < std :: string > b ;";
|
||
ASSERT_EQUALS(res1, tokenizeAndStringify(code1));
|
||
|
||
const char code2[] = "std::vector<std::string>::const_iterator it, cit;";
|
||
const char res2[] = "std :: vector < std :: string > :: const_iterator it ; std :: vector < std :: string > :: const_iterator cit ;";
|
||
ASSERT_EQUALS(res2, tokenizeAndStringify(code2));
|
||
|
||
const char code3[] = "std::vector<std::pair<std::string, std::string > > *c, d;";
|
||
const char res3[] = "std :: vector < std :: pair < std :: string , std :: string > > * c ; std :: vector < std :: pair < std :: string , std :: string > > d ;";
|
||
ASSERT_EQUALS(res3, tokenizeAndStringify(code3));
|
||
}
|
||
|
||
void vardecl_stl_2() {
|
||
const char code1[] = "{ std::string x = \"abc\"; }";
|
||
ASSERT_EQUALS("{ std :: string x ; x = \"abc\" ; }", tokenizeAndStringify(code1));
|
||
|
||
const char code2[] = "{ std::vector<int> x = y; }";
|
||
ASSERT_EQUALS("{ std :: vector < int > x ; x = y ; }", tokenizeAndStringify(code2));
|
||
}
|
||
|
||
void vardecl_template_1() {
|
||
// ticket #1046
|
||
const char code1[] = "b<(1<<24),10,24> u, v;";
|
||
const char res1[] = "b < 16777216 , 10 , 24 > u ; b < 16777216 , 10 , 24 > v ;";
|
||
ASSERT_EQUALS(res1, tokenizeAndStringify(code1));
|
||
// ticket #3571 (segmentation fault)
|
||
tokenizeAndStringify("template <int i = (3>4) > class X4 {};");
|
||
}
|
||
|
||
void vardecl_template_2() {
|
||
// ticket #3650
|
||
const char code[] = "const string str = x<8,int>();";
|
||
const char expected[] = "const string str = x < 8 , int > ( ) ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl_union() {
|
||
// ticket #1976
|
||
const char code1[] = "class Fred { public: union { int a ; int b ; } ; } ;";
|
||
ASSERT_EQUALS(code1, tokenizeAndStringify(code1));
|
||
|
||
// ticket #2039
|
||
const char code2[] = "void f() {\n"
|
||
" union {\n"
|
||
" int x;\n"
|
||
" long y;\n"
|
||
" };\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\n\nint x ;\nlong & y = x ;\n\n}", tokenizeAndStringify(code2));
|
||
|
||
// ticket #3927
|
||
const char code3[] = "union xy *p = NULL;";
|
||
ASSERT_EQUALS("union xy * p ; p = NULL ;", tokenizeAndStringify(code3));
|
||
}
|
||
|
||
void vardecl_par() {
|
||
// ticket #2743 - set links if variable type contains parentheses
|
||
const char code[] = "Fred<int(*)()> fred1=a, fred2=b;";
|
||
ASSERT_EQUALS("Fred < int ( * ) ( ) > fred1 ; fred1 = a ; Fred < int ( * ) ( ) > fred2 ; fred2 = b ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl_par2() {
|
||
// ticket #3912 - set correct links
|
||
const char code[] = "function<void (shared_ptr<MyClass>)> v;";
|
||
ASSERT_EQUALS("function < void ( shared_ptr < MyClass > ) > v ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl_par3() {
|
||
// ticket #6556- Fred x1(a), x2(b);
|
||
const char code[] = "Fred x1(a), x2(b);";
|
||
ASSERT_EQUALS("Fred x1 ( a ) ; Fred x2 ( b ) ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl_class_ref() {
|
||
const char code[] = "class A { B &b1,&b2; };";
|
||
ASSERT_EQUALS("class A { B & b1 ; B & b2 ; } ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardec_static() {
|
||
{
|
||
// don't simplify declarations of static variables
|
||
// "static int i = 0;" is not the same as "static int i; i = 0;"
|
||
const char code[] = "static int i = 0 ;";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "static int a, b;";
|
||
ASSERT_EQUALS("static int a ; static int b ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "static unsigned int a, b;";
|
||
ASSERT_EQUALS("static unsigned int a ; static unsigned int b ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "static int a=1, b=1;";
|
||
ASSERT_EQUALS("static int a = 1 ; static int b = 1 ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "static int *a, *b;";
|
||
ASSERT_EQUALS("static int * a ; static int * b ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "static unsigned int *a=0, *b=0;";
|
||
ASSERT_EQUALS("static unsigned int * a = 0 ; static unsigned int * b = 0 ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
// Ticket #4450
|
||
const char code[] = "static int large_eeprom_type = (13 | (5)), "
|
||
"default_flash_type = 42;";
|
||
ASSERT_EQUALS("static int large_eeprom_type = 13 | 5 ; static int default_flash_type = 42 ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
// Ticket #5121
|
||
const char code[] = "unsigned int x;"
|
||
"static const unsigned int A = 1, B = A, C = 0, D = (A), E = 0;"
|
||
"void f() {"
|
||
" unsigned int *foo = &x;"
|
||
"}";
|
||
ASSERT_EQUALS("unsigned int x ; "
|
||
"static const unsigned int A = 1 ; "
|
||
"static const unsigned int B = A ; "
|
||
"static const unsigned int C = 0 ; "
|
||
"static const unsigned int D = A ; "
|
||
"static const unsigned int E = 0 ; "
|
||
"void f ( ) { "
|
||
"unsigned int * foo ; "
|
||
"foo = & x ; "
|
||
"}",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
// Ticket #5266
|
||
const char code[] = "class Machine {\n"
|
||
" static int const STACK_ORDER = 10, STACK_MAX = 1 << STACK_ORDER,"
|
||
" STACK_GUARD = 2;\n"
|
||
"};";
|
||
ASSERT_EQUALS("class Machine {\n"
|
||
"static const int STACK_ORDER = 10 ; static const int STACK_MAX = 1 << STACK_ORDER ; "
|
||
"static const int STACK_GUARD = 2 ;\n"
|
||
"} ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void vardecl6() {
|
||
// ticket #565
|
||
|
||
const char code1[] = "int z = x >> 16;";
|
||
const char res1[] = "int z ; z = x >> 16 ;";
|
||
ASSERT_EQUALS(res1, tokenizeAndStringify(code1));
|
||
}
|
||
|
||
void vardecl7() {
|
||
// ticket #603
|
||
const char code[] = "void f() {\n"
|
||
" for (int c = 0; c < 0; ++c) {}\n"
|
||
" int t;\n"
|
||
" D(3 > t, \"T\");\n"
|
||
"}";
|
||
const char res[] = "void f ( ) {\n"
|
||
"for ( int c = 0 ; c < 0 ; ++ c ) { }\n"
|
||
"int t ;\n"
|
||
"D ( 3 > t , \"T\" ) ;\n"
|
||
"}";
|
||
|
||
ASSERT_EQUALS(res, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl8() {
|
||
// ticket #696
|
||
const char code[] = "char a[10]={'\\0'}, b[10]={'\\0'};";
|
||
const char res[] = "char a [ 10 ] = { '\\0' } ; char b [ 10 ] = { '\\0' } ;";
|
||
ASSERT_EQUALS(res, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl9() {
|
||
const char code[] = "char a[2] = {'A', '\\0'}, b[2] = {'B', '\\0'};";
|
||
const char res[] = "char a [ 2 ] = { 'A' , '\\0' } ; char b [ 2 ] = { 'B' , '\\0' } ;";
|
||
ASSERT_EQUALS(res, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl10() {
|
||
// ticket #732
|
||
const char code[] = "char a [ 2 ] = { '-' } ; memset ( a , '-' , sizeof ( a ) ) ;";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl11() {
|
||
// ticket #1684
|
||
const char code[] = "char a[5][8], b[5][8];";
|
||
ASSERT_EQUALS("char a [ 5 ] [ 8 ] ; char b [ 5 ] [ 8 ] ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl12() {
|
||
const char code[] = "struct A { public: B a, b, c, d; };";
|
||
ASSERT_EQUALS("struct A { public: B a ; B b ; B c ; B d ; } ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl13() {
|
||
const char code[] = "void f() {\n"
|
||
" int a = (x < y) ? 1 : 0;\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\nint a ; a = ( x < y ) ? 1 : 0 ;\n}", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl14() {
|
||
const char code[] = "::std::tr1::shared_ptr<int> pNum1, pNum2;\n";
|
||
ASSERT_EQUALS(":: std :: tr1 :: shared_ptr < int > pNum1 ; :: std :: tr1 :: shared_ptr < int > pNum2 ;", tokenizeAndStringify(code, false, false, Settings::Native, "test.cpp", false));
|
||
}
|
||
|
||
void vardecl15() {
|
||
const char code[] = "const char x[] = \"foo\", y[] = \"bar\";\n";
|
||
ASSERT_EQUALS("const char x [ 4 ] = \"foo\" ; const char y [ 4 ] = \"bar\" ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl16() {
|
||
{
|
||
const char code[] = "const a::b<c,d(e),f>::g::h<i>::l *x [] = foo(),y [][] = bar();\n";
|
||
ASSERT_EQUALS("const a :: b < c , d ( e ) , f > :: g :: h < i > :: l * x [ ] = foo ( ) ; "
|
||
"const a :: b < c , d ( e ) , f > :: g :: h < i > :: l y [ ] [ ] = bar ( ) ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "const ::b<c,d(e),f>::g::h<i>::l *x [] = foo(),y [][] = bar();\n";
|
||
ASSERT_EQUALS("const :: b < c , d ( e ) , f > :: g :: h < i > :: l * x [ ] = foo ( ) ; "
|
||
"const :: b < c , d ( e ) , f > :: g :: h < i > :: l y [ ] [ ] = bar ( ) ;", tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void vardecl17() {
|
||
const char code[] = "a < b > :: c :: d :: e < f > x = foo(), y = bar();\n";
|
||
ASSERT_EQUALS("a < b > :: c :: d :: e < f > x ; x = foo ( ) ; "
|
||
"a < b > :: c :: d :: e < f > y ; y = bar ( ) ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl18() {
|
||
const char code[] = "void f() {\n"
|
||
" g((double)v1*v2, v3, v4);\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS("void f ( ) {\n"
|
||
"g ( ( double ) v1 * v2 , v3 , v4 ) ;\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl19() {
|
||
{
|
||
const char code[] = "void func(in, r, m)\n"
|
||
"int in;"
|
||
"int r,m;"
|
||
"{\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS("void func (\n"
|
||
"int in ,\n"
|
||
"int r ,\n"
|
||
"int m )\n"
|
||
"{\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "void f(r,f)\n"
|
||
"char *r;\n"
|
||
"{\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS("void f (\n"
|
||
"char * r )\n"
|
||
"\n"
|
||
"{\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "void f(f)\n"
|
||
"{\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS("void f ( )\n"
|
||
"{\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "void f(f,r)\n"
|
||
"char *r;\n"
|
||
"{\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS("void f (\n"
|
||
"char * r )\n"
|
||
"\n"
|
||
"{\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "void f(r,f,s)\n"
|
||
"char *r;\n"
|
||
"char *s;\n"
|
||
"{\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS("void f (\n"
|
||
"char * r ,\n"
|
||
"\n"
|
||
"char * s )\n"
|
||
"\n"
|
||
"\n"
|
||
"{\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "void f(r,s,t)\n"
|
||
"char *r,*s,*t;\n"
|
||
"{\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS("void f (\n"
|
||
"char * r ,\n"
|
||
"char * s ,\n"
|
||
"char * t )\n"
|
||
"\n"
|
||
"{\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "void f(a, b) register char *a, *b;\n"
|
||
"{\n"
|
||
"}\n";
|
||
|
||
ASSERT_EQUALS("void f ( char * a , char * b )\n"
|
||
"{\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void vardecl20() {
|
||
// #3700
|
||
const char code[] = "void a::b() const\n"
|
||
"{\n"
|
||
" register const int X = 0;\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void a :: b ( ) const\n"
|
||
"{\n"
|
||
"const int X = 0 ;\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl21() { // type in namespace
|
||
// #4042 - a::b const *p = 0;
|
||
const char code1[] = "void f() {\n"
|
||
" a::b const *p = 0;\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void f ( ) {\n"
|
||
"const a :: b * p ; p = 0 ;\n"
|
||
"}"
|
||
, tokenizeAndStringify(code1));
|
||
|
||
// #4226 - ::a::b const *p = 0;
|
||
const char code2[] = "void f() {\n"
|
||
" ::a::b const *p = 0;\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void f ( ) {\n"
|
||
"const :: a :: b * p ; p = 0 ;\n"
|
||
"}"
|
||
, tokenizeAndStringify(code2));
|
||
}
|
||
|
||
void vardecl22() { // #4211 - segmentation fault
|
||
tokenizeAndStringify("A<B<C<int>> >* p = 0;");
|
||
}
|
||
|
||
void vardecl23() { // #4276 - segmentation fault
|
||
ASSERT_THROW(tokenizeAndStringify("class a { protected : template < class int x = 1 ; public : int f ( ) ; }"), InternalError);
|
||
}
|
||
|
||
void vardecl24() { // #4187 - variable declaration within lambda function
|
||
const char code1[] = "void f() {\n"
|
||
" std::for_each(ints.begin(), ints.end(), [](int val)\n"
|
||
" {\n"
|
||
" int temp = 0;\n"
|
||
" });\n"
|
||
"}";
|
||
|
||
const char expected1[] = "void f ( ) {\n"
|
||
"std :: for_each ( ints . begin ( ) , ints . end ( ) , [ ] ( int val )\n"
|
||
"{\n"
|
||
"int temp ; temp = 0 ;\n"
|
||
"} ) ;\n"
|
||
"}";
|
||
|
||
ASSERT_EQUALS(expected1, tokenizeAndStringify(code1));
|
||
|
||
const char code2[] = "void f(int j) {\n"
|
||
" g( [](){int temp = 0;} , j );\n"
|
||
"}";
|
||
|
||
const char expected2[] = "void f ( int j ) {\n"
|
||
"g ( [ ] ( ) { int temp ; temp = 0 ; } , j ) ;\n"
|
||
"}";
|
||
|
||
ASSERT_EQUALS(expected2, tokenizeAndStringify(code2));
|
||
}
|
||
|
||
void vardecl25() { // #4799 - segmentation fault
|
||
tokenizeAndStringify("void A::func(P g) const {}\n"
|
||
"void A::a() {\n"
|
||
" b = new d( [this]( const P & p) -> double { return this->func(p);} );\n"
|
||
"}");
|
||
}
|
||
|
||
void vardecl26() { // #5907
|
||
const char code[] = "extern int *new, obj, player;";
|
||
const char expected[] = "extern int * new ; extern int obj ; extern int player ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void vardecl27() { // #7850
|
||
const char code[] = "extern int foo(char);\n"
|
||
"void* class(char c) {\n"
|
||
" if (foo(c))\n"
|
||
" return 0;\n"
|
||
" return 0;\n"
|
||
"}";
|
||
tokenizeAndStringify(code, /*simplify=*/false, /*expand=*/true, Settings::Native, "test.c");
|
||
}
|
||
|
||
void volatile_variables() {
|
||
const char code[] = "volatile int a=0;\n"
|
||
"volatile int b=0;\n"
|
||
"volatile int c=0;\n";
|
||
|
||
const std::string actual(tokenizeAndStringify(code));
|
||
|
||
ASSERT_EQUALS("volatile int a ; a = 0 ;\nvolatile int b ; b = 0 ;\nvolatile int c ; c = 0 ;", actual);
|
||
}
|
||
|
||
|
||
void simplifyKeyword() {
|
||
{
|
||
const char code[] = "void f (int a [ static 5] );";
|
||
ASSERT_EQUALS("void f ( int a [ 5 ] ) ;", tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char in4 [] = "struct B final : A { void foo(); };";
|
||
const char out4 [] = "struct B : A { void foo ( ) ; } ;";
|
||
ASSERT_EQUALS(out4, tokenizeAndStringify(in4));
|
||
|
||
const char in5 [] = "struct ArrayItemsValidator final {\n"
|
||
" SchemaError validate() const override {\n"
|
||
" for (; pos < value.size(); ++pos) {\n"
|
||
" }\n"
|
||
" return none;\n"
|
||
" }\n"
|
||
"};\n";
|
||
const char out5 [] =
|
||
"struct ArrayItemsValidator {\n"
|
||
"SchemaError validate ( ) const override {\n"
|
||
"for ( ; pos < value . size ( ) ; ++ pos ) {\n"
|
||
"}\n"
|
||
"return none ;\n"
|
||
"}\n"
|
||
"} ;";
|
||
|
||
ASSERT_EQUALS(out5, tokenizeAndStringify(in5));
|
||
}
|
||
{
|
||
// Ticket #8679
|
||
const char code[] = "thread_local void *thread_local_var; "
|
||
"__thread void *thread_local_var_2;";
|
||
ASSERT_EQUALS("static void * thread_local_var ; "
|
||
"void * thread_local_var_2 ;", tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* tokenize "signed i" => "signed int i"
|
||
*/
|
||
void signed1() {
|
||
{
|
||
const char code1[] = "void foo ( signed int , float ) ;";
|
||
ASSERT_EQUALS(code1, tokenizeAndStringify(code1));
|
||
}
|
||
|
||
{
|
||
const char code1[] = "signed i ;";
|
||
const char code2[] = "signed int i ;";
|
||
ASSERT_EQUALS(code2, tokenizeAndStringify(code1));
|
||
}
|
||
|
||
{
|
||
const char code1[] = "signed int i ;";
|
||
ASSERT_EQUALS(code1, tokenizeAndStringify(code1));
|
||
}
|
||
|
||
{
|
||
const char code1[] = "int signed i ;";
|
||
const char code2[] = "signed int i ;";
|
||
ASSERT_EQUALS(code2, tokenizeAndStringify(code1));
|
||
}
|
||
|
||
{
|
||
const char code1[] = "void f() { for (signed i=0; i<10; i++) {} }";
|
||
const char code2[] = "void f ( ) { for ( signed int i = 0 ; i < 10 ; i ++ ) { } }";
|
||
ASSERT_EQUALS(code2, tokenizeAndStringify(code1));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* tokenize "unsigned i" => "unsigned int i"
|
||
* tokenize "unsigned" => "unsigned int"
|
||
*/
|
||
void unsigned1() {
|
||
// No changes..
|
||
{
|
||
const char code[] = "void foo ( unsigned int , float ) ;";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
// insert "int" after "unsigned"..
|
||
{
|
||
const char code1[] = "unsigned i ;";
|
||
const char code2[] = "unsigned int i ;";
|
||
ASSERT_EQUALS(code2, tokenizeAndStringify(code1));
|
||
}
|
||
|
||
{
|
||
const char code1[] = "int unsigned i ;";
|
||
const char code2[] = "unsigned int i ;";
|
||
ASSERT_EQUALS(code2, tokenizeAndStringify(code1));
|
||
}
|
||
|
||
// insert "int" after "unsigned"..
|
||
{
|
||
const char code1[] = "void f() { for (unsigned i=0; i<10; i++) {} }";
|
||
const char code2[] = "void f ( ) { for ( unsigned int i = 0 ; i < 10 ; i ++ ) { } }";
|
||
ASSERT_EQUALS(code2, tokenizeAndStringify(code1));
|
||
}
|
||
|
||
// "extern unsigned x;" => "extern int x;"
|
||
{
|
||
const char code1[] = "; extern unsigned x;";
|
||
const char code2[] = "; extern unsigned int x ;";
|
||
ASSERT_EQUALS(code2, tokenizeAndStringify(code1));
|
||
}
|
||
}
|
||
|
||
void unsigned2() {
|
||
const char code[] = "i = (unsigned)j;";
|
||
const char expected[] = "i = ( unsigned int ) j ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
|
||
// simplify "unsigned" when using templates..
|
||
void unsigned3() {
|
||
{
|
||
const char code[] = "; foo<unsigned>();";
|
||
const char expected[] = "; foo<int> ( ) ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
|
||
{
|
||
const char code[] = "; foo<unsigned int>();";
|
||
const char expected[] = "; foo<int> ( ) ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void simplifyStdType() { // #4947, #4950, #4951
|
||
// usigned long long
|
||
{
|
||
const char code[] = "long long unsigned int x;";
|
||
const char expected[] = "unsigned long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "long long int unsigned x;";
|
||
const char expected[] = "unsigned long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "unsigned long long int x;";
|
||
const char expected[] = "unsigned long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "unsigned int long long x;";
|
||
const char expected[] = "unsigned long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "int unsigned long long x;";
|
||
const char expected[] = "unsigned long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "int long long unsigned x;";
|
||
const char expected[] = "unsigned long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
// signed long long
|
||
{
|
||
const char code[] = "long long signed int x;";
|
||
const char expected[] = "signed long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "long long int signed x;";
|
||
const char expected[] = "signed long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "signed long long int x;";
|
||
const char expected[] = "signed long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "signed int long long x;";
|
||
const char expected[] = "signed long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "int signed long long x;";
|
||
const char expected[] = "signed long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "int long long signed x;";
|
||
const char expected[] = "signed long long x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
// usigned short
|
||
{
|
||
const char code[] = "short unsigned int x;";
|
||
const char expected[] = "unsigned short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "short int unsigned x;";
|
||
const char expected[] = "unsigned short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "unsigned short int x;";
|
||
const char expected[] = "unsigned short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "unsigned int short x;";
|
||
const char expected[] = "unsigned short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "int unsigned short x;";
|
||
const char expected[] = "unsigned short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "int short unsigned x;";
|
||
const char expected[] = "unsigned short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
// signed short
|
||
{
|
||
const char code[] = "short signed int x;";
|
||
const char expected[] = "signed short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "short int signed x;";
|
||
const char expected[] = "signed short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "signed short int x;";
|
||
const char expected[] = "signed short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "signed int short x;";
|
||
const char expected[] = "signed short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "int signed short x;";
|
||
const char expected[] = "signed short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "int short signed x;";
|
||
const char expected[] = "signed short x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "unsigned static short const int i;";
|
||
const char expected[] = "static const unsigned short i ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "float complex x;";
|
||
const char expected[] = "_Complex float x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "complex float x;";
|
||
const char expected[] = "_Complex float x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "complex long double x;";
|
||
const char expected[] = "_Complex long double x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "long double complex x;";
|
||
const char expected[] = "_Complex long double x ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "double complex;";
|
||
const char expected[] = "double complex ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void createLinks() {
|
||
{
|
||
const char code[] = "class A{\n"
|
||
" void f() {}\n"
|
||
"};";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
// A body {}
|
||
ASSERT_EQUALS(true, tok->linkAt(2) == tok->tokAt(9));
|
||
ASSERT_EQUALS(true, tok->linkAt(9) == tok->tokAt(2));
|
||
|
||
// f body {}
|
||
ASSERT_EQUALS(true, tok->linkAt(7) == tok->tokAt(8));
|
||
ASSERT_EQUALS(true, tok->linkAt(8) == tok->tokAt(7));
|
||
|
||
// f ()
|
||
ASSERT_EQUALS(true, tok->linkAt(5) == tok->tokAt(6));
|
||
ASSERT_EQUALS(true, tok->linkAt(6) == tok->tokAt(5));
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "void f(){\n"
|
||
" char a[10];\n"
|
||
" char *b ; b = new char[a[0]];\n"
|
||
"};";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
// a[10]
|
||
ASSERT_EQUALS(true, tok->linkAt(7) == tok->tokAt(9));
|
||
ASSERT_EQUALS(true, tok->linkAt(9) == tok->tokAt(7));
|
||
|
||
// new char[]
|
||
ASSERT_EQUALS(true, tok->linkAt(19) == tok->tokAt(24));
|
||
ASSERT_EQUALS(true, tok->linkAt(24) == tok->tokAt(19));
|
||
|
||
// a[0]
|
||
ASSERT_EQUALS(true, tok->linkAt(21) == tok->tokAt(23));
|
||
ASSERT_EQUALS(true, tok->linkAt(23) == tok->tokAt(21));
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "void f(){\n"
|
||
" foo(g());\n"
|
||
"};";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
// foo(
|
||
ASSERT_EQUALS(true, tok->linkAt(6) == tok->tokAt(10));
|
||
ASSERT_EQUALS(true, tok->linkAt(10) == tok->tokAt(6));
|
||
|
||
// g(
|
||
ASSERT_EQUALS(true, tok->linkAt(8) == tok->tokAt(9));
|
||
ASSERT_EQUALS(true, tok->linkAt(9) == tok->tokAt(8));
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "bool foo(C<z> a, bar<int, x<float>>& f, int b) {\n"
|
||
" return(a<b && b>f);\n"
|
||
"}";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
// template<
|
||
ASSERT_EQUALS(true, tok->tokAt(6) == tok->linkAt(4));
|
||
ASSERT_EQUALS(true, tok->tokAt(4) == tok->linkAt(6));
|
||
|
||
// bar<
|
||
ASSERT_EQUALS(true, tok->tokAt(17) == tok->linkAt(10));
|
||
ASSERT_EQUALS(true, tok->tokAt(10) == tok->linkAt(17));
|
||
|
||
// x<
|
||
ASSERT_EQUALS(true, tok->tokAt(16) == tok->linkAt(14));
|
||
ASSERT_EQUALS(true, tok->tokAt(14) == tok->linkAt(16));
|
||
|
||
// a<b && b>f
|
||
ASSERT_EQUALS(true, nullptr == tok->linkAt(28));
|
||
ASSERT_EQUALS(true, nullptr == tok->linkAt(32));
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "void foo() {\n"
|
||
" return static_cast<bar>(a);\n"
|
||
"}";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
// static_cast<
|
||
ASSERT_EQUALS(true, tok->tokAt(9) == tok->linkAt(7));
|
||
ASSERT_EQUALS(true, tok->tokAt(7) == tok->linkAt(9));
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "void foo() {\n"
|
||
" nvwa<(x > y)> ERROR_nnn;\n"
|
||
"}";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
// nvwa<(x > y)>
|
||
ASSERT_EQUALS(true, tok->tokAt(12) == tok->linkAt(6));
|
||
ASSERT_EQUALS(true, tok->tokAt(6) == tok->linkAt(12));
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
// #4860
|
||
const char code[] = "class A : public B<int> {};";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
// B<..>
|
||
ASSERT_EQUALS(true, tok->tokAt(5) == tok->linkAt(7));
|
||
ASSERT_EQUALS(true, tok->linkAt(5) == tok->tokAt(7));
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
// #4860
|
||
const char code[] = "Bar<Typelist< int, Typelist< int, Typelist< int, FooNullType>>>>::set(1, 2, 3);";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
ASSERT_EQUALS(true, tok->tokAt(1) == tok->linkAt(18));
|
||
ASSERT_EQUALS(true, tok->tokAt(3) == tok->linkAt(17));
|
||
ASSERT_EQUALS(true, tok->tokAt(7) == tok->linkAt(16));
|
||
ASSERT_EQUALS(true, tok->tokAt(11) == tok->linkAt(15));
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
// #5627
|
||
const char code[] = "new Foo<Bar>[10];";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
ASSERT_EQUALS(true, tok->tokAt(2) == tok->linkAt(4));
|
||
ASSERT_EQUALS(true, tok->tokAt(4) == tok->linkAt(2));
|
||
ASSERT_EQUALS(true, tok->tokAt(5) == tok->linkAt(7));
|
||
ASSERT_EQUALS(true, tok->tokAt(7) == tok->linkAt(5));
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
{
|
||
// #6242
|
||
const char code[] = "func = integral_<uchar, int, double>;";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
ASSERT_EQUALS(true, tok->tokAt(3) == tok->linkAt(9));
|
||
ASSERT_EQUALS(true, tok->linkAt(3) == tok->tokAt(9));
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
// if (a < b || c > d) { }
|
||
const char code[] = "{ if (a < b || c > d); }";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
ASSERT_EQUALS(true, tok->linkAt(3) == nullptr);
|
||
}
|
||
|
||
{
|
||
// bool f = a < b || c > d
|
||
const char code[] = "bool f = a < b || c > d;";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
ASSERT_EQUALS(true, tok->linkAt(4) == nullptr);
|
||
}
|
||
|
||
{
|
||
// template
|
||
const char code[] = "a < b || c > d;";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(5));
|
||
}
|
||
|
||
{
|
||
// if (a < ... > d) { }
|
||
const char code[] = "{ if (a < b || c == 3 || d > e); }";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
ASSERT_EQUALS(true, tok->linkAt(3) == nullptr);
|
||
}
|
||
|
||
{
|
||
// template
|
||
const char code[] = "a<b==3 || c> d;";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(7));
|
||
}
|
||
|
||
{
|
||
// template
|
||
const char code[] = "a<b || c==4> d;";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(7));
|
||
}
|
||
|
||
{
|
||
const char code[] = "template < f = b || c > struct S;";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(7));
|
||
ASSERT_EQUALS(true, tok->tokAt(1) == tok->linkAt(7));
|
||
}
|
||
|
||
{
|
||
const char code[] = "struct A : B<c&&d> {};";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
ASSERT_EQUALS(true, tok->linkAt(4) == tok->tokAt(8));
|
||
ASSERT_EQUALS(true, tok->tokAt(4) == tok->linkAt(8));
|
||
}
|
||
|
||
{
|
||
const char code[] = "Data<T&&>;";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(4));
|
||
ASSERT_EQUALS(true, tok->tokAt(1) == tok->linkAt(4));
|
||
}
|
||
|
||
{
|
||
// #6601
|
||
const char code[] = "template<class R> struct FuncType<R(&)()> : FuncType<R()> { };";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = tokenizer.tokens();
|
||
|
||
ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(4)); // <class R>
|
||
ASSERT_EQUALS(true, tok->linkAt(7) == tok->tokAt(14)); // <R(&)()>
|
||
ASSERT_EQUALS(true, tok->linkAt(9) == tok->tokAt(11)); // (&)
|
||
ASSERT_EQUALS(true, tok->linkAt(12) == tok->tokAt(13)); // ()
|
||
ASSERT_EQUALS(true, tok->linkAt(17) == tok->tokAt(21)); // <R()>
|
||
ASSERT_EQUALS(true, tok->linkAt(19) == tok->tokAt(20)); // ()
|
||
ASSERT_EQUALS(true, tok->linkAt(22) == tok->tokAt(23)); // {}
|
||
}
|
||
}
|
||
|
||
void createLinks2() {
|
||
{
|
||
// #7158
|
||
const char code[] = "enum { value = boost::mpl::at_c<B, C> };";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok = Token::findsimplematch(tokenizer.tokens(), "<");
|
||
ASSERT_EQUALS(true, tok->link() == tok->tokAt(4));
|
||
ASSERT_EQUALS(true, tok->linkAt(4) == tok);
|
||
}
|
||
|
||
{
|
||
// #7865
|
||
const char code[] = "template <typename T, typename U>\n"
|
||
"struct CheckedDivOp< T, U, typename std::enable_if<std::is_floating_point<T>::value || std::is_floating_point<U>::value>::type> {\n"
|
||
"};\n";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok1 = Token::findsimplematch(tokenizer.tokens(), "struct")->tokAt(2);
|
||
const Token *tok2 = Token::findsimplematch(tokenizer.tokens(), "{")->previous();
|
||
ASSERT_EQUALS(true, tok1->link() == tok2);
|
||
ASSERT_EQUALS(true, tok2->link() == tok1);
|
||
}
|
||
|
||
{
|
||
// #7975
|
||
const char code[] = "template <class C> X<Y&&Z, C*> copy() {};\n";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok1 = Token::findsimplematch(tokenizer.tokens(), "< Y");
|
||
const Token *tok2 = Token::findsimplematch(tok1, "> copy");
|
||
ASSERT_EQUALS(true, tok1->link() == tok2);
|
||
ASSERT_EQUALS(true, tok2->link() == tok1);
|
||
}
|
||
|
||
{
|
||
// #8006
|
||
const char code[] = "C<int> && a = b;";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok1 = tokenizer.tokens()->next();
|
||
const Token *tok2 = tok1->tokAt(2);
|
||
ASSERT_EQUALS(true, tok1->link() == tok2);
|
||
ASSERT_EQUALS(true, tok2->link() == tok1);
|
||
}
|
||
|
||
{
|
||
// #8115
|
||
const char code[] = "void Test(C<int> && c);";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *tok1 = Token::findsimplematch(tokenizer.tokens(), "<");
|
||
const Token *tok2 = tok1->tokAt(2);
|
||
ASSERT_EQUALS(true, tok1->link() == tok2);
|
||
ASSERT_EQUALS(true, tok2->link() == tok1);
|
||
}
|
||
{
|
||
// #8654
|
||
const char code[] = "template<int N> struct A {}; "
|
||
"template<int... Ns> struct foo : A<Ns>... {};";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *A = Token::findsimplematch(tokenizer.tokens(), "A <");
|
||
ASSERT_EQUALS(true, A->next()->link() == A->tokAt(3));
|
||
}
|
||
{
|
||
// #8851
|
||
const char code[] = "template<typename std::enable_if<!(std::value1) && std::value2>::type>"
|
||
"void basic_json() {}";
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
ASSERT_EQUALS(true, Token::simpleMatch(tokenizer.tokens()->next()->link(), "> void"));
|
||
}
|
||
|
||
{
|
||
// #9094 - template usage or comparison?
|
||
const char code[] = "a = f(x%x<--a==x>x);";
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
ASSERT(nullptr == Token::findsimplematch(tokenizer.tokens(), "<")->link());
|
||
}
|
||
|
||
{
|
||
// #9131 - template usage or comparison?
|
||
const char code[] = "using std::list; list<t *> l;";
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "<")->link());
|
||
}
|
||
|
||
{
|
||
const char code[] = "using std::set;\n"
|
||
"void foo()\n"
|
||
"{\n"
|
||
" for (set<ParticleSource*>::iterator i = sources.begin(); i != sources.end(); ++i) {}\n"
|
||
"}";
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "<")->link());
|
||
}
|
||
|
||
{
|
||
// #8890
|
||
const char code[] = "void f() {\n"
|
||
" a<> b;\n"
|
||
" b.a<>::c();\n"
|
||
"}\n";
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> ::")->link());
|
||
}
|
||
|
||
{
|
||
// #9136
|
||
const char code[] = "template <char> char * a;\n"
|
||
"template <char... b> struct c {\n"
|
||
" void d() { a<b...>[0]; }\n"
|
||
"};\n";
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> [")->link());
|
||
}
|
||
|
||
{
|
||
// #9057
|
||
const char code[] = "template <bool> struct a;\n"
|
||
"template <bool b, typename> using c = typename a<b>::d;\n"
|
||
"template <typename e> using f = c<e() && sizeof(int), int>;\n"
|
||
"template <typename e, typename = f<e>> struct g {};\n"
|
||
"template <typename e> using baz = g<e>;\n";
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> ;")->link());
|
||
}
|
||
|
||
{
|
||
// #9141
|
||
const char code[] = "struct a {\n"
|
||
" typedef int b;\n"
|
||
" operator b();\n"
|
||
"};\n"
|
||
"template <int> using c = a;\n"
|
||
"template <int d> c<d> e;\n"
|
||
"auto f = -e<1> == 0;\n";
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> ==")->link());
|
||
}
|
||
|
||
{
|
||
// #9145
|
||
const char code[] = "template <typename a, a> struct b {\n"
|
||
" template <typename c> constexpr void operator()(c &&) const;\n"
|
||
"};\n"
|
||
"template <int d> struct e { b<int, d> f; };\n"
|
||
"template <int g> using h = e<g>;\n"
|
||
"template <int g> h<g> i;\n"
|
||
"template <typename a, a d>\n"
|
||
"template <typename c>\n"
|
||
"constexpr void b<a, d>::operator()(c &&) const {\n"
|
||
" i<3>.f([] {});\n"
|
||
"}\n";
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> . f (")->link());
|
||
}
|
||
}
|
||
|
||
void simplifyString() {
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
ASSERT_EQUALS("\"abc\"", tokenizer.simplifyString("\"abc\""));
|
||
ASSERT_EQUALS("\"\n\"", tokenizer.simplifyString("\"\\xa\""));
|
||
ASSERT_EQUALS("\"3\"", tokenizer.simplifyString("\"\\x33\""));
|
||
ASSERT_EQUALS("\"33\"", tokenizer.simplifyString("\"\\x333\""));
|
||
|
||
ASSERT_EQUALS("\"a\"", tokenizer.simplifyString("\"\\x61\""));
|
||
ASSERT_EQUALS("\"\n1\"", tokenizer.simplifyString("\"\\0121\""));
|
||
|
||
ASSERT_EQUALS("\"3\"", tokenizer.simplifyString("\"\\x33\""));
|
||
ASSERT_EQUALS("\" 0\"", tokenizer.simplifyString("\"\\0400\""));
|
||
|
||
ASSERT_EQUALS("\"\\nhello\"", tokenizer.simplifyString("\"\\nhello\""));
|
||
|
||
ASSERT_EQUALS("\"aaa\"", tokenizer.simplifyString("\"\\x61\\x61\\x61\""));
|
||
ASSERT_EQUALS("\"\n1\n1\n1\"", tokenizer.simplifyString("\"\\0121\\0121\\0121\""));
|
||
|
||
ASSERT_EQUALS("\"\\\\x61\"", tokenizer.simplifyString("\"\\\\x61\""));
|
||
ASSERT_EQUALS("\"b\"", tokenizer.simplifyString("\"\\x62\""));
|
||
ASSERT_EQUALS("\" 7\"", tokenizer.simplifyString("\"\\0407\""));
|
||
|
||
// terminate a string at null character.
|
||
ASSERT_EQUALS(std::string("\"a") + '\0' + "\"", tokenizer.simplifyString("\"a\\0\""));
|
||
}
|
||
|
||
void simplifyConst() {
|
||
ASSERT_EQUALS("void foo ( ) { const int x ; }",
|
||
tokenizeAndStringify("void foo(){ int const x;}"));
|
||
|
||
ASSERT_EQUALS("void foo ( ) { { } const long x ; }",
|
||
tokenizeAndStringify("void foo(){ {} long const x;}"));
|
||
|
||
ASSERT_EQUALS("void foo ( int b , const unsigned int x ) { }",
|
||
tokenizeAndStringify("void foo(int b,unsigned const x){}"));
|
||
|
||
ASSERT_EQUALS("void foo ( ) { bar ( ) ; const char x ; }",
|
||
tokenizeAndStringify("void foo(){ bar(); char const x;}"));
|
||
|
||
ASSERT_EQUALS("void foo ( const char x ) { }",
|
||
tokenizeAndStringify("void foo(char const x){}"));
|
||
|
||
ASSERT_EQUALS("void foo ( int b , const char x ) { }",
|
||
tokenizeAndStringify("void foo(int b,char const x){}"));
|
||
|
||
ASSERT_EQUALS("void foo ( ) { int * const x ; }",
|
||
tokenizeAndStringify("void foo(){ int * const x;}"));
|
||
|
||
ASSERT_EQUALS("const int foo ( ) ;", tokenizeAndStringify("int const foo ();"));
|
||
|
||
ASSERT_EQUALS("const int x ;", tokenizeAndStringify("int const x;"));
|
||
ASSERT_EQUALS("const unsigned int x ;", tokenizeAndStringify("unsigned const x;"));
|
||
ASSERT_EQUALS("const struct X x ;", tokenizeAndStringify("struct X const x;"));
|
||
}
|
||
|
||
void switchCase() {
|
||
ASSERT_EQUALS("void foo ( int i ) { switch ( i ) { case -1 : ; break ; } }",
|
||
tokenizeAndStringify("void foo (int i) { switch(i) { case -1: break; } }"));
|
||
//ticket #3227
|
||
ASSERT_EQUALS("void foo ( ) { switch ( n ) { label : ; case 1 : ; label1 : ; label2 : ; break ; } }",
|
||
tokenizeAndStringify("void foo(){ switch (n){ label: case 1: label1: label2: break; }}"));
|
||
//ticket #8345
|
||
ASSERT_EQUALS("void foo ( ) { switch ( 0 ) { case 0 : ; default : ; } }",
|
||
tokenizeAndStringify("void foo () { switch(0) case 0 : default : ; }"));
|
||
//ticket #8477
|
||
ASSERT_EQUALS("void foo ( ) { enum Anonymous0 : int { Six = 6 } ; return Six ; }",
|
||
tokenizeAndStringify("void foo () { enum : int { Six = 6 } ; return Six ; }"));
|
||
// ticket #8281
|
||
tokenizeAndStringify("void lzma_decode(int i) { "
|
||
" bool state; "
|
||
" switch (i) "
|
||
" while (true) { "
|
||
" state=false; "
|
||
" case 1: "
|
||
" ; "
|
||
" }"
|
||
"}");
|
||
// ticket #8417
|
||
tokenizeAndStringify("void printOwnedAttributes(int mode) { "
|
||
" switch(mode) case 0: { break; } "
|
||
"}");
|
||
ASSERT_THROW(tokenizeAndStringify("void printOwnedAttributes(int mode) { "
|
||
" switch(mode) case 0: { break; } case 1: ; "
|
||
"}"),
|
||
InternalError);
|
||
}
|
||
|
||
void simplifyPointerToStandardType() {
|
||
// Pointer to standard type
|
||
ASSERT_EQUALS("char buf [ 100 ] ; readlink ( path , buf , 99 ) ;",
|
||
tokenizeAndStringify("char buf[100] ; readlink(path, &buf[0], 99);",
|
||
false, true, Settings::Native, "test.c"));
|
||
|
||
ASSERT_EQUALS("void foo ( char * c ) { if ( 1 == ( 1 & c [ 0 ] ) ) { } }",
|
||
tokenizeAndStringify("void foo(char *c) { if (1==(1 & c[0])) {} }",
|
||
false, true, Settings::Native, "test.c"));
|
||
|
||
// Simplification of unknown type - C only
|
||
ASSERT_EQUALS("foo data [ 100 ] ; something ( foo ) ;",
|
||
tokenizeAndStringify("foo data[100]; something(&foo[0]);", false, true, Settings::Native, "test.c"));
|
||
|
||
// C++: No pointer simplification
|
||
ASSERT_EQUALS("foo data [ 100 ] ; something ( & foo [ 0 ] ) ;",
|
||
tokenizeAndStringify("foo data[100]; something(&foo[0]);"));
|
||
}
|
||
|
||
void functionpointer1() {
|
||
ASSERT_EQUALS("void ( * f ) ( ) ;", tokenizeAndStringify("void (*f)();"));
|
||
ASSERT_EQUALS("void * ( * f ) ( ) ;", tokenizeAndStringify("void *(*f)();"));
|
||
ASSERT_EQUALS("unsigned int ( * f ) ( ) ;", tokenizeAndStringify("unsigned int (*f)();"));
|
||
ASSERT_EQUALS("unsigned int * ( * f ) ( ) ;", tokenizeAndStringify("unsigned int * (*f)();"));
|
||
}
|
||
|
||
void functionpointer2() {
|
||
const char code[] = "typedef void (* PF)();"
|
||
"void f1 ( ) { }"
|
||
"PF pf = &f1;"
|
||
"PF pfs[] = { &f1, &f1 };";
|
||
const char expected[] = "void f1 ( ) { } "
|
||
"void ( * pf ) ( ) ; pf = & f1 ; "
|
||
"void ( * pfs [ ] ) ( ) = { & f1 , & f1 } ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void functionpointer3() {
|
||
// Related with ticket #2873
|
||
const char code[] = "void f() {\n"
|
||
"(void)(xy(*p)(0);)"
|
||
"\n}";
|
||
const char expected[] = "void f ( ) {\n"
|
||
"( void ) ( xy ( * p ) ( 0 ) ; )\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void functionpointer4() {
|
||
const char code[] = "struct S\n"
|
||
"{\n"
|
||
" typedef void (*FP)();\n"
|
||
" virtual FP getFP();\n"
|
||
"};";
|
||
const char expected[] = "1: struct S\n"
|
||
"2: {\n"
|
||
"3:\n"
|
||
"4: virtual void * getFP ( ) ;\n"
|
||
"5: } ;\n";
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, false));
|
||
}
|
||
|
||
void functionpointer5() {
|
||
const char code[] = ";void (*fp[])(int a) = {0,0,0};";
|
||
const char expected[] = "1: ; void ( * fp@1 [ ] ) ( ) = { 0 , 0 , 0 } ;\n"; // TODO: Array dimension
|
||
ASSERT_EQUALS(expected, tokenizeDebugListing(code, false));
|
||
}
|
||
|
||
void functionpointer6() {
|
||
const char code1[] = "void (*fp(void))(int) {}";
|
||
const char expected1[] = "1: void * fp ( ) { }\n";
|
||
ASSERT_EQUALS(expected1, tokenizeDebugListing(code1, false));
|
||
|
||
const char code2[] = "std::string (*fp(void))(int);";
|
||
const char expected2[] = "1: std :: string * fp ( ) ;\n";
|
||
ASSERT_EQUALS(expected2, tokenizeDebugListing(code2, false));
|
||
}
|
||
|
||
void functionpointer7() {
|
||
const char code1[] = "void (X::*y)();";
|
||
const char expected1[] = "1: void ( * y@1 ) ( ) ;\n";
|
||
ASSERT_EQUALS(expected1, tokenizeDebugListing(code1, false));
|
||
}
|
||
|
||
void functionpointer8() {
|
||
const char code1[] = "int (*f)() throw(int);";
|
||
const char expected1[] = "1: int ( * f@1 ) ( ) ;\n";
|
||
ASSERT_EQUALS(expected1, tokenizeDebugListing(code1, false));
|
||
}
|
||
|
||
void functionpointer9() { // function call with function pointer
|
||
const char code1[] = "int f() { (*f)(); }";
|
||
const char expected1[] = "1: int f ( ) { ( * f ) ( ) ; }\n";
|
||
ASSERT_EQUALS(expected1, tokenizeDebugListing(code1, false));
|
||
|
||
const char code2[] = "int f() { return (*f)(); }";
|
||
const char expected2[] = "1: int f ( ) { return ( * f ) ( ) ; }\n";
|
||
ASSERT_EQUALS(expected2, tokenizeDebugListing(code2, false));
|
||
|
||
const char code3[] = "int f() { throw (*f)(); }";
|
||
const char expected3[] = "1: int f ( ) { throw ( * f ) ( ) ; }\n";
|
||
ASSERT_EQUALS(expected3, tokenizeDebugListing(code3, false));
|
||
}
|
||
|
||
void removeRedundantAssignment() {
|
||
ASSERT_EQUALS("void f ( ) { }", tokenizeAndStringify("void f() { int *p, *q; p = q; }", true));
|
||
ASSERT_EQUALS("void f ( ) { }", tokenizeAndStringify("void f() { int *p = 0, *q; p = q; }", true));
|
||
ASSERT_EQUALS("int f ( int * x ) { return * x ; }", tokenizeAndStringify("int f(int *x) { return *x; }", true));
|
||
}
|
||
|
||
void removedeclspec() {
|
||
ASSERT_EQUALS("a b", tokenizeAndStringify("a __declspec ( dllexport ) b"));
|
||
ASSERT_EQUALS("a b", tokenizeAndStringify("a _declspec ( dllexport ) b"));
|
||
ASSERT_EQUALS("int a ;", tokenizeAndStringify("__declspec(thread) __declspec(align(32)) int a;"));
|
||
ASSERT_EQUALS("int i ;", tokenizeAndStringify("__declspec(allocate(\"mycode\")) int i;"));
|
||
ASSERT_EQUALS("struct IUnknown ;", tokenizeAndStringify("struct __declspec(uuid(\"00000000-0000-0000-c000-000000000046\")) IUnknown;"));
|
||
ASSERT_EQUALS("__property int x [ ] ;", tokenizeAndStringify("__declspec(property(get=GetX, put=PutX)) int x[];"));
|
||
}
|
||
|
||
void removeattribute() {
|
||
ASSERT_EQUALS("short array [ 3 ] ;", tokenizeAndStringify("short array[3] __attribute__ ((aligned));"));
|
||
ASSERT_EQUALS("int x [ 2 ] ;", tokenizeAndStringify("int x[2] __attribute__ ((packed));"));
|
||
ASSERT_EQUALS("int vecint ;", tokenizeAndStringify("int __attribute__((mode(SI))) __attribute__((vector_size (16))) vecint;"));
|
||
|
||
// alternate spelling #5328
|
||
ASSERT_EQUALS("short array [ 3 ] ;", tokenizeAndStringify("short array[3] __attribute ((aligned));"));
|
||
ASSERT_EQUALS("int x [ 2 ] ;", tokenizeAndStringify("int x[2] __attribute ((packed));"));
|
||
ASSERT_EQUALS("int vecint ;", tokenizeAndStringify("int __attribute((mode(SI))) __attribute((vector_size (16))) vecint;"));
|
||
|
||
ASSERT_EQUALS("struct Payload_IR_config { uint8_t tap [ 16 ] ; } ;", tokenizeAndStringify("struct __attribute__((packed, gcc_struct)) Payload_IR_config { uint8_t tap[16]; };"));
|
||
}
|
||
|
||
void functionAttributeBefore() {
|
||
const char code[] = "void __attribute__((pure)) __attribute__((nothrow)) __attribute__((const)) func1();\n"
|
||
"void __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__)) func2();\n"
|
||
"void __attribute__((nothrow)) __attribute__((pure)) __attribute__((const)) func3();\n"
|
||
"void __attribute__((__nothrow__)) __attribute__((__pure__)) __attribute__((__const__)) func4();\n"
|
||
"void __attribute__((noreturn)) func5();";
|
||
const char expected[] = "void func1 ( ) ; void func2 ( ) ; void func3 ( ) ; void func4 ( ) ; void func5 ( ) ;";
|
||
|
||
errout.str("");
|
||
|
||
// tokenize..
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
|
||
// Expected result..
|
||
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
|
||
|
||
const Token * func1 = Token::findsimplematch(tokenizer.tokens(), "func1");
|
||
const Token * func2 = Token::findsimplematch(tokenizer.tokens(), "func2");
|
||
const Token * func3 = Token::findsimplematch(tokenizer.tokens(), "func3");
|
||
const Token * func4 = Token::findsimplematch(tokenizer.tokens(), "func4");
|
||
const Token * func5 = Token::findsimplematch(tokenizer.tokens(), "func5");
|
||
|
||
ASSERT(func1 && func1->isAttributePure() && func1->isAttributeNothrow() && func1->isAttributeConst());
|
||
ASSERT(func2 && func2->isAttributePure() && func2->isAttributeNothrow() && func2->isAttributeConst());
|
||
ASSERT(func3 && func3->isAttributePure() && func3->isAttributeNothrow() && func3->isAttributeConst());
|
||
ASSERT(func4 && func4->isAttributePure() && func4->isAttributeNothrow() && func4->isAttributeConst());
|
||
ASSERT(func5 && func5->isAttributeNoreturn());
|
||
}
|
||
|
||
void functionAttributeAfter() {
|
||
const char code[] = "void func1() __attribute__((pure)) __attribute__((nothrow)) __attribute__((const));\n"
|
||
"void func2() __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__));\n"
|
||
"void func3() __attribute__((nothrow)) __attribute__((pure)) __attribute__((const));\n"
|
||
"void func4() __attribute__((__nothrow__)) __attribute__((__pure__)) __attribute__((__const__));"
|
||
"void func5() __attribute__((noreturn));";
|
||
const char expected[] = "void func1 ( ) ; void func2 ( ) ; void func3 ( ) ; void func4 ( ) ; void func5 ( ) ;";
|
||
|
||
errout.str("");
|
||
|
||
// tokenize..
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
|
||
// Expected result..
|
||
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
|
||
|
||
const Token * func1 = Token::findsimplematch(tokenizer.tokens(), "func1");
|
||
const Token * func2 = Token::findsimplematch(tokenizer.tokens(), "func2");
|
||
const Token * func3 = Token::findsimplematch(tokenizer.tokens(), "func3");
|
||
const Token * func4 = Token::findsimplematch(tokenizer.tokens(), "func4");
|
||
const Token * func5 = Token::findsimplematch(tokenizer.tokens(), "func5");
|
||
|
||
ASSERT(func1 && func1->isAttributePure() && func1->isAttributeNothrow() && func1->isAttributeConst());
|
||
ASSERT(func2 && func2->isAttributePure() && func2->isAttributeNothrow() && func2->isAttributeConst());
|
||
ASSERT(func3 && func3->isAttributePure() && func3->isAttributeNothrow() && func3->isAttributeConst());
|
||
ASSERT(func4 && func4->isAttributePure() && func4->isAttributeNothrow() && func4->isAttributeConst());
|
||
ASSERT(func5 && func5->isAttributeNoreturn());
|
||
}
|
||
|
||
void cpp03template1() {
|
||
{
|
||
const char *code = "template<typename> struct extent {};";
|
||
ASSERT_EQUALS("template < typename > struct extent { } ;", tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char *code = "template<typename> struct extent;";
|
||
ASSERT_EQUALS("template < typename > struct extent ;", tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char *code = "template<typename, unsigned = 0> struct extent;";
|
||
ASSERT_EQUALS("template < typename , unsigned int = 0 > struct extent ;", tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void cpp0xtemplate1() {
|
||
const char *code = "template <class T>\n"
|
||
"void fn2 (T t = []{return 1;}())\n"
|
||
"{}\n"
|
||
"int main()\n"
|
||
"{\n"
|
||
" fn2<int>();\n"
|
||
"}\n";
|
||
ASSERT_EQUALS("void fn2<int> ( int t = [ ] { return 1 ; } ( ) ) ;\n"
|
||
"\n"
|
||
"int main ( )\n"
|
||
"{\n"
|
||
"fn2<int> ( ) ;\n"
|
||
"} void fn2<int> ( int t = [ ] { return 1 ; } ( ) )\n"
|
||
"{ }", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void cpp0xtemplate2() {
|
||
// tokenize ">>" into "> >"
|
||
const char *code = "list<list<int>> ints;\n";
|
||
ASSERT_EQUALS("list < list < int > > ints ;", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void cpp0xtemplate3() {
|
||
// #2549
|
||
const char *code = "template<class T, T t = (T)0>\n"
|
||
"struct S\n"
|
||
"{};\n"
|
||
"S<int> s;\n";
|
||
ASSERT_EQUALS("struct S<int,(int)0> ;\n"
|
||
"\n"
|
||
"\n"
|
||
"S<int,(int)0> s ; struct S<int,(int)0>\n"
|
||
"{ } ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void cpp0xtemplate4() { // #6181, #6354, #6414
|
||
tokenizeAndStringify("class A; "
|
||
"template <class T> class Disposer; "
|
||
"template <typename T, class D = Disposer<T>> class Shim {}; "
|
||
"class B : public Shim<A> {};");
|
||
tokenizeAndStringify("template <class ELFT> class ELFObjectImage {}; "
|
||
"ObjectImage *createObjectImage() { "
|
||
" return new ELFObjectImage<ELFType<little>>(Obj); "
|
||
"} "
|
||
"void resolveX86_64Relocation() { "
|
||
" reinterpret_cast<int>(0); "
|
||
"}");
|
||
tokenizeAndStringify("template<typename value_type, typename function_type> "
|
||
"value_type Base(const value_type x, const value_type dx, function_type func, int type_deriv) { "
|
||
" return 0.0; "
|
||
"}; "
|
||
"namespace { "
|
||
" template<class DC> class C { "
|
||
" void Fun(int G, const double x); "
|
||
" }; "
|
||
" template<class DC> void C<DC>::Fun(int G, const double x) {"
|
||
" Base<double, CDFFunctor<DC>>(2, 2, f, 0); "
|
||
" }; "
|
||
" template<class DC> class C2 {}; "
|
||
"}");
|
||
}
|
||
|
||
void cpp0xtemplate5() { // #9154
|
||
{
|
||
const char *code = "struct s<x<u...>>;";
|
||
ASSERT_EQUALS("struct s < x < u ... > > ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char *code = "template <class f> using c = e<i<q<f,r>,b...>>;";
|
||
ASSERT_EQUALS("template < class f > using c = e < i < q < f , r > , b ... > > ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char *code = "struct s<x<u...>> { };";
|
||
ASSERT_EQUALS("struct s < x < u ... > > { } ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char *code = "struct q : s<x<u...>> { };";
|
||
ASSERT_EQUALS("struct q : s < x < u ... > > { } ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char *code = "struct q : private s<x<u...>> { };";
|
||
ASSERT_EQUALS("struct q : private s < x < u ... > > { } ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void cpp14template() { // Ticket #6708
|
||
tokenizeAndStringify("template <typename T> "
|
||
"decltype(auto) forward(T& t) { return 0; }");
|
||
}
|
||
|
||
void arraySize() {
|
||
ASSERT_EQUALS("; int a [ 3 ] = { 1 , 2 , 3 } ;", tokenizeAndStringify(";int a[]={1,2,3};"));
|
||
ASSERT_EQUALS("; int a [ 3 ] = { 1 , 2 , 3 } ;", tokenizeAndStringify(";int a[]={1,2,3,};"));
|
||
ASSERT_EQUALS("; foo a [ 3 ] = { { 1 , 2 } , { 3 , 4 } , { 5 , 6 } } ;", tokenizeAndStringify(";foo a[]={{1,2},{3,4},{5,6}};"));
|
||
ASSERT_EQUALS("; int a [ 1 ] = { foo < bar1 , bar2 > ( 123 , 4 ) } ;", tokenizeAndStringify(";int a[]={foo<bar1,bar2>(123,4)};"));
|
||
ASSERT_EQUALS("; int a [ 2 ] = { b > c ? 1 : 2 , 3 } ;", tokenizeAndStringify(";int a[]={ b>c?1:2,3};"));
|
||
ASSERT_EQUALS("int main ( ) { int a [ 2 ] = { b < c ? 1 : 2 , 3 } }", tokenizeAndStringify("int main(){int a[]={b<c?1:2,3}}"));
|
||
ASSERT_EQUALS("; int a [ 3 ] = { ABC , 2 , 3 } ;", tokenizeAndStringify(";int a[]={ABC,2,3};"));
|
||
ASSERT_EQUALS("; int a [ 3 ] = { [ 2 ] = 5 } ;", tokenizeAndStringify(";int a[]={ [2] = 5 };"));
|
||
ASSERT_EQUALS("; int a [ 5 ] = { 1 , 2 , [ 2 ] = 5 , 3 , 4 } ;", tokenizeAndStringify(";int a[]={ 1, 2, [2] = 5, 3, 4 };"));
|
||
ASSERT_EQUALS("; int a [ ] = { 1 , 2 , [ x ] = 5 , 3 , 4 } ;", tokenizeAndStringify(";int a[]={ 1, 2, [x] = 5, 3, 4 };"));
|
||
}
|
||
|
||
void labels() {
|
||
ASSERT_EQUALS("void f ( ) { ab : ; a = 0 ; }", tokenizeAndStringify("void f() { ab: a=0; }"));
|
||
//ticket #3176
|
||
ASSERT_EQUALS("void f ( ) { ab : ; ( * func ) ( ) ; }", tokenizeAndStringify("void f() { ab: (*func)(); }"));
|
||
//with '*' operator
|
||
ASSERT_EQUALS("void f ( ) { ab : ; * b = 0 ; }", tokenizeAndStringify("void f() { ab: *b=0; }"));
|
||
ASSERT_EQUALS("void f ( ) { ab : ; * * b = 0 ; }", tokenizeAndStringify("void f() { ab: **b=0; }"));
|
||
//with '&' operator
|
||
ASSERT_EQUALS("void f ( ) { ab : ; & b = 0 ; }", tokenizeAndStringify("void f() { ab: &b=0; }"));
|
||
ASSERT_EQUALS("void f ( ) { ab : ; & ( b . x ) = 0 ; }", tokenizeAndStringify("void f() { ab: &(b->x)=0; }"));
|
||
//with '(' parentheses
|
||
ASSERT_EQUALS("void f ( ) { ab : ; * ( * b ) . x = 0 ; }", tokenizeAndStringify("void f() { ab: *(* b)->x=0; }"));
|
||
ASSERT_EQUALS("void f ( ) { ab : ; ( * * b ) . x = 0 ; }", tokenizeAndStringify("void f() { ab: (** b).x=0; }"));
|
||
ASSERT_EQUALS("void f ( ) { ab : ; & ( * b . x ) = 0 ; }", tokenizeAndStringify("void f() { ab: &(*b.x)=0; }"));
|
||
//with '{' parentheses
|
||
ASSERT_EQUALS("void f ( ) { ab : ; { b = 0 ; } }", tokenizeAndStringify("void f() { ab: {b=0;} }"));
|
||
ASSERT_EQUALS("void f ( ) { ab : ; { * b = 0 ; } }", tokenizeAndStringify("void f() { ab: { *b=0;} }"));
|
||
ASSERT_EQUALS("void f ( ) { ab : ; { & b = 0 ; } }", tokenizeAndStringify("void f() { ab: { &b=0;} }"));
|
||
ASSERT_EQUALS("void f ( ) { ab : ; { & ( * b . x ) = 0 ; } }", tokenizeAndStringify("void f() { ab: {&(*b.x)=0;} }"));
|
||
//with unhandled MACRO() code
|
||
ASSERT_THROW(tokenizeAndStringify("void f() { MACRO(ab: b=0;, foo)}"), InternalError);
|
||
ASSERT_EQUALS("void f ( ) { MACRO ( bar , ab : { & ( * b . x ) = 0 ; } ) }", tokenizeAndStringify("void f() { MACRO(bar, ab: {&(*b.x)=0;})}"));
|
||
}
|
||
|
||
void simplifyInitVar() {
|
||
{
|
||
const char code[] = "int i ; int p(0);";
|
||
ASSERT_EQUALS("int i ; int p ; p = 0 ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int i; int *p(0);";
|
||
ASSERT_EQUALS("int i ; int * p ; p = 0 ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int p(0);";
|
||
ASSERT_EQUALS("int p ; p = 0 ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int *p(0);";
|
||
ASSERT_EQUALS("int * p ; p = 0 ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int i ; int p(i);";
|
||
ASSERT_EQUALS("int i ; int p ; p = i ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int i; int *p(&i);";
|
||
ASSERT_EQUALS("int i ; int * p ; p = & i ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int i; void *p(&i);";
|
||
ASSERT_EQUALS("int i ; void * p ; p = & i ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "struct S { }; struct S s; struct S *p(&s);";
|
||
ASSERT_EQUALS("struct S { } ; struct S s ; struct S * p ; p = & s ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "struct S { }; S s; S *p(&s);";
|
||
ASSERT_EQUALS("struct S { } ; S s ; S * p ; p = & s ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "union S { int i; float f; }; union S s; union S *p(&s);";
|
||
ASSERT_EQUALS("union S { int i ; float f ; } ; union S s ; union S * p ; p = & s ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "union S { int i; float f; }; S s; S *p(&s);";
|
||
ASSERT_EQUALS("union S { int i ; float f ; } ; S s ; S * p ; p = & s ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "class C { }; class C c; class C *p(&c);";
|
||
ASSERT_EQUALS("class C { } ; class C c ; class C * p ; p = & c ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "class C { }; C c; C *p(&c);";
|
||
ASSERT_EQUALS("class C { } ; C c ; C * p ; p = & c ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "struct S { }; struct S s; struct S s1(s);";
|
||
ASSERT_EQUALS("struct S { } ; struct S s ; struct S s1 ( s ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "struct S { }; S s; S s1(s);";
|
||
ASSERT_EQUALS("struct S { } ; S s ; S s1 ( s ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "struct S { }; struct S s; struct S s1(&s);";
|
||
ASSERT_EQUALS("struct S { } ; struct S s ; struct S s1 ( & s ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "struct S { }; S s; S s1(&s);";
|
||
ASSERT_EQUALS("struct S { } ; S s ; S s1 ( & s ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "class S { int function(); };";
|
||
ASSERT_EQUALS("class S { int function ( ) ; } ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "class S { int function(void); };";
|
||
ASSERT_EQUALS("class S { int function ( ) ; } ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "class S { int function(int); };";
|
||
ASSERT_EQUALS("class S { int function ( int ) ; } ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int function(void);";
|
||
ASSERT_EQUALS("int function ( ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int function(int);";
|
||
ASSERT_EQUALS("int function ( int ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "extern int function(void);";
|
||
ASSERT_EQUALS("extern int function ( ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int function1(void); int function2(void);";
|
||
ASSERT_EQUALS("int function1 ( ) ; int function2 ( ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int function(A);";
|
||
// We can't tell if this a function prototype or a variable without knowing
|
||
// what A is. Since A is undefined, just leave it alone.
|
||
ASSERT_EQUALS("int function ( A ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int i; int function(A);";
|
||
ASSERT_EQUALS("int i ; int function ( A ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "class A { } ; int foo(A);";
|
||
ASSERT_EQUALS("class A { } ; int foo ( A ) ;", tokenizeAndStringify(code));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "class A { } ; A a; int foo(a);";
|
||
ASSERT_EQUALS("class A { } ; A a ; int foo ; foo = a ;", tokenizeAndStringify(code, false));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "int x(f());";
|
||
ASSERT_EQUALS("int x ; x = f ( ) ;", tokenizeAndStringify(code, false));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "{ return doSomething(X), 0; }";
|
||
ASSERT_EQUALS("{ return doSomething ( X ) , 0 ; }", tokenizeAndStringify(code, false));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "const int x(1);"
|
||
"const int y(2);"
|
||
"const int z((x+1)*y);"
|
||
"f(z);";
|
||
ASSERT_EQUALS("f ( 4 ) ;", tokenizeAndStringify(code, true));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "const int x(1);"
|
||
"const int y(2);"
|
||
"const int z((x+1)*y);"
|
||
"f(&z);";
|
||
ASSERT_EQUALS("const int z ( 4 ) ; f ( & z ) ;", tokenizeAndStringify(code, true));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "const bool x(true);"
|
||
"const bool y(!x);"
|
||
"f(y);";
|
||
ASSERT_EQUALS("f ( false ) ;", tokenizeAndStringify(code, true));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
{
|
||
const char code[] = "const bool x(true);"
|
||
"const bool y(!x);"
|
||
"f(&y);";
|
||
ASSERT_EQUALS("const bool y ( false ) ; f ( & y ) ;", tokenizeAndStringify(code, true));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
}
|
||
|
||
void simplifyInitVar2() {
|
||
// ticket #5131 - unsigned
|
||
const char code[] = "void f() {\n"
|
||
" unsigned int a(0),b(0);\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\n"
|
||
"unsigned int a ; a = 0 ; unsigned int b ; b = 0 ;\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyInitVar3() {
|
||
const char code[] = "void f() {\n"
|
||
" int *a(0),b(0);\n"
|
||
"}";
|
||
ASSERT_EQUALS("void f ( ) {\n"
|
||
"int * a ; a = 0 ; int b ; b = 0 ;\n"
|
||
"}", tokenizeAndStringify(code));
|
||
}
|
||
|
||
void bitfields1() {
|
||
const char code1[] = "struct A { bool x : 1; };";
|
||
ASSERT_EQUALS("struct A { bool x ; } ;", tokenizeAndStringify(code1,false));
|
||
|
||
const char code2[] = "struct A { char x : 3; };";
|
||
ASSERT_EQUALS("struct A { char x ; } ;", tokenizeAndStringify(code2,false));
|
||
|
||
const char code3[] = "struct A { short x : 3; };";
|
||
ASSERT_EQUALS("struct A { short x ; } ;", tokenizeAndStringify(code3,false));
|
||
|
||
const char code4[] = "struct A { int x : 3; };";
|
||
ASSERT_EQUALS("struct A { int x ; } ;", tokenizeAndStringify(code4,false));
|
||
|
||
const char code5[] = "struct A { long x : 3; };";
|
||
ASSERT_EQUALS("struct A { long x ; } ;", tokenizeAndStringify(code5,false));
|
||
|
||
const char code6[] = "struct A { __int8 x : 3; };";
|
||
ASSERT_EQUALS("struct A { char x ; } ;", tokenizeAndStringifyWindows(code6,false, true, Settings::Win32A));
|
||
|
||
const char code7[] = "struct A { __int16 x : 3; };";
|
||
ASSERT_EQUALS("struct A { short x ; } ;", tokenizeAndStringifyWindows(code7,false, true, Settings::Win32A));
|
||
|
||
const char code8[] = "struct A { __int32 x : 3; };";
|
||
ASSERT_EQUALS("struct A { int x ; } ;", tokenizeAndStringifyWindows(code8,false, true, Settings::Win32A));
|
||
|
||
const char code9[] = "struct A { __int64 x : 3; };";
|
||
ASSERT_EQUALS("struct A { long long x ; } ;", tokenizeAndStringifyWindows(code9,false, true, Settings::Win32A));
|
||
|
||
const char code10[] = "struct A { unsigned char x : 3; };";
|
||
ASSERT_EQUALS("struct A { unsigned char x ; } ;", tokenizeAndStringify(code10,false));
|
||
|
||
const char code11[] = "struct A { unsigned short x : 3; };";
|
||
ASSERT_EQUALS("struct A { unsigned short x ; } ;", tokenizeAndStringify(code11,false));
|
||
|
||
const char code12[] = "struct A { unsigned int x : 3; };";
|
||
ASSERT_EQUALS("struct A { unsigned int x ; } ;", tokenizeAndStringify(code12,false));
|
||
|
||
const char code13[] = "struct A { unsigned long x : 3; };";
|
||
ASSERT_EQUALS("struct A { unsigned long x ; } ;", tokenizeAndStringify(code13,false));
|
||
|
||
const char code14[] = "struct A { unsigned __int8 x : 3; };";
|
||
ASSERT_EQUALS("struct A { unsigned char x ; } ;", tokenizeAndStringifyWindows(code14,false, true, Settings::Win32A));
|
||
|
||
const char code15[] = "struct A { unsigned __int16 x : 3; };";
|
||
ASSERT_EQUALS("struct A { unsigned short x ; } ;", tokenizeAndStringifyWindows(code15,false, true, Settings::Win32A));
|
||
|
||
const char code16[] = "struct A { unsigned __int32 x : 3; };";
|
||
ASSERT_EQUALS("struct A { unsigned int x ; } ;", tokenizeAndStringifyWindows(code16,false, true, Settings::Win32A));
|
||
|
||
const char code17[] = "struct A { unsigned __int64 x : 3; };";
|
||
ASSERT_EQUALS("struct A { unsigned long long x ; } ;", tokenizeAndStringifyWindows(code17,false, true, Settings::Win32A));
|
||
|
||
const char code18[] = "struct A { signed char x : 3; };";
|
||
ASSERT_EQUALS("struct A { signed char x ; } ;", tokenizeAndStringify(code18,false));
|
||
|
||
const char code19[] = "struct A { signed short x : 3; };";
|
||
ASSERT_EQUALS("struct A { signed short x ; } ;", tokenizeAndStringify(code19,false));
|
||
|
||
const char code20[] = "struct A { signed int x : 3; };";
|
||
ASSERT_EQUALS("struct A { signed int x ; } ;", tokenizeAndStringify(code20,false));
|
||
|
||
const char code21[] = "struct A { signed long x : 3; };";
|
||
ASSERT_EQUALS("struct A { signed long x ; } ;", tokenizeAndStringifyWindows(code21,false));
|
||
|
||
const char code22[] = "struct A { signed __int8 x : 3; };";
|
||
ASSERT_EQUALS("struct A { signed char x ; } ;", tokenizeAndStringifyWindows(code22,false, true, Settings::Win32A));
|
||
|
||
const char code23[] = "struct A { signed __int16 x : 3; };";
|
||
ASSERT_EQUALS("struct A { signed short x ; } ;", tokenizeAndStringifyWindows(code23,false, true, Settings::Win32A));
|
||
|
||
const char code24[] = "struct A { signed __int32 x : 3; };";
|
||
ASSERT_EQUALS("struct A { signed int x ; } ;", tokenizeAndStringifyWindows(code24,false, true, Settings::Win32A));
|
||
|
||
const char code25[] = "struct A { signed __int64 x : 3; };";
|
||
ASSERT_EQUALS("struct A { signed long long x ; } ;", tokenizeAndStringifyWindows(code25,false, true, Settings::Win32A));
|
||
}
|
||
|
||
void bitfields2() {
|
||
const char code1[] = "struct A { public: int x : 3; };";
|
||
ASSERT_EQUALS("struct A { public: int x ; } ;", tokenizeAndStringify(code1,false));
|
||
|
||
const char code2[] = "struct A { public: unsigned long x : 3; };";
|
||
ASSERT_EQUALS("struct A { public: unsigned long x ; } ;", tokenizeAndStringify(code2,false));
|
||
|
||
const char code3[] = "struct A { protected: int x : 3; };";
|
||
ASSERT_EQUALS("struct A { protected: int x ; } ;", tokenizeAndStringify(code3,false));
|
||
|
||
const char code4[] = "struct A { protected: unsigned long x : 3; };";
|
||
ASSERT_EQUALS("struct A { protected: unsigned long x ; } ;", tokenizeAndStringify(code4,false));
|
||
|
||
const char code5[] = "struct A { private: int x : 3; };";
|
||
ASSERT_EQUALS("struct A { private: int x ; } ;", tokenizeAndStringify(code5,false));
|
||
|
||
const char code6[] = "struct A { private: unsigned long x : 3; };";
|
||
ASSERT_EQUALS("struct A { private: unsigned long x ; } ;", tokenizeAndStringify(code6,false));
|
||
}
|
||
|
||
void bitfields3() {
|
||
const char code1[] = "struct A { const int x : 3; };";
|
||
ASSERT_EQUALS("struct A { const int x ; } ;", tokenizeAndStringify(code1,false));
|
||
|
||
const char code2[] = "struct A { const unsigned long x : 3; };";
|
||
ASSERT_EQUALS("struct A { const unsigned long x ; } ;", tokenizeAndStringify(code2,false));
|
||
|
||
const char code3[] = "struct A { public: const int x : 3; };";
|
||
ASSERT_EQUALS("struct A { public: const int x ; } ;", tokenizeAndStringify(code3,false));
|
||
|
||
const char code4[] = "struct A { public: const unsigned long x : 3; };";
|
||
ASSERT_EQUALS("struct A { public: const unsigned long x ; } ;", tokenizeAndStringify(code4,false));
|
||
}
|
||
|
||
void bitfields4() { // ticket #1956
|
||
const char code1[] = "struct A { CHAR x : 3; };";
|
||
ASSERT_EQUALS("struct A { CHAR x ; } ;", tokenizeAndStringify(code1,false));
|
||
|
||
const char code2[] = "struct A { UCHAR x : 3; };";
|
||
ASSERT_EQUALS("struct A { UCHAR x ; } ;", tokenizeAndStringify(code2,false));
|
||
|
||
const char code3[] = "struct A { BYTE x : 3; };";
|
||
ASSERT_EQUALS("struct A { BYTE x ; } ;", tokenizeAndStringify(code3,false));
|
||
|
||
const char code4[] = "struct A { WORD x : 3; };";
|
||
ASSERT_EQUALS("struct A { WORD x ; } ;", tokenizeAndStringify(code4,false));
|
||
|
||
const char code5[] = "struct A { DWORD x : 3; };";
|
||
ASSERT_EQUALS("struct A { DWORD x ; } ;", tokenizeAndStringify(code5,false));
|
||
|
||
const char code6[] = "struct A { LONG x : 3; };";
|
||
ASSERT_EQUALS("struct A { LONG x ; } ;", tokenizeAndStringify(code6,false));
|
||
|
||
const char code7[] = "struct A { UINT8 x : 3; };";
|
||
ASSERT_EQUALS("struct A { UINT8 x ; } ;", tokenizeAndStringify(code7,false));
|
||
|
||
const char code8[] = "struct A { UINT16 x : 3; };";
|
||
ASSERT_EQUALS("struct A { UINT16 x ; } ;", tokenizeAndStringify(code8,false));
|
||
|
||
const char code9[] = "struct A { UINT32 x : 3; };";
|
||
ASSERT_EQUALS("struct A { UINT32 x ; } ;", tokenizeAndStringify(code9,false));
|
||
|
||
const char code10[] = "struct A { UINT64 x : 3; };";
|
||
ASSERT_EQUALS("struct A { UINT64 x ; } ;", tokenizeAndStringify(code10,false));
|
||
}
|
||
|
||
void bitfields5() { // ticket #1956
|
||
const char code1[] = "struct RGB { unsigned int r : 3, g : 3, b : 2; };";
|
||
ASSERT_EQUALS("struct RGB { unsigned int r ; unsigned int g ; unsigned int b ; } ;", tokenizeAndStringify(code1,false));
|
||
|
||
const char code2[] = "struct A { int a : 3; int : 3; int c : 3; };";
|
||
ASSERT_EQUALS("struct A { int a ; int c ; } ;", tokenizeAndStringify(code2,false));
|
||
|
||
const char code3[] = "struct A { virtual void f() {} int f1 : 1; };";
|
||
ASSERT_EQUALS("struct A { virtual void f ( ) { } int f1 ; } ;", tokenizeAndStringify(code3,false));
|
||
}
|
||
|
||
void bitfields6() { // ticket #2595
|
||
const char code1[] = "struct A { bool b : true; };";
|
||
ASSERT_EQUALS("struct A { bool b ; } ;", tokenizeAndStringify(code1,false));
|
||
|
||
const char code2[] = "struct A { bool b : true, c : true; };";
|
||
ASSERT_EQUALS("struct A { bool b ; bool c ; } ;", tokenizeAndStringify(code2,false));
|
||
|
||
const char code3[] = "struct A { bool : true; };";
|
||
ASSERT_EQUALS("struct A { } ;", tokenizeAndStringify(code3,false));
|
||
|
||
const char code4[] = "void f(int a) { switch (a) { case b: break; } }";
|
||
ASSERT_EQUALS("void f ( int a ) { switch ( a ) { case b : ; break ; } }", tokenizeAndStringify(code4,true));
|
||
|
||
const char code5[] = "void f(int a) { switch (a) { default: break; } }";
|
||
ASSERT_EQUALS("void f ( int a ) { switch ( a ) { default : ; break ; } }", tokenizeAndStringify(code5,true));
|
||
}
|
||
|
||
void bitfields7() { // ticket #1987
|
||
const char code[] = "typedef struct Descriptor {"
|
||
" unsigned element_size: 8* sizeof( unsigned );"
|
||
"} Descriptor;";
|
||
const char expected[] = "struct Descriptor { "
|
||
"unsigned int element_size ; "
|
||
"} ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code,false));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
void bitfields8() {
|
||
const char code[] = "struct A;"
|
||
"class B : virtual public C"
|
||
"{"
|
||
" int f();"
|
||
"};";
|
||
const char expected[] = "struct A ; "
|
||
"class B : virtual public C "
|
||
"{ "
|
||
"int f ( ) ; "
|
||
"} ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code,false));
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
void bitfields9() { // ticket #2706
|
||
const char code[] = "void f() {\n"
|
||
" goto half;\n"
|
||
"half:\n"
|
||
" {\n"
|
||
" ;\n"
|
||
" }\n"
|
||
"};";
|
||
tokenizeAndStringify(code,false);
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
void bitfields10() { // ticket #2737
|
||
const char code[] = "{}"
|
||
"MACRO "
|
||
"default: { }"
|
||
";";
|
||
ASSERT_EQUALS("{ } MACRO default : { } ;", tokenizeAndStringify(code,false));
|
||
}
|
||
|
||
void bitfields12() { // ticket #3485 (segmentation fault)
|
||
const char code[] = "{a:1;};\n";
|
||
ASSERT_EQUALS("{ } ;", tokenizeAndStringify(code,false));
|
||
}
|
||
|
||
void bitfields13() { // ticket #3502 (segmentation fault)
|
||
ASSERT_EQUALS("x y ;", tokenizeAndStringify("struct{x y:};\n",false));
|
||
}
|
||
|
||
void bitfields14() { // #4561 - crash for 'signals:'
|
||
ASSERT_EQUALS("class x { protected: } ;", tokenizeAndStringify("class x { signals: };\n",false));
|
||
}
|
||
|
||
void bitfields15() { // #7747 - enum Foo {A,B}:4;
|
||
ASSERT_EQUALS("struct AB {\n"
|
||
"enum Foo { A , B } ; enum Foo Anonymous ;\n"
|
||
"} ;",
|
||
tokenizeAndStringify("struct AB {\n"
|
||
" enum Foo {A,B} : 4;\n"
|
||
"};"));
|
||
ASSERT_EQUALS("struct AB {\n"
|
||
"enum Foo { A , B } ; enum Foo foo ;\n"
|
||
"} ;",
|
||
tokenizeAndStringify("struct AB {\n"
|
||
" enum Foo {A,B} foo : 4;\n"
|
||
"};"));
|
||
}
|
||
|
||
void bitfields16() {
|
||
const char code[] = "struct A { unsigned int x : 1; };";
|
||
|
||
errout.str("");
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
const Token *x = Token::findsimplematch(tokenizer.tokens(), "x");
|
||
ASSERT_EQUALS(1, x->bits());
|
||
}
|
||
|
||
void simplifyNamespaceStd() {
|
||
const char *code, *expected;
|
||
|
||
code = "map<foo, bar> m;"; // namespace std is not used
|
||
ASSERT_EQUALS("map < foo , bar > m ;", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"map<foo, bar> m;";
|
||
ASSERT_EQUALS("std :: map < foo , bar > m ;", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"string s;";
|
||
ASSERT_EQUALS("std :: string s ;", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"void foo() {swap(a, b); }";
|
||
ASSERT_EQUALS("void foo ( ) { std :: swap ( a , b ) ; }", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"void search() {}";
|
||
ASSERT_EQUALS("void search ( ) { }", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"void search();\n"
|
||
"void dostuff() { search(); }";
|
||
ASSERT_EQUALS("void search ( ) ;\nvoid dostuff ( ) { search ( ) ; }", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"void foo() {map(a, b); }"; // That's obviously not std::map<>
|
||
ASSERT_EQUALS("void foo ( ) { map ( a , b ) ; }", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"string<wchar_t> s;"; // That's obviously not std::string
|
||
ASSERT_EQUALS("string < wchar_t > s ;", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"swap s;"; // That's obviously not std::swap
|
||
ASSERT_EQUALS("swap s ;", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"std::string s;";
|
||
ASSERT_EQUALS("std :: string s ;", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"tr1::function <void(int)> f;";
|
||
ASSERT_EQUALS("tr1 :: function < void ( int ) > f ;", tokenizeAndStringify(code, false, true, Settings::Native, "test.cpp", false));
|
||
ASSERT_EQUALS("std :: function < void ( int ) > f ;", tokenizeAndStringify(code, false, true, Settings::Native, "test.cpp", true));
|
||
|
||
code = "std::tr1::function <void(int)> f;";
|
||
ASSERT_EQUALS("std :: tr1 :: function < void ( int ) > f ;", tokenizeAndStringify(code, false, true, Settings::Native, "test.cpp", false));
|
||
ASSERT_EQUALS("std :: function < void ( int ) > f ;", tokenizeAndStringify(code, false, true, Settings::Native, "test.cpp", true));
|
||
|
||
// #4042 (Do not add 'std ::' to variables)
|
||
code = "using namespace std;\n"
|
||
"const char * string = \"Hi\";";
|
||
ASSERT_EQUALS("const char * string ; string = \"Hi\" ;", tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"string f(const char * string) {\n"
|
||
" cout << string << endl;\n"
|
||
" return string;\n"
|
||
"}";
|
||
expected = "std :: string f ( const char * string ) {\n"
|
||
"std :: cout << string << std :: endl ;\n"
|
||
"return string ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, false));
|
||
|
||
code = "using namespace std;\n"
|
||
"void f() {\n"
|
||
" try { }\n"
|
||
" catch(std::exception &exception) { }\n"
|
||
"}";
|
||
expected = "void f ( ) {\n"
|
||
"try { }\n"
|
||
"catch ( std :: exception & exception ) { }\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, false));
|
||
|
||
// #5773 (Don't prepend 'std ::' to function definitions)
|
||
code = "using namespace std;\n"
|
||
"class C {\n"
|
||
" void search() {}\n"
|
||
" void search() const {}\n"
|
||
" void search() THROW_MACRO {}\n"
|
||
"};";
|
||
expected = "class C {\n"
|
||
"void search ( ) { }\n"
|
||
"void search ( ) const { }\n"
|
||
"void search ( ) { }\n"
|
||
"} ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, false));
|
||
|
||
// Ticket #8091
|
||
ASSERT_EQUALS("enum Anonymous0 { string } ;",
|
||
tokenizeAndStringify("using namespace std; "
|
||
"enum { string };"));
|
||
ASSERT_EQUALS("enum Type { string } ;",
|
||
tokenizeAndStringify("using namespace std; "
|
||
"enum Type { string } ;"));
|
||
ASSERT_EQUALS("enum class Type { string } ;",
|
||
tokenizeAndStringify("using namespace std; "
|
||
"enum class Type { string } ;"));
|
||
ASSERT_EQUALS("enum struct Type { string } ;",
|
||
tokenizeAndStringify("using namespace std; "
|
||
"enum struct Type { string } ;"));
|
||
ASSERT_EQUALS("enum struct Type : int { f = 0 , string } ;",
|
||
tokenizeAndStringify("using namespace std; "
|
||
"enum struct Type : int { f = 0 , string } ;"));
|
||
ASSERT_EQUALS("enum Type { a , b } ; void foo ( enum Type , std :: string ) { }",
|
||
tokenizeAndStringify("using namespace std; "
|
||
"enum Type { a , b } ; void foo ( enum Type , string) {}"));
|
||
ASSERT_EQUALS("struct T { } ; enum struct Type : int { f = 0 , string } ;",
|
||
tokenizeAndStringify("using namespace std; "
|
||
"struct T { typedef int type; } ; "
|
||
"enum struct Type : T :: type { f = 0 , string } ;"));
|
||
// Handle garbage enum code "well"
|
||
ASSERT_EQUALS("enum E : int ; void foo ( ) { std :: string s ; }",
|
||
tokenizeAndStringify("using namespace std; enum E : int ; void foo ( ) { string s ; }"));
|
||
}
|
||
|
||
void microsoftMemory() {
|
||
const char code1a[] = "void foo() { int a[10], b[10]; CopyMemory(a, b, sizeof(a)); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memcpy ( a , b , sizeof ( a ) ) ; }", tokenizeAndStringify(code1a,false,true,Settings::Win32A));
|
||
|
||
const char code1b[] = "void foo() { int a[10], b[10]; RtlCopyMemory(a, b, sizeof(a)); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memcpy ( a , b , sizeof ( a ) ) ; }", tokenizeAndStringify(code1b,false,true,Settings::Win32A));
|
||
|
||
const char code1c[] = "void foo() { int a[10], b[10]; RtlCopyBytes(a, b, sizeof(a)); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memcpy ( a , b , sizeof ( a ) ) ; }", tokenizeAndStringify(code1c,false,true,Settings::Win32A));
|
||
|
||
const char code2a[] = "void foo() { int a[10]; FillMemory(a, sizeof(a), 255); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; memset ( a , 255 , sizeof ( a ) ) ; }", tokenizeAndStringify(code2a,false,true,Settings::Win32A));
|
||
const char code2b[] = "void foo() { int a[10]; RtlFillMemory(a, sizeof(a), 255); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; memset ( a , 255 , sizeof ( a ) ) ; }", tokenizeAndStringify(code2b,false,true,Settings::Win32A));
|
||
const char code2c[] = "void foo() { int a[10]; RtlFillBytes(a, sizeof(a), 255); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; memset ( a , 255 , sizeof ( a ) ) ; }", tokenizeAndStringify(code2c,false,true,Settings::Win32A));
|
||
|
||
const char code3a[] = "void foo() { int a[10], b[10]; MoveMemory(a, b, sizeof(a)); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memmove ( a , b , sizeof ( a ) ) ; }", tokenizeAndStringify(code3a,false,true,Settings::Win32A));
|
||
const char code3b[] = "void foo() { int a[10], b[10]; RtlMoveMemory(a, b, sizeof(a)); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memmove ( a , b , sizeof ( a ) ) ; }", tokenizeAndStringify(code3b,false,true,Settings::Win32A));
|
||
|
||
const char code4a[] = "void foo() { int a[10]; ZeroMemory(a, sizeof(a)); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; memset ( a , 0 , sizeof ( a ) ) ; }", tokenizeAndStringify(code4a,false,true,Settings::Win32A));
|
||
const char code4b[] = "void foo() { int a[10]; RtlZeroMemory(a, sizeof(a)); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; memset ( a , 0 , sizeof ( a ) ) ; }", tokenizeAndStringify(code4b,false,true,Settings::Win32A));
|
||
const char code4c[] = "void foo() { int a[10]; RtlZeroBytes(a, sizeof(a)); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; memset ( a , 0 , sizeof ( a ) ) ; }", tokenizeAndStringify(code4c,false,true,Settings::Win32A));
|
||
const char code4d[] = "void foo() { int a[10]; RtlSecureZeroMemory(a, sizeof(a)); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; memset ( a , 0 , sizeof ( a ) ) ; }", tokenizeAndStringify(code4d,false,true,Settings::Win32A));
|
||
|
||
const char code5[] = "void foo() { int a[10], b[10]; RtlCompareMemory(a, b, sizeof(a)); }";
|
||
ASSERT_EQUALS("void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memcmp ( a , b , sizeof ( a ) ) ; }", tokenizeAndStringify(code5,false,true,Settings::Win32A));
|
||
|
||
const char code6[] = "void foo() { ZeroMemory(f(1, g(a, b)), h(i, j(0, 1))); }";
|
||
ASSERT_EQUALS("void foo ( ) { memset ( f ( 1 , g ( a , b ) ) , 0 , h ( i , j ( 0 , 1 ) ) ) ; }", tokenizeAndStringify(code6,false,true,Settings::Win32A));
|
||
|
||
const char code7[] = "void foo() { FillMemory(f(1, g(a, b)), h(i, j(0, 1)), 255); }";
|
||
ASSERT_EQUALS("void foo ( ) { memset ( f ( 1 , g ( a , b ) ) , 255 , h ( i , j ( 0 , 1 ) ) ) ; }", tokenizeAndStringify(code7,false,true,Settings::Win32A));
|
||
}
|
||
|
||
void microsoftString() {
|
||
const char code1a[] = "void foo() { _tprintf (_T(\"test\") _T(\"1\")); }";
|
||
ASSERT_EQUALS("void foo ( ) { printf ( \"test1\" ) ; }", tokenizeAndStringify(code1a, false, true, Settings::Win32A));
|
||
const char code1b[] = "void foo() { _tprintf (_TEXT(\"test\") _TEXT(\"2\")); }";
|
||
ASSERT_EQUALS("void foo ( ) { printf ( \"test2\" ) ; }", tokenizeAndStringify(code1b, false, true, Settings::Win32A));
|
||
const char code1c[] = "void foo() { _tprintf (TEXT(\"test\") TEXT(\"3\")); }";
|
||
ASSERT_EQUALS("void foo ( ) { printf ( \"test3\" ) ; }", tokenizeAndStringify(code1c, false, true, Settings::Win32A));
|
||
|
||
const char code2a[] = "void foo() { _tprintf (_T(\"test\") _T(\"1\")); }";
|
||
ASSERT_EQUALS("void foo ( ) { wprintf ( L\"test1\" ) ; }", tokenizeAndStringify(code2a, false, true, Settings::Win32W));
|
||
ASSERT_EQUALS("void foo ( ) { wprintf ( L\"test1\" ) ; }", tokenizeAndStringify(code2a, false, true, Settings::Win64));
|
||
const char code2b[] = "void foo() { _tprintf (_TEXT(\"test\") _TEXT(\"2\")); }";
|
||
ASSERT_EQUALS("void foo ( ) { wprintf ( L\"test2\" ) ; }", tokenizeAndStringify(code2b, false, true, Settings::Win32W));
|
||
ASSERT_EQUALS("void foo ( ) { wprintf ( L\"test2\" ) ; }", tokenizeAndStringify(code2b, false, true, Settings::Win64));
|
||
const char code2c[] = "void foo() { _tprintf (TEXT(\"test\") TEXT(\"3\")); }";
|
||
ASSERT_EQUALS("void foo ( ) { wprintf ( L\"test3\" ) ; }", tokenizeAndStringify(code2c, false, true, Settings::Win32W));
|
||
ASSERT_EQUALS("void foo ( ) { wprintf ( L\"test3\" ) ; }", tokenizeAndStringify(code2c, false, true, Settings::Win64));
|
||
}
|
||
|
||
void borland() {
|
||
// __closure
|
||
ASSERT_EQUALS("int ( * a ) ( ) ;", // TODO VarId
|
||
tokenizeAndStringify("int (__closure *a)();", false, true, Settings::Win32A));
|
||
|
||
// __property
|
||
ASSERT_EQUALS("class Fred { ; __property ; } ;",
|
||
tokenizeAndStringify("class Fred { __property int x = { } };", false, true, Settings::Win32A));
|
||
}
|
||
|
||
void simplifyQtSignalsSlots1() {
|
||
const char code1[] = "class Counter : public QObject "
|
||
"{ "
|
||
" Q_OBJECT "
|
||
"public: "
|
||
" Counter() { m_value = 0; } "
|
||
" int value() const { return m_value; } "
|
||
"public slots: "
|
||
" void setValue(int value); "
|
||
"signals: "
|
||
" void valueChanged(int newValue); "
|
||
"private: "
|
||
" int m_value; "
|
||
"}; "
|
||
"void Counter::setValue(int value) "
|
||
"{ "
|
||
" if (value != m_value) { "
|
||
" m_value = value; "
|
||
" emit valueChanged(value); "
|
||
" } "
|
||
"}";
|
||
|
||
const char result1 [] = "class Counter : public QObject "
|
||
"{ "
|
||
"public: "
|
||
"Counter ( ) { m_value = 0 ; } "
|
||
"int value ( ) const { return m_value ; } "
|
||
"public: "
|
||
"void setValue ( int value ) ; "
|
||
"protected: "
|
||
"void valueChanged ( int newValue ) ; "
|
||
"private: "
|
||
"int m_value ; "
|
||
"} ; "
|
||
"void Counter :: setValue ( int value ) "
|
||
"{ "
|
||
"if ( value != m_value ) { "
|
||
"m_value = value ; "
|
||
"valueChanged ( value ) ; "
|
||
"} "
|
||
"}";
|
||
|
||
ASSERT_EQUALS(result1, tokenizeAndStringify(code1,false));
|
||
|
||
const char code2[] = "class Counter : public QObject "
|
||
"{ "
|
||
" Q_OBJECT "
|
||
"public: "
|
||
" Counter() { m_value = 0; } "
|
||
" int value() const { return m_value; } "
|
||
"public Q_SLOTS: "
|
||
" void setValue(int value); "
|
||
"Q_SIGNALS: "
|
||
" void valueChanged(int newValue); "
|
||
"private: "
|
||
" int m_value; "
|
||
"};"
|
||
"void Counter::setValue(int value) "
|
||
"{ "
|
||
" if (value != m_value) { "
|
||
" m_value = value; "
|
||
" emit valueChanged(value); "
|
||
" } "
|
||
"}";
|
||
|
||
const char result2 [] = "class Counter : public QObject "
|
||
"{ "
|
||
"public: "
|
||
"Counter ( ) { m_value = 0 ; } "
|
||
"int value ( ) const { return m_value ; } "
|
||
"public: "
|
||
"void setValue ( int value ) ; "
|
||
"protected: "
|
||
"void valueChanged ( int newValue ) ; "
|
||
"private: "
|
||
"int m_value ; "
|
||
"} ; "
|
||
"void Counter :: setValue ( int value ) "
|
||
"{ "
|
||
"if ( value != m_value ) { "
|
||
"m_value = value ; "
|
||
"valueChanged ( value ) ; "
|
||
"} "
|
||
"}";
|
||
|
||
ASSERT_EQUALS(result2, tokenizeAndStringify(code2,false));
|
||
|
||
const char code3[] = "class MyObject : public QObject {"
|
||
" MyObject() {}"
|
||
" ~MyObject() {}"
|
||
" public slots:"
|
||
" signals:"
|
||
" void test() {}"
|
||
"};";
|
||
const char result3 [] = "class MyObject : public QObject { "
|
||
"MyObject ( ) { } "
|
||
"~ MyObject ( ) { } "
|
||
"public: "
|
||
"protected: "
|
||
"void test ( ) { } "
|
||
"} ;";
|
||
|
||
ASSERT_EQUALS(result3, tokenizeAndStringify(code3,false));
|
||
ASSERT_EQUALS("", errout.str());
|
||
|
||
const char code4[] = "class MyObject : public QObject {"
|
||
" Q_OBJECT "
|
||
"public slots:"
|
||
"};";
|
||
const char result4[] = "class MyObject : public QObject { "
|
||
"public: "
|
||
"} ;";
|
||
|
||
ASSERT_EQUALS(result4, tokenizeAndStringify(code4,false));
|
||
}
|
||
|
||
void simplifyQtSignalsSlots2() {
|
||
const char code1[] = "class Foo::Bar: public QObject { private slots: };";
|
||
const char result1[] = "class Foo :: Bar : public QObject { private: } ;";
|
||
ASSERT_EQUALS(result1, tokenizeAndStringify(code1,false));
|
||
}
|
||
|
||
void simplifySQL() {
|
||
// Oracle PRO*C extensions for inline SQL. Just replace the SQL with "asm()" to fix wrong error messages
|
||
// ticket: #1959
|
||
ASSERT_EQUALS("asm ( \"\"__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL SELECT A FROM B\"\" ) ;", tokenizeAndStringify("__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL SELECT A FROM B;",false));
|
||
ASSERT_THROW(tokenizeAndStringify("__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL",false), InternalError);
|
||
|
||
ASSERT_EQUALS("asm ( \"\"__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL EXECUTE BEGIN Proc1 ( A ) ; END ; END - __CPPCHECK_EMBEDDED_SQL_EXEC__\"\" ) ; asm ( \"\"__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT\"\" ) ;",
|
||
tokenizeAndStringify("__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL EXECUTE BEGIN Proc1(A); END; END-__CPPCHECK_EMBEDDED_SQL_EXEC__; __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT;",false));
|
||
ASSERT_EQUALS("asm ( \"\"__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL UPDATE A SET B = C\"\" ) ; asm ( \"\"__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT\"\" ) ;",
|
||
tokenizeAndStringify("__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL UPDATE A SET B = C; __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT;",false));
|
||
ASSERT_EQUALS("asm ( \"\"__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT\"\" ) ; asm ( \"\"__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL EXECUTE BEGIN Proc1 ( A ) ; END ; END - __CPPCHECK_EMBEDDED_SQL_EXEC__\"\" ) ;",
|
||
tokenizeAndStringify("__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT; __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL EXECUTE BEGIN Proc1(A); END; END-__CPPCHECK_EMBEDDED_SQL_EXEC__;",false));
|
||
|
||
ASSERT_THROW(tokenizeAndStringify("int f(){ __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL } int a;",false), InternalError);
|
||
ASSERT_THROW(tokenizeAndStringify("__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL int f(){",false), InternalError);
|
||
ASSERT_THROW(tokenizeAndStringify("__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL END-__CPPCHECK_EMBEDDED_SQL_EXEC__ int a;",false), InternalError);
|
||
ASSERT_NO_THROW(tokenizeAndStringify("__CPPCHECK_EMBEDDED_SQL_EXEC__ SQL UPDATE A SET B = :&b->b1, C = :c::c1;",false));
|
||
}
|
||
|
||
void simplifyCAlternativeTokens() {
|
||
ASSERT_EQUALS("void or ( ) ;", tokenizeAndStringify("void or(void);", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a && b ) { ; } }", tokenizeAndStringify("void f() { if (a and b); }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a && b ) { ; } }", tokenizeAndStringify("void f() { if (a and b); }", false, true, Settings::Native, "test.cpp"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a || b ) { ; } }", tokenizeAndStringify("void f() { if (a or b); }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a || b ) { ; } }", tokenizeAndStringify("void f() { if (a or b); }", false, true, Settings::Native, "test.cpp"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a & b ) { ; } }", tokenizeAndStringify("void f() { if (a bitand b); }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a & b ) { ; } }", tokenizeAndStringify("void f() { if (a bitand b); }", false, true, Settings::Native, "test.cpp"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a | b ) { ; } }", tokenizeAndStringify("void f() { if (a bitor b); }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a | b ) { ; } }", tokenizeAndStringify("void f() { if (a bitor b); }", false, true, Settings::Native, "test.cpp"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a ^ b ) { ; } }", tokenizeAndStringify("void f() { if (a xor b); }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a ^ b ) { ; } }", tokenizeAndStringify("void f() { if (a xor b); }", false, true, Settings::Native, "test.cpp"));
|
||
ASSERT_EQUALS("void f ( ) { if ( ~ b ) { ; } }", tokenizeAndStringify("void f() { if (compl b); }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( ~ b ) { ; } }", tokenizeAndStringify("void f() { if (compl b); }", false, true, Settings::Native, "test.cpp"));
|
||
ASSERT_EQUALS("void f ( ) { if ( ! b ) { ; } }", tokenizeAndStringify("void f() { if (not b); }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( ! b ) { ; } }", tokenizeAndStringify("void f() { if (not b); }", false, true, Settings::Native, "test.cpp"));
|
||
ASSERT_EQUALS("void f ( ) const { if ( ! b ) { ; } }", tokenizeAndStringify("void f() const { if (not b); }", false, true, Settings::Native, "test.cpp"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a != b ) { ; } }", tokenizeAndStringify("void f() { if (a not_eq b); }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( a != b ) { ; } }", tokenizeAndStringify("void f() { if (a not_eq b); }", false, true, Settings::Native, "test.cpp"));
|
||
// #6201
|
||
ASSERT_EQUALS("void f ( ) { if ( ! c || ! memcmp ( a , b , s ) ) { ; } }", tokenizeAndStringify("void f() { if (!c or !memcmp(a, b, s)); }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( ! c || ! memcmp ( a , b , s ) ) { ; } }", tokenizeAndStringify("void f() { if (!c or !memcmp(a, b, s)); }", false, true, Settings::Native, "test.cpp"));
|
||
// #6029
|
||
ASSERT_EQUALS("void f ( ) { if ( ! b ) { } }", tokenizeAndStringify("void f() { if (not b){} }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( ! b ) { } }", tokenizeAndStringify("void f() { if (not b){} }", false, true, Settings::Native, "test.cpp"));
|
||
// #6207
|
||
ASSERT_EQUALS("void f ( ) { if ( not = x ) { } }", tokenizeAndStringify("void f() { if (not=x){} }", false, true, Settings::Native, "test.c"));
|
||
ASSERT_EQUALS("void f ( ) { if ( not = x ) { } }", tokenizeAndStringify("void f() { if (not=x){} }", false, true, Settings::Native, "test.cpp"));
|
||
// #8029
|
||
ASSERT_EQUALS("void f ( struct S * s ) { x = s . and + 1 ; }", tokenizeAndStringify("void f(struct S *s) { x = s->and + 1; }", false, true, Settings::Native, "test.c"));
|
||
// #8745
|
||
ASSERT_EQUALS("void f ( ) { if ( x ) { or = 0 ; } }", tokenizeAndStringify("void f() { if (x) or = 0; }"));
|
||
// #9324
|
||
ASSERT_EQUALS("void f ( const char * str ) { while ( * str == '!' || * str == '[' ) { } }",
|
||
tokenizeAndStringify("void f(const char *str) { while (*str=='!' or *str=='['){} }"));
|
||
// #9920
|
||
ASSERT_EQUALS("result = ch != s . end ( ) && * ch == ':' ;", tokenizeAndStringify("result = ch != s.end() and *ch == ':';", false, true, Settings::Native, "test.c"));
|
||
}
|
||
|
||
void simplifyCalculations() {
|
||
ASSERT_EQUALS("void foo ( char str [ ] ) { char x ; x = * str ; }",
|
||
tokenizeAndStringify("void foo ( char str [ ] ) { char x = 0 | ( * str ) ; }", true));
|
||
ASSERT_EQUALS("void foo ( ) { if ( b ) { } }",
|
||
tokenizeAndStringify("void foo ( ) { if (b + 0) { } }", true));
|
||
ASSERT_EQUALS("void foo ( ) { if ( b ) { } }",
|
||
tokenizeAndStringify("void foo ( ) { if (0 + b) { } }", true));
|
||
ASSERT_EQUALS("void foo ( ) { if ( b ) { } }",
|
||
tokenizeAndStringify("void foo ( ) { if (b - 0) { } }", true));
|
||
ASSERT_EQUALS("void foo ( ) { if ( b ) { } }",
|
||
tokenizeAndStringify("void foo ( ) { if (b * 1) { } }", true));
|
||
ASSERT_EQUALS("void foo ( ) { if ( b ) { } }",
|
||
tokenizeAndStringify("void foo ( ) { if (1 * b) { } }", true));
|
||
//ASSERT_EQUALS("void foo ( ) { if ( b ) { } }",
|
||
// tokenizeAndStringify("void foo ( ) { if (b / 1) { } }", true));
|
||
ASSERT_EQUALS("void foo ( ) { if ( b ) { } }",
|
||
tokenizeAndStringify("void foo ( ) { if (b | 0) { } }", true));
|
||
ASSERT_EQUALS("void foo ( ) { if ( b ) { } }",
|
||
tokenizeAndStringify("void foo ( ) { if (0 | b) { } }", true));
|
||
ASSERT_EQUALS("void foo ( int b ) { int a ; a = b ; bar ( a ) ; }",
|
||
tokenizeAndStringify("void foo ( int b ) { int a = b | 0 ; bar ( a ) ; }", true));
|
||
ASSERT_EQUALS("void foo ( int b ) { int a ; a = b ; bar ( a ) ; }",
|
||
tokenizeAndStringify("void foo ( int b ) { int a = 0 | b ; bar ( a ) ; }", true));
|
||
|
||
// ticket #3093
|
||
ASSERT_EQUALS("int f ( ) { return 15 ; }",
|
||
tokenizeAndStringify("int f() { int a = 10; int b = 5; return a + b; }", true));
|
||
ASSERT_EQUALS("int f ( ) { return a ; }",
|
||
tokenizeAndStringify("int f() { return a * 1; }", true));
|
||
ASSERT_EQUALS("int f ( int a ) { return 0 ; }",
|
||
tokenizeAndStringify("int f(int a) { return 0 * a; }", true));
|
||
ASSERT_EQUALS("bool f ( int i ) { switch ( i ) { case 15 : ; return true ; } }",
|
||
tokenizeAndStringify("bool f(int i) { switch (i) { case 10 + 5: return true; } }", true));
|
||
|
||
// ticket #3576 - False positives in boolean expressions
|
||
ASSERT_EQUALS("int foo ( ) { return 1 ; }",
|
||
tokenizeAndStringify("int foo ( ) { int i; int j; i = 1 || j; return i; }", true));
|
||
|
||
ASSERT_EQUALS("int foo ( ) { return 0 ; }",
|
||
tokenizeAndStringify("int foo ( ) { int i; int j; i = 0 && j; return i; }", true)); // ticket #3576 - False positives in boolean expressions
|
||
|
||
// ticket #3723 - Simplify condition (0 && a < 123)
|
||
ASSERT_EQUALS("( 0 ) ;",
|
||
tokenizeAndStringify("( 0 && a < 123 );", true));
|
||
ASSERT_EQUALS("( 0 ) ;",
|
||
tokenizeAndStringify("( 0 && a[123] );", true));
|
||
|
||
// ticket #4931
|
||
ASSERT_EQUALS("dostuff ( 1 ) ;", tokenizeAndStringify("dostuff(9&&8);", true));
|
||
}
|
||
|
||
void simplifyRoundCurlyParentheses() {
|
||
ASSERT_EQUALS("; x = 123 ;", tokenizeAndStringify(";x=({123;});"));
|
||
ASSERT_EQUALS("; x = y ;", tokenizeAndStringify(";x=({y;});"));
|
||
}
|
||
|
||
void simplifyOperatorName1() {
|
||
// make sure C code doesn't get changed
|
||
const char code[] = "void operator () {}"
|
||
"int main()"
|
||
"{"
|
||
" operator();"
|
||
"}";
|
||
|
||
const char result [] = "void operator ( ) { } "
|
||
"int main ( ) "
|
||
"{ "
|
||
"operator ( ) ; "
|
||
"}";
|
||
|
||
ASSERT_EQUALS(result, tokenizeAndStringify(code, /*simplify=*/false, /*expand=*/true, /*platform=*/Settings::Native, "test.c"));
|
||
}
|
||
|
||
void simplifyOperatorName2() {
|
||
const char code[] = "class Fred"
|
||
"{"
|
||
" Fred(const Fred & f) { operator = (f); }"
|
||
" operator = ();"
|
||
"}";
|
||
|
||
const char result [] = "class Fred "
|
||
"{ "
|
||
"Fred ( const Fred & f ) { operator= ( f ) ; } "
|
||
"operator= ( ) ; "
|
||
"}";
|
||
|
||
ASSERT_EQUALS(result, tokenizeAndStringify(code,false));
|
||
}
|
||
|
||
void simplifyOperatorName3() {
|
||
// #2615
|
||
const char code[] = "void f() {"
|
||
"static_cast<ScToken*>(xResult.operator->())->GetMatrix();"
|
||
"}";
|
||
const char result[] = "void f ( ) { static_cast < ScToken * > ( xResult . operator. ( ) ) . GetMatrix ( ) ; }";
|
||
ASSERT_EQUALS(result, tokenizeAndStringify(code,false));
|
||
}
|
||
|
||
void simplifyOperatorName4() {
|
||
const char code[] = "void operator==() { }";
|
||
const char result[] = "void operator== ( ) { }";
|
||
ASSERT_EQUALS(result, tokenizeAndStringify(code,false));
|
||
}
|
||
|
||
void simplifyOperatorName5() {
|
||
const char code1[] = "std::istream & operator >> (std::istream & s, Fred &f);";
|
||
const char result1[] = "std :: istream & operator>> ( std :: istream & s , Fred & f ) ;";
|
||
ASSERT_EQUALS(result1, tokenizeAndStringify(code1,false));
|
||
|
||
const char code2[] = "std::ostream & operator << (std::ostream & s, const Fred &f);";
|
||
const char result2[] = "std :: ostream & operator<< ( std :: ostream & s , const Fred & f ) ;";
|
||
ASSERT_EQUALS(result2, tokenizeAndStringify(code2,false));
|
||
}
|
||
|
||
void simplifyOperatorName6() { // ticket #3195
|
||
const char code1[] = "value_type * operator ++ (int);";
|
||
const char result1[] = "value_type * operator++ ( int ) ;";
|
||
ASSERT_EQUALS(result1, tokenizeAndStringify(code1,false));
|
||
|
||
const char code2[] = "value_type * operator -- (int);";
|
||
const char result2[] = "value_type * operator-- ( int ) ;";
|
||
ASSERT_EQUALS(result2, tokenizeAndStringify(code2,false));
|
||
}
|
||
|
||
void simplifyOperatorName7() { // ticket #4619
|
||
const char code1[] = "value_type * operator += (int);";
|
||
const char result1[] = "value_type * operator+= ( int ) ;";
|
||
ASSERT_EQUALS(result1, tokenizeAndStringify(code1,false));
|
||
}
|
||
|
||
void simplifyOperatorName8() { // ticket #5706
|
||
const char code1[] = "value_type * operator += (int) noexcept ;";
|
||
const char result1[] = "value_type * operator+= ( int ) noexcept ( true ) ;";
|
||
ASSERT_EQUALS(result1, tokenizeAndStringify(code1,false));
|
||
|
||
const char code2[] = "value_type * operator += (int) noexcept ( true ) ;";
|
||
const char result2[] = "value_type * operator+= ( int ) noexcept ( true ) ;";
|
||
ASSERT_EQUALS(result2, tokenizeAndStringify(code2,false));
|
||
|
||
const char code3[] = "value_type * operator += (int) throw ( ) ;";
|
||
const char result3[] = "value_type * operator+= ( int ) throw ( ) ;";
|
||
ASSERT_EQUALS(result3, tokenizeAndStringify(code3,false));
|
||
|
||
const char code4[] = "value_type * operator += (int) const noexcept ;";
|
||
const char result4[] = "value_type * operator+= ( int ) const noexcept ;";
|
||
ASSERT_EQUALS(result4, tokenizeAndStringify(code4,false));
|
||
|
||
const char code5[] = "value_type * operator += (int) const noexcept ( true ) ;";
|
||
const char result5[] = "value_type * operator+= ( int ) const noexcept ( true ) ;";
|
||
ASSERT_EQUALS(result5, tokenizeAndStringify(code5,false));
|
||
|
||
const char code6[] = "value_type * operator += (int) const throw ( ) ;";
|
||
const char result6[] = "value_type * operator+= ( int ) const throw ( ) ;";
|
||
ASSERT_EQUALS(result6, tokenizeAndStringify(code6,false));
|
||
|
||
const char code7[] = "value_type * operator += (int) const noexcept ( false ) ;";
|
||
const char result7[] = "value_type * operator+= ( int ) const noexcept ( false ) ;";
|
||
ASSERT_EQUALS(result7, tokenizeAndStringify(code7,false));
|
||
|
||
}
|
||
|
||
void simplifyOperatorName9() { // Ticket #5709
|
||
const char code[] = "struct R { R operator, ( R b ) ; } ;";
|
||
ASSERT_EQUALS(code, tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOperatorName10() { // #8746
|
||
const char code1[] = "using a::operator=;";
|
||
ASSERT_EQUALS("using a :: operator= ;", tokenizeAndStringify(code1));
|
||
|
||
const char code2[] = "{ return &Fred::operator!=; }";
|
||
ASSERT_EQUALS("{ return & Fred :: operator!= ; }", tokenizeAndStringify(code2));
|
||
}
|
||
|
||
void simplifyOperatorName11() { // #8889
|
||
const char code[] = "auto operator = (const Fred & other) -> Fred & ;";
|
||
ASSERT_EQUALS("auto operator= ( const Fred & other ) . Fred & ;", tokenizeAndStringify(code));
|
||
|
||
const char code1[] = "auto operator = (const Fred & other) -> Fred & { }";
|
||
ASSERT_EQUALS("auto operator= ( const Fred & other ) . Fred & { }", tokenizeAndStringify(code1));
|
||
|
||
const char code2[] = "template <typename T> void g(S<&T::operator+ >) {}";
|
||
ASSERT_EQUALS("template < typename T > void g ( S < & T :: operator+ > ) { }", tokenizeAndStringify(code2));
|
||
|
||
const char code3[] = "template <typename T> void g(S<&T::operator int>) {}";
|
||
ASSERT_EQUALS("template < typename T > void g ( S < & T :: operatorint > ) { }", tokenizeAndStringify(code3));
|
||
|
||
const char code4[] = "template <typename T> void g(S<&T::template operator- <double> >) {}";
|
||
ASSERT_EQUALS("template < typename T > void g ( S < & T :: template operator- < double > > ) { }", tokenizeAndStringify(code4));
|
||
}
|
||
|
||
void simplifyOperatorName12() { // #9110
|
||
const char code[] = "namespace a {"
|
||
"template <typename b> void operator+(b);"
|
||
"}"
|
||
"using a::operator+;";
|
||
ASSERT_EQUALS("namespace a { "
|
||
"template < typename b > void operator+ ( b ) ; "
|
||
"} "
|
||
"using a :: operator+ ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOperatorName13() { // user defined literal
|
||
const char code[] = "unsigned long operator\"\"_numch(const char *ch, unsigned long size);";
|
||
ASSERT_EQUALS("unsigned long operator\"\"_numch ( const char * ch , unsigned long size ) ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOperatorName14() { // std::complex operator "" if
|
||
{
|
||
const char code[] = "constexpr std::complex<float> operator\"\"if(long double __num);";
|
||
ASSERT_EQUALS("const std :: complex < float > operator\"\"if ( long double __num ) ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "constexpr std::complex<float> operator\"\"if(long double __num) { }";
|
||
ASSERT_EQUALS("const std :: complex < float > operator\"\"if ( long double __num ) { }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void simplifyOperatorName15() { // ticket #9468 syntaxError
|
||
const char code[] = "template <typename> struct a;"
|
||
"template <typename> struct b {"
|
||
" typedef char c;"
|
||
" operator c();"
|
||
"};"
|
||
"template <> struct a<char> : b<char> { using b::operator char; };";
|
||
ASSERT_EQUALS("struct a<char> ; template < typename > struct a ; "
|
||
"struct b<char> ; "
|
||
"struct a<char> : b<char> { using b :: operatorchar ; } ; struct b<char> { "
|
||
"operatorchar ( ) ; "
|
||
"} ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOperatorName16() { // ticket #9472
|
||
{
|
||
const char code[] = "class I : public A { iterator& operator++() override; };";
|
||
ASSERT_EQUALS("class I : public A { iterator & operator++ ( ) override ; } ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "class I : public A { iterator& operator++() override { } };";
|
||
ASSERT_EQUALS("class I : public A { iterator & operator++ ( ) override { } } ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void simplifyOperatorName17() {
|
||
{
|
||
const char code[] = "template <class a> void b(a c, a d) { c.operator>() == d; }";
|
||
ASSERT_EQUALS("template < class a > void b ( a c , a d ) { c . operator> ( ) == d ; }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "template <class a> void b(a c, a d) { c.operator>() == (d + 1); }";
|
||
ASSERT_EQUALS("template < class a > void b ( a c , a d ) { c . operator> ( ) == ( d + 1 ) ; }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "template <class a> void b(a c, a d) { c.operator<() == d; }";
|
||
ASSERT_EQUALS("template < class a > void b ( a c , a d ) { c . operator< ( ) == d ; }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "template <class a> void b(a c, a d) { c.operator>() == (d + 1); }";
|
||
ASSERT_EQUALS("template < class a > void b ( a c , a d ) { c . operator> ( ) == ( d + 1 ) ; }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "template <class a> void b(a c, a d) { c.operator++() == d; }";
|
||
ASSERT_EQUALS("template < class a > void b ( a c , a d ) { c . operator++ ( ) == d ; }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "template <class a> void b(a c, a d) { c.operator++() == (d + 1); }";
|
||
ASSERT_EQUALS("template < class a > void b ( a c , a d ) { c . operator++ ( ) == ( d + 1 ) ; }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void simplifyOperatorName18() { // global namespace
|
||
{
|
||
const char code[] = "struct Fred { operator std::string() const { return std::string(\"Fred\"); } };";
|
||
ASSERT_EQUALS("struct Fred { operatorstd::string ( ) const { return std :: string ( \"Fred\" ) ; } } ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "struct Fred { operator ::std::string() const { return ::std::string(\"Fred\"); } };";
|
||
ASSERT_EQUALS("struct Fred { operator::std::string ( ) const { return :: std :: string ( \"Fred\" ) ; } } ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void simplifyOperatorName19() {
|
||
const char code[] = "struct v {};"
|
||
"enum E { e };"
|
||
"struct s {"
|
||
" operator struct v() { return v(); };"
|
||
" operator enum E() { return e; }"
|
||
"};"
|
||
"void f() {"
|
||
" (void)&s::operator struct v;"
|
||
" (void)&s::operator enum E;"
|
||
"}";
|
||
ASSERT_EQUALS("struct v { } ; "
|
||
"enum E { e } ; "
|
||
"struct s { "
|
||
"operatorstructv ( ) { return v ( ) ; } ; "
|
||
"operatorenumE ( ) { return e ; } "
|
||
"} ; "
|
||
"void f ( ) { "
|
||
"( void ) & s :: operatorstructv ; "
|
||
"( void ) & s :: operatorenumE ; "
|
||
"}",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOperatorName20() {
|
||
const char code[] = "void operator \"\" _a(const char *);"
|
||
"namespace N {"
|
||
" using ::operator \"\" _a;"
|
||
" void operator \"\" _b(const char *);"
|
||
"}";
|
||
ASSERT_EQUALS("void operator\"\"_a ( const char * ) ; "
|
||
"namespace N { "
|
||
"using :: operator\"\"_a ; "
|
||
"void operator\"\"_b ( const char * ) ; "
|
||
"}",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOperatorName21() {
|
||
const char code[] = "template<char...> void operator \"\" _h() {}"
|
||
"template<> void operator \"\" _h<'a', 'b', 'c'>() {}"
|
||
"template void operator \"\" _h<'a', 'b', 'c', 'd'>();";
|
||
ASSERT_EQUALS("void operator\"\"_h<'a','b','c'> ( ) ; "
|
||
"void operator\"\"_h<'a','b','c','d'> ( ) ; "
|
||
"void operator\"\"_h<'a','b','c'> ( ) { } "
|
||
"void operator\"\"_h<'a','b','c','d'> ( ) { }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOperatorName22() {
|
||
const char code[] = "static RSLRelOp convertOperator(const Software::ComparisonOperator& op) {"
|
||
" if (op == &Software::operator==) return RSLEqual;"
|
||
"return RSLNotEqual;"
|
||
"}";
|
||
ASSERT_EQUALS("static RSLRelOp convertOperator ( const Software :: ComparisonOperator & op ) { "
|
||
"if ( op == & Software :: operator== ) { return RSLEqual ; } "
|
||
"return RSLNotEqual ; "
|
||
"}",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOperatorName23() {
|
||
{
|
||
const char code[] = "double *vtkMatrix3x3::operator[](const unsigned int i) {"
|
||
" VTK_LEGACY_BODY(vtkMatrix3x3::operator[], \"VTK 7.0\");"
|
||
" return &(this->Element[i][0]);"
|
||
"}";
|
||
ASSERT_EQUALS("double * vtkMatrix3x3 :: operator[] ( const unsigned int i ) { "
|
||
"VTK_LEGACY_BODY ( vtkMatrix3x3 :: operator[] , \"VTK 7.0\" ) ; "
|
||
"return & ( this . Element [ i ] [ 0 ] ) ; "
|
||
"}",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "double *vtkMatrix3x3::operator,(const unsigned int i) {"
|
||
" VTK_LEGACY_BODY(vtkMatrix3x3::operator,, \"VTK 7.0\");"
|
||
" return &(this->Element[i][0]);"
|
||
"}";
|
||
ASSERT_EQUALS("double * vtkMatrix3x3 :: operator, ( const unsigned int i ) { "
|
||
"VTK_LEGACY_BODY ( vtkMatrix3x3 :: operator, , \"VTK 7.0\" ) ; "
|
||
"return & ( this . Element [ i ] [ 0 ] ) ; "
|
||
"}",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void simplifyOperatorName24() {
|
||
{
|
||
const char code[] = "void foo() { int i = a.operator++() ? a.operator--() : 0; }";
|
||
ASSERT_EQUALS("void foo ( ) { int i ; i = a . operator++ ( ) ? a . operator-- ( ) : 0 ; }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
{
|
||
const char code[] = "void foo() { int i = a.operator++(0) ? a.operator--(0) : 0; }";
|
||
ASSERT_EQUALS("void foo ( ) { int i ; i = a . operator++ ( 0 ) ? a . operator-- ( 0 ) : 0 ; }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
}
|
||
|
||
void simplifyOperatorName25() {
|
||
const char code[] = "bool negative(const Number &num) { return num.operator std::string()[0] == '-'; }";
|
||
ASSERT_EQUALS("bool negative ( const Number & num ) { return num . operatorstd::string ( ) [ 0 ] == '-' ; }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOperatorName26() {
|
||
const char code[] = "void foo() {"
|
||
" x = y.operator *().z[123];"
|
||
"}";
|
||
ASSERT_EQUALS("void foo ( ) { x = y . operator* ( ) . z [ 123 ] ; }",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOperatorName27() {
|
||
const char code[] = "int operator \"\" i (const char *, int);\n"
|
||
"x = \"abc\"i;";
|
||
ASSERT_EQUALS("int operator\"\"i ( const char * , int ) ;\n"
|
||
"x = operator\"\"i ( \"abc\" , 3 ) ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOverloadedOperators1() {
|
||
const char code[] = "struct S { void operator()(int); };\n"
|
||
"\n"
|
||
"void foo(S x) {\n"
|
||
" x(123);\n"
|
||
"}";
|
||
ASSERT_EQUALS("struct S { void operator() ( int ) ; } ;\n"
|
||
"\n"
|
||
"void foo ( S x ) {\n"
|
||
"x . operator() ( 123 ) ;\n"
|
||
"}",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOverloadedOperators2() { // #9879 - (*this)(123);
|
||
const char code[] = "struct S {\n"
|
||
" void operator()(int);\n"
|
||
" void foo() { (*this)(123); }\n"
|
||
"};\n";
|
||
ASSERT_EQUALS("struct S {\n"
|
||
"void operator() ( int ) ;\n"
|
||
"void foo ( ) { ( * this ) . operator() ( 123 ) ; }\n"
|
||
"} ;",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyOverloadedOperators3() { // #9881
|
||
const char code[] = "struct Func { double operator()(double x) const; };\n"
|
||
"void foo(double, double);\n"
|
||
"void test() {\n"
|
||
" Func max;\n"
|
||
" double y = 0;\n"
|
||
" foo(0, max(y));\n"
|
||
"}";
|
||
ASSERT_EQUALS("struct Func { double operator() ( double x ) const ; } ;\n"
|
||
"void foo ( double , double ) ;\n"
|
||
"void test ( ) {\n"
|
||
"Func max ;\n"
|
||
"double y ; y = 0 ;\n"
|
||
"foo ( 0 , max . operator() ( y ) ) ;\n"
|
||
"}",
|
||
tokenizeAndStringify(code));
|
||
}
|
||
|
||
void simplifyNullArray() {
|
||
ASSERT_EQUALS("* ( foo . bar [ 5 ] ) = x ;", tokenizeAndStringify("0[foo.bar[5]] = x;"));
|
||
}
|
||
|
||
void removeMacrosInGlobalScope() {
|
||
// remove some unhandled macros in the global scope.
|
||
ASSERT_EQUALS("void f ( ) { }", tokenizeAndStringify("void f() NOTHROW { }"));
|
||
ASSERT_EQUALS("struct Foo { } ;", tokenizeAndStringify("struct __declspec(dllexport) Foo {};"));
|
||
ASSERT_EQUALS("namespace { int a ; }", tokenizeAndStringify("ABA() namespace { int a ; }"));
|
||
|
||
// #3750
|
||
ASSERT_THROW(tokenizeAndStringify("; AB(foo*) foo::foo() { }"), InternalError);
|
||
|
||
// #4834 - syntax error
|
||
ASSERT_THROW(tokenizeAndStringify("A(B) foo() {}"), InternalError);
|
||
|
||
// #3855
|
||
ASSERT_EQUALS("; class foo { }",
|
||
tokenizeAndStringify("; AB class foo { }"));
|
||
ASSERT_EQUALS("; CONST struct ABC abc ;",
|
||
tokenizeAndStringify("; CONST struct ABC abc ;"));
|
||
|
||
ASSERT_NO_THROW(tokenizeAndStringify("class A {\n"
|
||
" UNKNOWN_MACRO(A)\n" // <- this macro is ignored
|
||
"private:\n"
|
||
" int x;\n"
|
||
"};"));
|
||
|
||
ASSERT_THROW(tokenizeAndStringify("MACRO(test) void test() { }"), InternalError); // #7931
|
||
|
||
ASSERT_THROW(tokenizeAndStringify("BEGIN_MESSAGE_MAP(CSetProgsAdvDlg, CResizableStandAloneDialog)\n"
|
||
" ON_BN_CLICKED(IDC_ADDTOOL, OnBnClickedAddtool)\n"
|
||
"END_MESSAGE_MAP()\n"
|
||
"\n"
|
||
"BOOL CSetProgsAdvDlg::OnInitDialog() {}"),
|
||
InternalError);
|
||
}
|
||
|
||
void removeMacroInVarDecl() { // #4304
|
||
// only remove macros with parentheses (those hurt most)
|
||
ASSERT_EQUALS("void f ( ) { PROGMEM int x ; }", tokenizeAndStringify("void f() { PROGMEM int x ; }"));
|
||
ASSERT_EQUALS("void f ( ) { int x ; }", tokenizeAndStringify("void f() { SECTION(\".data.ro\") int x ; }"));
|
||
|
||
// various variable declarations
|
||
ASSERT_EQUALS("void f ( ) { CONST int x ; }", tokenizeAndStringify("void f() { SECTION(\".data.ro\") CONST int x ; }"));
|
||
ASSERT_EQUALS("void f ( ) { char a [ 4 ] ; }", tokenizeAndStringify("void f() { SECTION(\".data.ro\") char a[4]; }"));
|
||
ASSERT_EQUALS("void f ( ) { const char a [ 4 ] ; }", tokenizeAndStringify("void f() { SECTION(\".data.ro\") const char a[4]; }"));
|
||
ASSERT_EQUALS("void f ( ) { struct ABC abc ; }", tokenizeAndStringify("void f() { SECTION(\".data.ro\") struct ABC abc; }"));
|
||
ASSERT_EQUALS("void f ( ) { CONST struct ABC abc ; }", tokenizeAndStringify("void f() { SECTION(\".data.ro\") CONST struct ABC abc; }"));
|
||
}
|
||
|
||
void addSemicolonAfterUnknownMacro() {
|
||
// #6975
|
||
ASSERT_EQUALS("void f ( ) { MACRO ( ) ; try { } }", tokenizeAndStringify("void f() { MACRO() try {} }"));
|
||
// #9376
|
||
ASSERT_EQUALS("MACRO ( ) ; using namespace foo ;", tokenizeAndStringify("MACRO() using namespace foo;"));
|
||
}
|
||
|
||
void multipleAssignment() {
|
||
ASSERT_EQUALS("a = b = 0 ;", tokenizeAndStringify("a=b=0;"));
|
||
}
|
||
|
||
void sizeOfCharLiteral() { // #7490 sizeof('a') should be 4 in C mode
|
||
std::stringstream expected;
|
||
expected << "unsigned long a ; a = " << settings1.sizeof_int << " ;";
|
||
ASSERT_EQUALS(expected.str(),
|
||
tokenizeAndStringify("unsigned long a = sizeof('x');", true, true, Settings::Native, "test.c", false));
|
||
ASSERT_EQUALS("unsigned long a ; a = 1 ;",
|
||
tokenizeAndStringify("unsigned long a = sizeof('x');", true, true, Settings::Native, "test.cpp", true));
|
||
}
|
||
|
||
void platformWin() {
|
||
const char code[] = "BOOL f;"
|
||
"BOOLEAN g;"
|
||
"BYTE h;"
|
||
"CHAR i;"
|
||
"DWORD j;"
|
||
"FLOAT k;"
|
||
"INT l;"
|
||
"INT32 m;"
|
||
"INT64 n;"
|
||
"LONG o;"
|
||
"SHORT p;"
|
||
"UCHAR q;"
|
||
"UINT r;"
|
||
"ULONG s;"
|
||
"USHORT t;"
|
||
"WORD u;"
|
||
"VOID *v;"
|
||
"LPBOOL w;"
|
||
"PBOOL x;"
|
||
"LPBYTE y;"
|
||
"PBOOLEAN z;"
|
||
"PBYTE A;"
|
||
"LPCSTR B;"
|
||
"PCSTR C;"
|
||
"LPCVOID D;"
|
||
"LPDWORD E;"
|
||
"LPINT F;"
|
||
"PINT G;"
|
||
"LPLONG H;"
|
||
"PLONG I;"
|
||
"LPSTR J;"
|
||
"PSTR K;"
|
||
"PCHAR L;"
|
||
"LPVOID M;"
|
||
"PVOID N;"
|
||
"BOOL _bool;"
|
||
"HFILE hfile;"
|
||
"LONG32 long32;"
|
||
"LCID lcid;"
|
||
"LCTYPE lctype;"
|
||
"LGRPID lgrpid;"
|
||
"LONG64 long64;"
|
||
"PUCHAR puchar;"
|
||
"LPCOLORREF lpcolorref;"
|
||
"PDWORD pdword;"
|
||
"PULONG pulong;"
|
||
"SERVICE_STATUS_HANDLE service_status_hanlde;"
|
||
"SC_LOCK sc_lock;"
|
||
"SC_HANDLE sc_handle;"
|
||
"HACCEL haccel;"
|
||
"HCONV hconv;"
|
||
"HCONVLIST hconvlist;"
|
||
"HDDEDATA hddedata;"
|
||
"HDESK hdesk;"
|
||
"HDROP hdrop;"
|
||
"HDWP hdwp;"
|
||
"HENHMETAFILE henhmetafile;"
|
||
"HHOOK hhook;"
|
||
"HKL hkl;"
|
||
"HMONITOR hmonitor;"
|
||
"HSZ hsz;"
|
||
"HWINSTA hwinsta;"
|
||
"PWCHAR pwchar;"
|
||
"PUSHORT pushort;"
|
||
"LANGID langid;"
|
||
"DWORD64 dword64;"
|
||
"ULONG64 ulong64;"
|
||
"LPWSTR lpcwstr;"
|
||
"LPCWSTR lpcwstr;"
|
||
"LPHANDLE lpHandle;"
|
||
"PCWSTR pcwStr;"
|
||
"PDWORDLONG pdWordLong;"
|
||
"PDWORD_PTR pdWordPtr;"
|
||
"PDWORD32 pdWord32;"
|
||
"PDWORD64 pdWord64;"
|
||
"LONGLONG ll;"
|
||
"USN usn;"
|
||
"PULONG64 puLong64;"
|
||
"PULONG32 puLong32;"
|
||
"PFLOAT ptrToFloat;";
|
||
|
||
const char expected[] = "int f ; "
|
||
"unsigned char g ; "
|
||
"unsigned char h ; "
|
||
"char i ; "
|
||
"unsigned long j ; "
|
||
"float k ; "
|
||
"int l ; "
|
||
"int m ; "
|
||
"long long n ; "
|
||
"long o ; "
|
||
"short p ; "
|
||
"unsigned char q ; "
|
||
"unsigned int r ; "
|
||
"unsigned long s ; "
|
||
"unsigned short t ; "
|
||
"unsigned short u ; "
|
||
"void * v ; "
|
||
"int * w ; "
|
||
"int * x ; "
|
||
"unsigned char * y ; "
|
||
"unsigned char * z ; "
|
||
"unsigned char * A ; "
|
||
"const char * B ; "
|
||
"const char * C ; "
|
||
"const void * D ; "
|
||
"unsigned long * E ; "
|
||
"int * F ; "
|
||
"int * G ; "
|
||
"long * H ; "
|
||
"long * I ; "
|
||
"char * J ; "
|
||
"char * K ; "
|
||
"char * L ; "
|
||
"void * M ; "
|
||
"void * N ; "
|
||
"int _bool ; "
|
||
"int hfile ; "
|
||
"int long32 ; "
|
||
"unsigned long lcid ; "
|
||
"unsigned long lctype ; "
|
||
"unsigned long lgrpid ; "
|
||
"long long long64 ; "
|
||
"unsigned char * puchar ; "
|
||
"unsigned long * lpcolorref ; "
|
||
"unsigned long * pdword ; "
|
||
"unsigned long * pulong ; "
|
||
"void * service_status_hanlde ; "
|
||
"void * sc_lock ; "
|
||
"void * sc_handle ; "
|
||
"void * haccel ; "
|
||
"void * hconv ; "
|
||
"void * hconvlist ; "
|
||
"void * hddedata ; "
|
||
"void * hdesk ; "
|
||
"void * hdrop ; "
|
||
"void * hdwp ; "
|
||
"void * henhmetafile ; "
|
||
"void * hhook ; "
|
||
"void * hkl ; "
|
||
"void * hmonitor ; "
|
||
"void * hsz ; "
|
||
"void * hwinsta ; "
|
||
"wchar_t * pwchar ; "
|
||
"unsigned short * pushort ; "
|
||
"unsigned short langid ; "
|
||
"unsigned long long dword64 ; "
|
||
"unsigned long long ulong64 ; "
|
||
"wchar_t * lpcwstr ; "
|
||
"const wchar_t * lpcwstr ; "
|
||
"void * lpHandle ; "
|
||
"const wchar_t * pcwStr ; "
|
||
"long * pdWordLong ; "
|
||
"long * pdWordPtr ; "
|
||
"unsigned int * pdWord32 ; "
|
||
"unsigned long * pdWord64 ; "
|
||
"long long ll ; "
|
||
"long long usn ; "
|
||
"unsigned long long * puLong64 ; "
|
||
"unsigned int * puLong32 ; "
|
||
"float * ptrToFloat ;";
|
||
|
||
// These types should be defined the same on all Windows platforms
|
||
const std::string win32A = tokenizeAndStringifyWindows(code, true, true, Settings::Win32A);
|
||
ASSERT_EQUALS(expected, win32A);
|
||
ASSERT_EQUALS(win32A, tokenizeAndStringifyWindows(code, true, true, Settings::Win32W));
|
||
ASSERT_EQUALS(win32A, tokenizeAndStringifyWindows(code, true, true, Settings::Win64));
|
||
}
|
||
|
||
void platformWin32() {
|
||
const char code[] = "unsigned int sizeof_short = sizeof(short);"
|
||
"unsigned int sizeof_unsigned_short = sizeof(unsigned short);"
|
||
"unsigned int sizeof_int = sizeof(int);"
|
||
"unsigned int sizeof_unsigned_int = sizeof(unsigned int);"
|
||
"unsigned int sizeof_long = sizeof(long);"
|
||
"unsigned int sizeof_unsigned_long = sizeof(unsigned long);"
|
||
"unsigned int sizeof_long_long = sizeof(long long);"
|
||
"unsigned int sizeof_unsigned_long_long = sizeof(unsigned long long);"
|
||
"unsigned int sizeof_float = sizeof(float);"
|
||
"unsigned int sizeof_double = sizeof(double);"
|
||
"unsigned int sizeof_long_double = sizeof(long double);"
|
||
"unsigned int sizeof_bool = sizeof(bool);"
|
||
"unsigned int sizeof_wchar_t = sizeof(wchar_t);"
|
||
"unsigned int sizeof_pointer = sizeof(void *);"
|
||
"unsigned int sizeof_size_t = sizeof(size_t);"
|
||
"size_t a;"
|
||
"ssize_t b;"
|
||
"ptrdiff_t c;"
|
||
"intptr_t d;"
|
||
"uintptr_t e;"
|
||
"DWORD_PTR O;"
|
||
"ULONG_PTR P;"
|
||
"SIZE_T Q;"
|
||
"HRESULT R;"
|
||
"LONG_PTR S;"
|
||
"HANDLE T;"
|
||
"PHANDLE U;"
|
||
"SSIZE_T _ssize_t;"
|
||
"UINT_PTR uint_ptr;"
|
||
"WPARAM wparam;"
|
||
"HALF_PTR half_ptr;"
|
||
"INT_PTR int_ptr;";
|
||
|
||
const char expected[] = "unsigned int sizeof_short ; sizeof_short = 2 ; "
|
||
"unsigned int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; "
|
||
"unsigned int sizeof_int ; sizeof_int = 4 ; "
|
||
"unsigned int sizeof_unsigned_int ; sizeof_unsigned_int = 4 ; "
|
||
"unsigned int sizeof_long ; sizeof_long = 4 ; "
|
||
"unsigned int sizeof_unsigned_long ; sizeof_unsigned_long = 4 ; "
|
||
"unsigned int sizeof_long_long ; sizeof_long_long = 8 ; "
|
||
"unsigned int sizeof_unsigned_long_long ; sizeof_unsigned_long_long = 8 ; "
|
||
"unsigned int sizeof_float ; sizeof_float = 4 ; "
|
||
"unsigned int sizeof_double ; sizeof_double = 8 ; "
|
||
"unsigned int sizeof_long_double ; sizeof_long_double = 8 ; "
|
||
"unsigned int sizeof_bool ; sizeof_bool = 1 ; "
|
||
"unsigned int sizeof_wchar_t ; sizeof_wchar_t = 2 ; "
|
||
"unsigned int sizeof_pointer ; sizeof_pointer = 4 ; "
|
||
"unsigned int sizeof_size_t ; sizeof_size_t = 4 ; "
|
||
"unsigned long a ; "
|
||
"long b ; "
|
||
"long c ; "
|
||
"long d ; "
|
||
"unsigned long e ; "
|
||
"unsigned long O ; "
|
||
"unsigned long P ; "
|
||
"unsigned long Q ; "
|
||
"long R ; "
|
||
"long S ; "
|
||
"void * T ; "
|
||
"void * * U ; "
|
||
"long _ssize_t ; "
|
||
"unsigned int uint_ptr ; "
|
||
"unsigned int wparam ; "
|
||
"short half_ptr ; "
|
||
"int int_ptr ;";
|
||
|
||
// These types should be defined the same on all Win32 platforms
|
||
std::string win32A = tokenizeAndStringifyWindows(code, true, true, Settings::Win32A);
|
||
ASSERT_EQUALS(expected, win32A);
|
||
ASSERT_EQUALS(win32A, tokenizeAndStringifyWindows(code, true, true, Settings::Win32W));
|
||
}
|
||
|
||
void platformWin32A() {
|
||
const char code[] = "wchar_t wc;"
|
||
"TCHAR c;"
|
||
"PTSTR ptstr;"
|
||
"LPTSTR lptstr;"
|
||
"PCTSTR pctstr;"
|
||
"LPCTSTR lpctstr;"
|
||
"void foo() {"
|
||
" TCHAR tc = _T(\'c\'); "
|
||
" TCHAR src[10] = _T(\"123456789\");"
|
||
" TCHAR dst[10];"
|
||
" _tcscpy(dst, src);"
|
||
" dst[0] = 0;"
|
||
" _tcscat(dst, src);"
|
||
" LPTSTR d = _tcsdup(str);"
|
||
" _tprintf(_T(\"Hello world!\"));"
|
||
" _stprintf(dst, _T(\"Hello!\"));"
|
||
" _sntprintf(dst, sizeof(dst) / sizeof(TCHAR), _T(\"Hello world!\"));"
|
||
" _tscanf(_T(\"%s\"), dst);"
|
||
" _stscanf(dst, _T(\"%s\"), dst);"
|
||
"}"
|
||
"TBYTE tbyte;";
|
||
const char expected[] = "wchar_t wc ; "
|
||
"char c ; "
|
||
"char * ptstr ; "
|
||
"char * lptstr ; "
|
||
"const char * pctstr ; "
|
||
"const char * lpctstr ; "
|
||
"void foo ( ) { "
|
||
"char tc ; tc = \'c\' ; "
|
||
"char src [ 10 ] = \"123456789\" ; "
|
||
"char dst [ 10 ] ; "
|
||
"strcpy ( dst , src ) ; "
|
||
"dst [ 0 ] = 0 ; "
|
||
"strcat ( dst , src ) ; "
|
||
"char * d ; d = strdup ( str ) ; "
|
||
"printf ( \"Hello world!\" ) ; "
|
||
"sprintf ( dst , \"Hello!\" ) ; "
|
||
"_snprintf ( dst , sizeof ( dst ) / sizeof ( char ) , \"Hello world!\" ) ; "
|
||
"scanf ( \"%s\" , dst ) ; "
|
||
"sscanf ( dst , \"%s\" , dst ) ; "
|
||
"} "
|
||
"unsigned char tbyte ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringifyWindows(code, false, true, Settings::Win32A));
|
||
}
|
||
|
||
void platformWin32W() {
|
||
const char code[] = "wchar_t wc;"
|
||
"TCHAR c;"
|
||
"PTSTR ptstr;"
|
||
"LPTSTR lptstr;"
|
||
"PCTSTR pctstr;"
|
||
"LPCTSTR lpctstr;"
|
||
"TBYTE tbyte;"
|
||
"void foo() {"
|
||
" TCHAR tc = _T(\'c\');"
|
||
" TCHAR src[10] = _T(\"123456789\");"
|
||
" TCHAR dst[10];"
|
||
" _tcscpy(dst, src);"
|
||
" dst[0] = 0;"
|
||
" _tcscat(dst, src);"
|
||
" LPTSTR d = _tcsdup(str);"
|
||
" _tprintf(_T(\"Hello world!\"));"
|
||
" _stprintf(dst, _T(\"Hello!\"));"
|
||
" _sntprintf(dst, sizeof(dst) / sizeof(TCHAR), _T(\"Hello world!\"));"
|
||
" _tscanf(_T(\"%s\"), dst);"
|
||
" _stscanf(dst, _T(\"%s\"), dst);"
|
||
"}";
|
||
const char expected[] = "wchar_t wc ; "
|
||
"wchar_t c ; "
|
||
"wchar_t * ptstr ; "
|
||
"wchar_t * lptstr ; "
|
||
"const wchar_t * pctstr ; "
|
||
"const wchar_t * lpctstr ; "
|
||
"unsigned wchar_t tbyte ; "
|
||
"void foo ( ) { "
|
||
"wchar_t tc ; tc = L\'c\' ; "
|
||
"wchar_t src [ 10 ] = L\"123456789\" ; "
|
||
"wchar_t dst [ 10 ] ; "
|
||
"wcscpy ( dst , src ) ; "
|
||
"dst [ 0 ] = 0 ; "
|
||
"wcscat ( dst , src ) ; "
|
||
"wchar_t * d ; d = wcsdup ( str ) ; "
|
||
"wprintf ( L\"Hello world!\" ) ; "
|
||
"swprintf ( dst , L\"Hello!\" ) ; "
|
||
"_snwprintf ( dst , sizeof ( dst ) / sizeof ( wchar_t ) , L\"Hello world!\" ) ; "
|
||
"wscanf ( L\"%s\" , dst ) ; "
|
||
"swscanf ( dst , L\"%s\" , dst ) ; "
|
||
"}";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringifyWindows(code, false, true, Settings::Win32W));
|
||
}
|
||
|
||
void platformWin64() {
|
||
const char code[] = "unsigned int sizeof_short = sizeof(short);"
|
||
"unsigned int sizeof_unsigned_short = sizeof(unsigned short);"
|
||
"unsigned int sizeof_int = sizeof(int);"
|
||
"unsigned int sizeof_unsigned_int = sizeof(unsigned int);"
|
||
"unsigned int sizeof_long = sizeof(long);"
|
||
"unsigned int sizeof_unsigned_long = sizeof(unsigned long);"
|
||
"unsigned int sizeof_long_long = sizeof(long long);"
|
||
"unsigned int sizeof_unsigned_long_long = sizeof(unsigned long long);"
|
||
"unsigned int sizeof_float = sizeof(float);"
|
||
"unsigned int sizeof_double = sizeof(double);"
|
||
"unsigned int sizeof_long_double = sizeof(long double);"
|
||
"unsigned int sizeof_bool = sizeof(bool);"
|
||
"unsigned int sizeof_wchar_t = sizeof(wchar_t);"
|
||
"unsigned int sizeof_pointer = sizeof(void *);"
|
||
"unsigned int sizeof_size_t = sizeof(size_t);"
|
||
"size_t a;"
|
||
"ssize_t b;"
|
||
"ptrdiff_t c;"
|
||
"intptr_t d;"
|
||
"uintptr_t e;"
|
||
"DWORD_PTR O;"
|
||
"ULONG_PTR P;"
|
||
"SIZE_T Q;"
|
||
"HRESULT R;"
|
||
"LONG_PTR S;"
|
||
"HANDLE T;"
|
||
"PHANDLE U;"
|
||
"SSIZE_T _ssize_t;"
|
||
"UINT_PTR uint_ptr;"
|
||
"WPARAM wparam;"
|
||
"HALF_PTR half_ptr;"
|
||
"INT_PTR int_ptr;";
|
||
|
||
const char expected[] = "unsigned int sizeof_short ; sizeof_short = 2 ; "
|
||
"unsigned int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; "
|
||
"unsigned int sizeof_int ; sizeof_int = 4 ; "
|
||
"unsigned int sizeof_unsigned_int ; sizeof_unsigned_int = 4 ; "
|
||
"unsigned int sizeof_long ; sizeof_long = 4 ; "
|
||
"unsigned int sizeof_unsigned_long ; sizeof_unsigned_long = 4 ; "
|
||
"unsigned int sizeof_long_long ; sizeof_long_long = 8 ; "
|
||
"unsigned int sizeof_unsigned_long_long ; sizeof_unsigned_long_long = 8 ; "
|
||
"unsigned int sizeof_float ; sizeof_float = 4 ; "
|
||
"unsigned int sizeof_double ; sizeof_double = 8 ; "
|
||
"unsigned int sizeof_long_double ; sizeof_long_double = 8 ; "
|
||
"unsigned int sizeof_bool ; sizeof_bool = 1 ; "
|
||
"unsigned int sizeof_wchar_t ; sizeof_wchar_t = 2 ; "
|
||
"unsigned int sizeof_pointer ; sizeof_pointer = 8 ; "
|
||
"unsigned int sizeof_size_t ; sizeof_size_t = 8 ; "
|
||
"unsigned long long a ; "
|
||
"long long b ; "
|
||
"long long c ; "
|
||
"long long d ; "
|
||
"unsigned long long e ; "
|
||
"unsigned long long O ; "
|
||
"unsigned long long P ; "
|
||
"unsigned long long Q ; "
|
||
"long R ; "
|
||
"long long S ; "
|
||
"void * T ; "
|
||
"void * * U ; "
|
||
"long long _ssize_t ; "
|
||
"unsigned long long uint_ptr ; "
|
||
"unsigned long long wparam ; "
|
||
"int half_ptr ; "
|
||
"long long int_ptr ;";
|
||
|
||
ASSERT_EQUALS(expected, tokenizeAndStringifyWindows(code, true, true, Settings::Win64));
|
||
}
|
||
|
||
void platformUnix32() {
|
||
const char code[] = "unsigned int sizeof_short = sizeof(short);"
|
||
"unsigned int sizeof_unsigned_short = sizeof(unsigned short);"
|
||
"unsigned int sizeof_int = sizeof(int);"
|
||
"unsigned int sizeof_unsigned_int = sizeof(unsigned int);"
|
||
"unsigned int sizeof_long = sizeof(long);"
|
||
"unsigned int sizeof_unsigned_long = sizeof(unsigned long);"
|
||
"unsigned int sizeof_long_long = sizeof(long long);"
|
||
"unsigned int sizeof_unsigned_long_long = sizeof(unsigned long long);"
|
||
"unsigned int sizeof_float = sizeof(float);"
|
||
"unsigned int sizeof_double = sizeof(double);"
|
||
"unsigned int sizeof_long_double = sizeof(long double);"
|
||
"unsigned int sizeof_bool = sizeof(bool);"
|
||
"unsigned int sizeof_wchar_t = sizeof(wchar_t);"
|
||
"unsigned int sizeof_pointer = sizeof(void *);"
|
||
"unsigned int sizeof_size_t = sizeof(size_t);"
|
||
"size_t a;"
|
||
"ssize_t b;"
|
||
"ptrdiff_t c;"
|
||
"intptr_t d;"
|
||
"uintptr_t e;";
|
||
|
||
const char expected[] = "unsigned int sizeof_short ; sizeof_short = 2 ; "
|
||
"unsigned int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; "
|
||
"unsigned int sizeof_int ; sizeof_int = 4 ; "
|
||
"unsigned int sizeof_unsigned_int ; sizeof_unsigned_int = 4 ; "
|
||
"unsigned int sizeof_long ; sizeof_long = 4 ; "
|
||
"unsigned int sizeof_unsigned_long ; sizeof_unsigned_long = 4 ; "
|
||
"unsigned int sizeof_long_long ; sizeof_long_long = 8 ; "
|
||
"unsigned int sizeof_unsigned_long_long ; sizeof_unsigned_long_long = 8 ; "
|
||
"unsigned int sizeof_float ; sizeof_float = 4 ; "
|
||
"unsigned int sizeof_double ; sizeof_double = 8 ; "
|
||
"unsigned int sizeof_long_double ; sizeof_long_double = 12 ; "
|
||
"unsigned int sizeof_bool ; sizeof_bool = 1 ; "
|
||
"unsigned int sizeof_wchar_t ; sizeof_wchar_t = 4 ; "
|
||
"unsigned int sizeof_pointer ; sizeof_pointer = 4 ; "
|
||
"unsigned int sizeof_size_t ; sizeof_size_t = 4 ; "
|
||
"unsigned long a ; "
|
||
"long b ; "
|
||
"long c ; "
|
||
"long d ; "
|
||
"unsigned long e ;";
|
||
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Unix32));
|
||
}
|
||
|
||
void platformUnix64() {
|
||
const char code[] = "unsigned int sizeof_short = sizeof(short);"
|
||
"unsigned int sizeof_unsigned_short = sizeof(unsigned short);"
|
||
"unsigned int sizeof_int = sizeof(int);"
|
||
"unsigned int sizeof_unsigned_int = sizeof(unsigned int);"
|
||
"unsigned int sizeof_long = sizeof(long);"
|
||
"unsigned int sizeof_unsigned_long = sizeof(unsigned long);"
|
||
"unsigned int sizeof_long_long = sizeof(long long);"
|
||
"unsigned int sizeof_unsigned_long_long = sizeof(unsigned long long);"
|
||
"unsigned int sizeof_float = sizeof(float);"
|
||
"unsigned int sizeof_double = sizeof(double);"
|
||
"unsigned int sizeof_long_double = sizeof(long double);"
|
||
"unsigned int sizeof_bool = sizeof(bool);"
|
||
"unsigned int sizeof_wchar_t = sizeof(wchar_t);"
|
||
"unsigned int sizeof_pointer = sizeof(void *);"
|
||
"unsigned int sizeof_size_t = sizeof(size_t);"
|
||
"size_t a;"
|
||
"ssize_t b;"
|
||
"ptrdiff_t c;"
|
||
"intptr_t d;"
|
||
"uintptr_t e;";
|
||
|
||
const char expected[] = "unsigned int sizeof_short ; sizeof_short = 2 ; "
|
||
"unsigned int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; "
|
||
"unsigned int sizeof_int ; sizeof_int = 4 ; "
|
||
"unsigned int sizeof_unsigned_int ; sizeof_unsigned_int = 4 ; "
|
||
"unsigned int sizeof_long ; sizeof_long = 8 ; "
|
||
"unsigned int sizeof_unsigned_long ; sizeof_unsigned_long = 8 ; "
|
||
"unsigned int sizeof_long_long ; sizeof_long_long = 8 ; "
|
||
"unsigned int sizeof_unsigned_long_long ; sizeof_unsigned_long_long = 8 ; "
|
||
"unsigned int sizeof_float ; sizeof_float = 4 ; "
|
||
"unsigned int sizeof_double ; sizeof_double = 8 ; "
|
||
"unsigned int sizeof_long_double ; sizeof_long_double = 16 ; "
|
||
"unsigned int sizeof_bool ; sizeof_bool = 1 ; "
|
||
"unsigned int sizeof_wchar_t ; sizeof_wchar_t = 4 ; "
|
||
"unsigned int sizeof_pointer ; sizeof_pointer = 8 ; "
|
||
"unsigned int sizeof_size_t ; sizeof_size_t = 8 ; "
|
||
"unsigned long a ; "
|
||
"long b ; "
|
||
"long c ; "
|
||
"long d ; "
|
||
"unsigned long e ;";
|
||
|
||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Unix64));
|
||
}
|
||
|
||
void platformWin32AStringCat() { //#5150
|
||
const char code[] = "TCHAR text[] = _T(\"123\") _T(\"456\") _T(\"789\");";
|
||
const char expected[] = "char text [ 10 ] = \"123456789\" ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringifyWindows(code, true, true, Settings::Win32A));
|
||
}
|
||
|
||
void platformWin32WStringCat() { //#5150
|
||
const char code[] = "TCHAR text[] = _T(\"123\") _T(\"456\") _T(\"789\");";
|
||
const char expected[] = "wchar_t text [ 10 ] = L\"123456789\" ;";
|
||
ASSERT_EQUALS(expected, tokenizeAndStringifyWindows(code, true, true, Settings::Win32W));
|
||
}
|
||
|
||
void platformWinWithNamespace() {
|
||
const char code1[] = "UINT32 a; ::UINT32 b; foo::UINT32 c;";
|
||
const char expected1[] = "unsigned int a ; unsigned int b ; foo :: UINT32 c ;";
|
||
ASSERT_EQUALS(expected1, tokenizeAndStringifyWindows(code1, true, true, Settings::Win32A));
|
||
|
||
const char code2[] = "LPCVOID a; ::LPCVOID b; foo::LPCVOID c;";
|
||
const char expected2[] = "const void * a ; const void * b ; foo :: LPCVOID c ;";
|
||
ASSERT_EQUALS(expected2, tokenizeAndStringifyWindows(code2, true, true, Settings::Win32A));
|
||
}
|
||
|
||
void isZeroNumber() const {
|
||
ASSERT_EQUALS(true, Tokenizer::isZeroNumber("0.0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isZeroNumber("+0.0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isZeroNumber("-0.0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isZeroNumber("+0L"));
|
||
ASSERT_EQUALS(true, Tokenizer::isZeroNumber("+0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isZeroNumber("-0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isZeroNumber("-0E+0"));
|
||
|
||
ASSERT_EQUALS(false, Tokenizer::isZeroNumber("1.0"));
|
||
ASSERT_EQUALS(false, Tokenizer::isZeroNumber("+1.0"));
|
||
ASSERT_EQUALS(false, Tokenizer::isZeroNumber("-1"));
|
||
ASSERT_EQUALS(false, Tokenizer::isZeroNumber(""));
|
||
ASSERT_EQUALS(false, Tokenizer::isZeroNumber("garbage"));
|
||
ASSERT_EQUALS(false, Tokenizer::isZeroNumber("E2"));
|
||
ASSERT_EQUALS(false, Tokenizer::isZeroNumber("2e"));
|
||
}
|
||
|
||
void isOneNumber() const {
|
||
ASSERT_EQUALS(true, Tokenizer::isOneNumber("1.0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isOneNumber("+1.0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isOneNumber("1.0e+0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isOneNumber("+1L"));
|
||
ASSERT_EQUALS(true, Tokenizer::isOneNumber("+1"));
|
||
ASSERT_EQUALS(true, Tokenizer::isOneNumber("1"));
|
||
ASSERT_EQUALS(true, Tokenizer::isOneNumber("+1E+0"));
|
||
|
||
ASSERT_EQUALS(false, Tokenizer::isOneNumber("0.0"));
|
||
ASSERT_EQUALS(false, Tokenizer::isOneNumber("+0.0"));
|
||
ASSERT_EQUALS(false, Tokenizer::isOneNumber("-0"));
|
||
ASSERT_EQUALS(false, Tokenizer::isOneNumber(""));
|
||
ASSERT_EQUALS(false, Tokenizer::isOneNumber("garbage"));
|
||
}
|
||
|
||
void isTwoNumber() const {
|
||
ASSERT_EQUALS(true, Tokenizer::isTwoNumber("2.0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isTwoNumber("+2.0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isTwoNumber("2.0e+0"));
|
||
ASSERT_EQUALS(true, Tokenizer::isTwoNumber("+2L"));
|
||
ASSERT_EQUALS(true, Tokenizer::isTwoNumber("+2"));
|
||
ASSERT_EQUALS(true, Tokenizer::isTwoNumber("2"));
|
||
ASSERT_EQUALS(true, Tokenizer::isTwoNumber("+2E+0"));
|
||
|
||
ASSERT_EQUALS(false, Tokenizer::isTwoNumber("0.0"));
|
||
ASSERT_EQUALS(false, Tokenizer::isTwoNumber("+0.0"));
|
||
ASSERT_EQUALS(false, Tokenizer::isTwoNumber("-0"));
|
||
ASSERT_EQUALS(false, Tokenizer::isTwoNumber(""));
|
||
ASSERT_EQUALS(false, Tokenizer::isTwoNumber("garbage"));
|
||
}
|
||
|
||
void simplifyStaticConst() {
|
||
const char code1[] = "class foo { public: bool const static c ; }";
|
||
const char expected1[] = "class foo { public: static const bool c ; }";
|
||
ASSERT_EQUALS(expected1, tokenizeAndStringify(code1, true));
|
||
|
||
const char code2[] =
|
||
"int long long f()\n"
|
||
"{\n"
|
||
"static const long long signed int i1;\n"
|
||
"static const long long int signed i2;\n"
|
||
"static const signed long long int i3;\n"
|
||
"static const signed int long long i4;\n"
|
||
"static const int signed long long i5;\n"
|
||
"static const int long long signed i6;\n"
|
||
"long long static const signed int i7;\n"
|
||
"long long static const int signed i8;\n"
|
||
"signed static const long long int i9;\n"
|
||
"signed static const int long long i10;\n"
|
||
"int static const signed long long i11;\n"
|
||
"int static const long long signed i12;\n"
|
||
"long long signed int static const i13;\n"
|
||
"long long int signed static const i14;\n"
|
||
"signed long long int static const i15;\n"
|
||
"signed int long long static const i16;\n"
|
||
"int signed long long static const i17;\n"
|
||
"int long long signed static const i18;\n"
|
||
"return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12\n"
|
||
"+ i13 + i14 + i15 + i16 + i17 + i18;\n"
|
||
"}";
|
||
const char expected2[] =
|
||
"long long f ( )\n"
|
||
"{\n"
|
||
"static const signed long long i1 ;\n"
|
||
"static const signed long long i2 ;\n"
|
||
"static const signed long long i3 ;\n"
|
||
"static const signed long long i4 ;\n"
|
||
"static const signed long long i5 ;\n"
|
||
"static const signed long long i6 ;\n"
|
||
"static const signed long long i7 ;\n"
|
||
"static const signed long long i8 ;\n"
|
||
"static const signed long long i9 ;\n"
|
||
"static const signed long long i10 ;\n"
|
||
"static const signed long long i11 ;\n"
|
||
"static const signed long long i12 ;\n"
|
||
"static const signed long long i13 ;\n"
|
||
"static const signed long long i14 ;\n"
|
||
"static const signed long long i15 ;\n"
|
||
"static const signed long long i16 ;\n"
|
||
"static const signed long long i17 ;\n"
|
||
"static const signed long long i18 ;\n"
|
||
"return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12\n"
|
||
"+ i13 + i14 + i15 + i16 + i17 + i18 ;\n"
|
||
"}";
|
||
ASSERT_EQUALS(expected2, tokenizeAndStringify(code2, true));
|
||
|
||
const char code3[] = "const unsigned long extern int i;";
|
||
const char expected3[] = "extern const unsigned long i ;";
|
||
ASSERT_EQUALS(expected3, tokenizeAndStringify(code3, true));
|
||
}
|
||
|
||
void simplifyCPPAttribute() {
|
||
ASSERT_EQUALS("int f ( ) ;",
|
||
tokenizeAndStringify("[[deprecated]] int f();", false, true, Settings::Native, "test.cpp", true));
|
||
|
||
ASSERT_EQUALS("[ [ deprecated ] ] int f ( ) ;",
|
||
tokenizeAndStringify("[[deprecated]] int f();", false, true, Settings::Native, "test.cpp", false));
|
||
|
||
ASSERT_EQUALS("[ [ deprecated ] ] int f ( ) ;",
|
||
tokenizeAndStringify("[[deprecated]] int f();", false, true, Settings::Native, "test.c", true));
|
||
|
||
ASSERT_EQUALS("template < class T > int f ( ) { }",
|
||
tokenizeAndStringify("template <class T> [[noreturn]] int f(){}", false, true, Settings::Native, "test.cpp", true));
|
||
|
||
ASSERT_EQUALS("int f ( int i ) ;",
|
||
tokenizeAndStringify("[[maybe_unused]] int f([[maybe_unused]] int i);", false, true, Settings::Native, "test.cpp", true));
|
||
|
||
ASSERT_EQUALS("[ [ maybe_unused ] ] int f ( [ [ maybe_unused ] ] int i ) ;",
|
||
tokenizeAndStringify("[[maybe_unused]] int f([[maybe_unused]] int i);", false, true, Settings::Native, "test.cpp", false));
|
||
|
||
ASSERT_EQUALS("struct a ;",
|
||
tokenizeAndStringify("struct [[]] a;", false, true, Settings::Native, "test.cpp", true));
|
||
|
||
ASSERT_EQUALS("struct a ;",
|
||
tokenizeAndStringify("struct [[,]] a;", false, true, Settings::Native, "test.cpp", true));
|
||
|
||
ASSERT_EQUALS("struct a ;",
|
||
tokenizeAndStringify("struct [[deprecated,]] a;", false, true, Settings::Native, "test.cpp", true));
|
||
|
||
ASSERT_EQUALS("struct a ;",
|
||
tokenizeAndStringify("struct [[,,]] a;", false, true, Settings::Native, "test.cpp", true));
|
||
|
||
ASSERT_EQUALS("struct a ;",
|
||
tokenizeAndStringify("struct [[deprecated,,]] a;", false, true, Settings::Native, "test.cpp", true));
|
||
|
||
ASSERT_EQUALS("struct a ;",
|
||
tokenizeAndStringify("struct [[deprecated,maybe_unused,]] a;", false, true, Settings::Native, "test.cpp", true));
|
||
|
||
ASSERT_EQUALS("struct a ;",
|
||
tokenizeAndStringify("struct [[,,,]] a;", false, true, Settings::Native, "test.cpp", true));
|
||
}
|
||
|
||
void simplifyCaseRange() {
|
||
ASSERT_EQUALS("void f ( ) { switch ( x ) { case 1 : case 2 : case 3 : case 4 : ; } }", tokenizeAndStringify("void f() { switch(x) { case 1 ... 4: } }"));
|
||
ASSERT_EQUALS("void f ( ) { switch ( x ) { case 4 ... 1 : ; } }", tokenizeAndStringify("void f() { switch(x) { case 4 ... 1: } }"));
|
||
tokenizeAndStringify("void f() { switch(x) { case 1 ... 1000000: } }"); // Do not run out of memory
|
||
|
||
ASSERT_EQUALS("void f ( ) { switch ( x ) { case 'a' : case 'b' : case 'c' : ; } }", tokenizeAndStringify("void f() { switch(x) { case 'a' ... 'c': } }"));
|
||
ASSERT_EQUALS("void f ( ) { switch ( x ) { case 'c' ... 'a' : ; } }", tokenizeAndStringify("void f() { switch(x) { case 'c' ... 'a': } }"));
|
||
|
||
ASSERT_EQUALS("void f ( ) { switch ( x ) { case '[' : case '\\\\' : case ']' : ; } }", tokenizeAndStringify("void f() { switch(x) { case '[' ... ']': } }"));
|
||
}
|
||
|
||
void simplifyEmptyNamespaces() {
|
||
ASSERT_EQUALS(";", tokenizeAndStringify("namespace { }"));
|
||
ASSERT_EQUALS(";", tokenizeAndStringify("namespace foo { }"));
|
||
ASSERT_EQUALS(";", tokenizeAndStringify("namespace foo { namespace { } }"));
|
||
ASSERT_EQUALS(";", tokenizeAndStringify("namespace { namespace { } }")); // Ticket #9512
|
||
ASSERT_EQUALS(";", tokenizeAndStringify("namespace foo { namespace bar { } }"));
|
||
}
|
||
|
||
void prepareTernaryOpForAST() {
|
||
ASSERT_EQUALS("a ? b : c ;", tokenizeAndStringify("a ? b : c;"));
|
||
|
||
ASSERT_EQUALS("a ? ( b , c ) : d ;", tokenizeAndStringify("a ? b , c : d;"));
|
||
ASSERT_EQUALS("a ? ( b , c ) : d ;", tokenizeAndStringify("a ? (b , c) : d;"));
|
||
|
||
ASSERT_EQUALS("a ? ( 1 ? ( a , b ) : 3 ) : d ;", tokenizeAndStringify("a ? 1 ? a, b : 3 : d;"));
|
||
|
||
ASSERT_EQUALS("a ? ( std :: map < int , int > ( ) ) : 0 ;", tokenizeAndStringify("typedef std::map<int,int> mymap; a ? mymap() : 0;"));
|
||
|
||
ASSERT_EQUALS("a ? ( b < c ) : d > e", tokenizeAndStringify("a ? b < c : d > e"));
|
||
}
|
||
|
||
enum class AstStyle {
|
||
Simple,
|
||
Z3
|
||
};
|
||
|
||
std::string testAst(const char code[], AstStyle style = AstStyle::Simple) {
|
||
// tokenize given code..
|
||
Tokenizer tokenList(&settings0, nullptr);
|
||
std::istringstream istr(code);
|
||
if (!tokenList.list.createTokens(istr,"test.cpp"))
|
||
return "ERROR";
|
||
|
||
tokenList.combineStringAndCharLiterals();
|
||
tokenList.combineOperators();
|
||
tokenList.createLinks();
|
||
tokenList.createLinks2();
|
||
tokenList.list.front()->assignIndexes();
|
||
|
||
// set varid..
|
||
for (Token *tok = tokenList.list.front(); tok; tok = tok->next()) {
|
||
if (tok->str() == "var")
|
||
tok->varId(1);
|
||
}
|
||
|
||
// Create AST..
|
||
tokenList.prepareTernaryOpForAST();
|
||
tokenList.list.createAst();
|
||
|
||
tokenList.list.validateAst();
|
||
|
||
// Basic AST validation
|
||
for (const Token *tok = tokenList.list.front(); tok; tok = tok->next()) {
|
||
if (tok->astOperand2() && !tok->astOperand1() && tok->str() != ";" && tok->str() != ":")
|
||
return "Op2 but no Op1 for token: " + tok->str();
|
||
}
|
||
|
||
// Return stringified AST
|
||
if (style == AstStyle::Z3)
|
||
return tokenList.list.front()->astTop()->astStringZ3();
|
||
|
||
std::string ret;
|
||
std::set<const Token *> astTop;
|
||
for (const Token *tok = tokenList.list.front(); tok; tok = tok->next()) {
|
||
if (tok->astOperand1() && astTop.find(tok->astTop()) == astTop.end()) {
|
||
astTop.insert(tok->astTop());
|
||
if (!ret.empty())
|
||
ret = ret + " ";
|
||
ret += tok->astTop()->astString();
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
void astexpr() { // simple expressions with arithmetical ops
|
||
ASSERT_EQUALS("12+3+", testAst("1+2+3"));
|
||
ASSERT_EQUALS("12*3+", testAst("1*2+3"));
|
||
ASSERT_EQUALS("123*+", testAst("1+2*3"));
|
||
ASSERT_EQUALS("12*34*+", testAst("1*2+3*4"));
|
||
ASSERT_EQUALS("12*34*5*+", testAst("1*2+3*4*5"));
|
||
ASSERT_EQUALS("0(r.&", testAst("(&((typeof(x))0).r);"));
|
||
ASSERT_EQUALS("0(r.&", testAst("&((typeof(x))0).r;"));
|
||
|
||
// Various tests of precedence
|
||
ASSERT_EQUALS("ab::c+", testAst("a::b+c"));
|
||
ASSERT_EQUALS("abc+=", testAst("a=b+c"));
|
||
ASSERT_EQUALS("abc=,", testAst("a,b=c"));
|
||
ASSERT_EQUALS("a-1+", testAst("-a+1"));
|
||
ASSERT_EQUALS("ab++-c-", testAst("a-b++-c"));
|
||
|
||
// sizeof
|
||
ASSERT_EQUALS("ab.sizeof", testAst("sizeof a.b"));
|
||
|
||
// assignment operators
|
||
ASSERT_EQUALS("ab>>=", testAst("a>>=b;"));
|
||
ASSERT_EQUALS("ab<<=", testAst("a<<=b;"));
|
||
ASSERT_EQUALS("ab+=", testAst("a+=b;"));
|
||
ASSERT_EQUALS("ab-=", testAst("a-=b;"));
|
||
ASSERT_EQUALS("ab*=", testAst("a*=b;"));
|
||
ASSERT_EQUALS("ab/=", testAst("a/=b;"));
|
||
ASSERT_EQUALS("ab%=", testAst("a%=b;"));
|
||
ASSERT_EQUALS("ab&=", testAst("a&=b;"));
|
||
ASSERT_EQUALS("ab|=", testAst("a|=b;"));
|
||
ASSERT_EQUALS("ab^=", testAst("a^=b;"));
|
||
|
||
ASSERT_EQUALS("ab*c*.(+return", testAst("return a + ((*b).*c)();"));
|
||
|
||
// assignments are executed from right to left
|
||
ASSERT_EQUALS("abc==", testAst("a=b=c;"));
|
||
|
||
// ternary operator
|
||
ASSERT_EQUALS("ab0=c1=:?", testAst("a?b=0:c=1;"));
|
||
ASSERT_EQUALS("fabc,d:?=e,", testAst("f = a ? b, c : d, e;"));
|
||
ASSERT_EQUALS("fabc,de,:?=", testAst("f = (a ? (b, c) : (d, e));"));
|
||
ASSERT_EQUALS("fabc,de,:?=", testAst("f = (a ? b, c : (d, e));"));
|
||
ASSERT_EQUALS("ab35,4:?foo(:?return", testAst("return (a ? b ? (3,5) : 4 : foo());"));
|
||
ASSERT_EQUALS("check(result_type00,{invalid:?return", testAst("return check() ? result_type {0, 0} : invalid;"));
|
||
ASSERT_EQUALS("x01:?return", testAst("return x ? 0 : 1;"));
|
||
ASSERT_EQUALS("x00throw:?return", testAst("return x ? 0 : throw 0;")); // #9768
|
||
ASSERT_EQUALS("val0<1throwval:?return", testAst("return val < 0 ? throw 1 : val;")); // #8526
|
||
ASSERT_EQUALS("ix0<00throw:?=", testAst("int i = x < 0 ? 0 : throw 0;"));
|
||
|
||
ASSERT_EQUALS("a\"\"=", testAst("a=\"\""));
|
||
ASSERT_EQUALS("a\'\'=", testAst("a=\'\'"));
|
||
ASSERT_EQUALS("'X''a'>", testAst("('X' > 'a')"));
|
||
ASSERT_EQUALS("L'X'L'a'>", testAst("(L'X' > L'a')"));
|
||
ASSERT_EQUALS("u'X'u'a'>", testAst("(u'X' > u'a')"));
|
||
ASSERT_EQUALS("U'X'U'a'>", testAst("(U'X' > U'a')"));
|
||
ASSERT_EQUALS("u8'X'u8'a'>", testAst("(u8'X' > u8'a')"));
|
||
|
||
ASSERT_EQUALS("a0>bc/d:?", testAst("(a>0) ? (b/(c)) : d;"));
|
||
ASSERT_EQUALS("abc/+d+", testAst("a + (b/(c)) + d;"));
|
||
ASSERT_EQUALS("x1024x/0:?", testAst("void f() { x ? 1024 / x : 0; }"));
|
||
|
||
ASSERT_EQUALS("absizeofd(ef.+(=", testAst("a = b(sizeof(c d) + e.f)"));
|
||
|
||
ASSERT_EQUALS("a*b***", testAst("*a * **b;")); // Correctly distinguish between unary and binary operator*
|
||
|
||
// strings
|
||
ASSERT_EQUALS("f\"A\"1,(",testAst("f(\"A\" B, 1);"));
|
||
ASSERT_EQUALS("fA1,(",testAst("f(A \"B\", 1);"));
|
||
|
||
// C++ : type()
|
||
ASSERT_EQUALS("fint(0,(", testAst("f(int(),0);"));
|
||
ASSERT_EQUALS("f(0,(", testAst("f(int *(),0);")); // typedef int* X; f(X(),0);
|
||
ASSERT_EQUALS("f((0,(", testAst("f((intp)int *(),0);"));
|
||
ASSERT_EQUALS("zx1(&y2(&|=", testAst("z = (x & (unsigned)1) | (y & (unsigned)2);")); // not type()
|
||
|
||
// for
|
||
ASSERT_EQUALS("for;;(", testAst("for(;;)"));
|
||
ASSERT_EQUALS("fora0=a8<a++;;(", testAst("for(a=0;a<8;a++)"));
|
||
ASSERT_EQUALS("fori1=current0=,iNUM<=i++;;(", testAst("for(i = (1), current = 0; i <= (NUM); ++i)"));
|
||
ASSERT_EQUALS("foreachxy,((", testAst("for(each(x,y)){}")); // it's not well-defined what this ast should be
|
||
ASSERT_EQUALS("forvar1(;;(", testAst("for(int var(1);;)"));
|
||
ASSERT_EQUALS("forab:(", testAst("for (int a : b);"));
|
||
ASSERT_EQUALS("forvarb:(", testAst("for (int *var : b);"));
|
||
ASSERT_EQUALS("forvard:(", testAst("for (a<b> var : d);"));
|
||
ASSERT_EQUALS("forvare:(", testAst("for (a::b<c> var : e);"));
|
||
ASSERT_EQUALS("forx*0=yz;;(", testAst("for(*x=0;y;z)"));
|
||
ASSERT_EQUALS("forx0=y(8<z;;(", testAst("for (x=0;(int)y<8;z);"));
|
||
ASSERT_EQUALS("forab,c:(", testAst("for (auto [a,b]: c);"));
|
||
ASSERT_EQUALS("fora*++;;(", testAst("for (++(*a);;);"));
|
||
ASSERT_EQUALS("foryz:(", testAst("for (decltype(x) *y : z);"));
|
||
ASSERT_EQUALS("for(tmpNULL!=tmptmpnext.=;;( tmpa=", testAst("for ( ({ tmp = a; }) ; tmp != NULL; tmp = tmp->next ) {}"));
|
||
|
||
// problems with multiple expressions
|
||
ASSERT_EQUALS("ax( whilex(", testAst("a(x) while (x)"));
|
||
ASSERT_EQUALS("ifx( i0= whilei(", testAst("if (x) { ({ int i = 0; while(i); }) };"));
|
||
ASSERT_EQUALS("ifx( BUG_ON{!( i0= whilei(", testAst("if (x) { BUG_ON(!({int i=0; while(i);})); }"));
|
||
ASSERT_EQUALS("v0= while{0!=( v0= while{0!=( v0=", testAst("({ v = 0; }); while (({ v = 0; }) != 0); while (({ v = 0; }) != 0);"));
|
||
|
||
|
||
ASSERT_EQUALS("abc.1:?1+bd.1:?+=", testAst("a =(b.c ? : 1) + 1 + (b.d ? : 1);"));
|
||
|
||
ASSERT_EQUALS("catch...(", testAst("try {} catch (...) {}"));
|
||
|
||
ASSERT_EQUALS("", testAst("void Foo(Bar&);"));
|
||
ASSERT_EQUALS("", testAst("void Foo(Bar&&);"));
|
||
|
||
ASSERT_EQUALS("Barb&", testAst("void Foo(Bar& b);"));
|
||
ASSERT_EQUALS("Barb&&", testAst("void Foo(Bar&& b);"));
|
||
|
||
ASSERT_EQUALS("DerivedDerived::(", testAst("Derived::~Derived() {}"));
|
||
|
||
ASSERT_EQUALS("ifCA_FarReadfilenew(,sizeofobjtype(,(!(", testAst("if (!CA_FarRead(file, (void far *)new, sizeof(objtype)))")); // #5910 - don't hang if C code is parsed as C++
|
||
|
||
// C++17: if (expr1; expr2)
|
||
ASSERT_EQUALS("ifx3=y;(", testAst("if (int x=3; y)"));
|
||
|
||
ASSERT_EQUALS("forx0=x;;(", testAst("for (int x=0; x;);"));
|
||
|
||
ASSERT_EQUALS("0f1(||", testAst("; 0 || f(1);"));
|
||
}
|
||
|
||
void astexpr2() { // limit for large expressions
|
||
// #7724 - wrong AST causes hang
|
||
// Ideally a proper AST is created for this code.
|
||
const char code[] = "const char * a(int type) {\n"
|
||
" return (\n"
|
||
" (type == 1) ? \"\"\n"
|
||
" : (type == 2) ? \"\"\n"
|
||
" : (type == 3) ? \"\"\n"
|
||
" : (type == 4) ? \"\"\n"
|
||
" : (type == 5) ? \"\"\n"
|
||
" : (type == 6) ? \"\"\n"
|
||
" : (type == 7) ? \"\"\n"
|
||
" : (type == 8) ? \"\"\n"
|
||
" : (type == 9) ? \"\"\n"
|
||
" : (type == 10) ? \"\"\n"
|
||
" : (type == 11) ? \"\"\n"
|
||
" : (type == 12) ? \"\"\n"
|
||
" : (type == 13) ? \"\"\n"
|
||
" : (type == 14) ? \"\"\n"
|
||
" : (type == 15) ? \"\"\n"
|
||
" : (type == 16) ? \"\"\n"
|
||
" : (type == 17) ? \"\"\n"
|
||
" : (type == 18) ? \"\"\n"
|
||
" : (type == 19) ? \"\"\n"
|
||
" : (type == 20) ? \"\"\n"
|
||
" : (type == 21) ? \"\"\n"
|
||
" : (type == 22) ? \"\"\n"
|
||
" : (type == 23) ? \"\"\n"
|
||
" : (type == 24) ? \"\"\n"
|
||
" : (type == 25) ? \"\"\n"
|
||
" : (type == 26) ? \"\"\n"
|
||
" : (type == 27) ? \"\"\n"
|
||
" : (type == 28) ? \"\"\n"
|
||
" : (type == 29) ? \"\"\n"
|
||
" : (type == 30) ? \"\"\n"
|
||
" : (type == 31) ? \"\"\n"
|
||
" : (type == 32) ? \"\"\n"
|
||
" : (type == 33) ? \"\"\n"
|
||
" : (type == 34) ? \"\"\n"
|
||
" : (type == 35) ? \"\"\n"
|
||
" : (type == 36) ? \"\"\n"
|
||
" : (type == 37) ? \"\"\n"
|
||
" : (type == 38) ? \"\"\n"
|
||
" : (type == 39) ? \"\"\n"
|
||
" : (type == 40) ? \"\"\n"
|
||
" : (type == 41) ? \"\"\n"
|
||
" : (type == 42) ? \"\"\n"
|
||
" : (type == 43) ? \"\"\n"
|
||
" : (type == 44) ? \"\"\n"
|
||
" : (type == 45) ? \"\"\n"
|
||
" : (type == 46) ? \"\"\n"
|
||
" : (type == 47) ? \"\"\n"
|
||
" : (type == 48) ? \"\"\n"
|
||
" : (type == 49) ? \"\"\n"
|
||
" : (type == 50) ? \"\"\n"
|
||
" : (type == 51) ? \"\"\n"
|
||
" : \"\");\n"
|
||
"}\n";
|
||
// Ensure that the AST is validated for the simplified token list
|
||
TODO_ASSERT_THROW(tokenizeAndStringify(code), InternalError); // this should not crash/hang
|
||
ASSERT_THROW(tokenizeAndStringify(code,true), InternalError); // when parentheses are simplified the AST will be wrong
|
||
}
|
||
|
||
void astnewdelete() {
|
||
ASSERT_EQUALS("aintnew=", testAst("a = new int;"));
|
||
ASSERT_EQUALS("aint4[new=", testAst("a = new int[4];"));
|
||
ASSERT_EQUALS("aFoobar(new=", testAst("a = new Foo(bar);"));
|
||
ASSERT_EQUALS("aFoobar(new=", testAst("a = new Foo(bar);"));
|
||
ASSERT_EQUALS("aFoo(new=", testAst("a = new Foo<bar>();"));
|
||
ASSERT_EQUALS("aXnew(", testAst("a (new (X));"));
|
||
ASSERT_EQUALS("aXnew5,(", testAst("a (new (X), 5);"));
|
||
ASSERT_EQUALS("adelete", testAst("delete a;"));
|
||
ASSERT_EQUALS("adelete", testAst("delete (a);"));
|
||
ASSERT_EQUALS("adelete", testAst("delete[] a;"));
|
||
ASSERT_EQUALS("ab.3c-(delete", testAst("delete[] a.b(3 - c);"));
|
||
ASSERT_EQUALS("aA1(new(bB2(new(,", testAst("a(new A(1)), b(new B(2))"));
|
||
ASSERT_EQUALS("Fred10[new", testAst(";new Fred[10];"));
|
||
ASSERT_EQUALS("adelete", testAst("void f() { delete a; }"));
|
||
|
||
// placement new
|
||
ASSERT_EQUALS("X12,3,(new ab,c,", testAst("new (a,b,c) X(1,2,3);"));
|
||
ASSERT_EQUALS("a::new=", testAst("a = new (b) ::X;"));
|
||
ASSERT_EQUALS("cCnew= abc:?", testAst("c = new(a ? b : c) C;"));
|
||
|
||
// invalid code (libreoffice), don't hang
|
||
// #define SlideSorterViewShell
|
||
// SfxViewFrame* pFrame;
|
||
// new SlideSorterViewShell(pFrame,rViewShellBase,pParentWindow,pFrameViewArgument);
|
||
ASSERT_EQUALS("fxnewy,z,(", testAst("f(new (x,y,z));"));
|
||
|
||
// clang testsuite..
|
||
ASSERT_EQUALS("const0(new", testAst("new const auto (0);"));
|
||
ASSERT_EQUALS("autonew", testAst("new (auto) (0.0);"));
|
||
ASSERT_EQUALS("int3[4[5[new", testAst("new (int S::*[3][4][5]) ();"));
|
||
ASSERT_EQUALS("pSnew=", testAst("p=new (x)(S)(1,2);"));
|
||
ASSERT_EQUALS("inti[new(", testAst("(void)new (int[i]);"));
|
||
ASSERT_EQUALS("intp* pnew malloc4(", testAst("int*p; new (p) (malloc(4));"));
|
||
ASSERT_EQUALS("intnew", testAst("new (&w.x)(int*)(0);"));
|
||
ASSERT_EQUALS("&new", testAst("new (&w.x)(0);")); // <- the "(int*)" has been simplified
|
||
|
||
// gcc testsuite..
|
||
ASSERT_EQUALS("char10[new(", testAst("(void)new(char*)[10];"));
|
||
}
|
||
|
||
void astpar() { // parentheses
|
||
ASSERT_EQUALS("12+3*", testAst("(1+2)*3"));
|
||
ASSERT_EQUALS("123+*", testAst("1*(2+3)"));
|
||
ASSERT_EQUALS("123+*4*", testAst("1*(2+3)*4"));
|
||
ASSERT_EQUALS("ifab.c&d==(", testAst("if((a.b&c)==d){}"));
|
||
|
||
ASSERT_EQUALS("pf.pf.12,(&&", testAst("((p.f) && (p.f)(1,2))"));
|
||
|
||
ASSERT_EQUALS("forresdirGetFirst.file&_T(,(=;;(", testAst("for ((res = dir.GetFirst(&file, _T("")));;) {}"));
|
||
|
||
// problems with: if (x[y]==z)
|
||
ASSERT_EQUALS("ifa(0[1==(", testAst("if(a()[0]==1){}"));
|
||
ASSERT_EQUALS("ifbuff0[&(*1==(", testAst("if (*((DWORD*)&buff[0])==1){}"));
|
||
ASSERT_EQUALS("ifp*0[1==(", testAst("if((*p)[0]==1)"));
|
||
ASSERT_EQUALS("ifab.cd.[e==(", testAst("if(a.b[c.d]==e){}"));
|
||
|
||
ASSERT_EQUALS("iftpnote.i1-[note.0==tpnote.i1-[type.4>||(", testAst("if ((tp.note[i - 1].note == 0) || (tp.note[i - 1].type > 4)) {}"));
|
||
ASSERT_EQUALS("ab.i[j1+[", testAst("a.b[i][j+1]"));
|
||
|
||
// problems with: x=expr
|
||
ASSERT_EQUALS("(= x (( (. ([ a i) f)))",
|
||
testAst("x = ((a[i]).f)();", AstStyle::Z3));
|
||
ASSERT_EQUALS("abc.de.++[=", testAst("a = b.c[++(d.e)];"));
|
||
ASSERT_EQUALS("abc(1+=", testAst("a = b(c**)+1;"));
|
||
ASSERT_EQUALS("abc.=", testAst("a = (b).c;"));
|
||
|
||
// casts
|
||
ASSERT_EQUALS("a1(2(+=",testAst("a=(t)1+(t)2;"));
|
||
ASSERT_EQUALS("a1(2+=",testAst("a=(t)1+2;"));
|
||
ASSERT_EQUALS("a1(2+=",testAst("a=(t*)1+2;"));
|
||
ASSERT_EQUALS("a1(2+=",testAst("a=(t&)1+2;"));
|
||
ASSERT_EQUALS("a1(2+=",testAst("a=(t&&)1+2;"));
|
||
ASSERT_EQUALS("ab::r&c(=", testAst("a::b& r = (a::b&)c;")); // #5261
|
||
ASSERT_EQUALS("ab10:?=", testAst("a=(b)?1:0;"));
|
||
ASSERT_EQUALS("ac5[new(=", testAst("a = (b*)(new c[5]);")); // #8786
|
||
ASSERT_EQUALS("a(4+", testAst("(int)(a) + 4;"));
|
||
|
||
// (cast){data}[index]
|
||
ASSERT_EQUALS("a&{(0[1[5[0=", testAst("(int (**)[i]){&a}[0][1][5] = 0;"));
|
||
ASSERT_EQUALS("ab12,{(0[,(", testAst("a(b, (int []){1,2}[0]);"));
|
||
ASSERT_EQUALS("n0=", testAst("TrivialDefCtor{[2][2]}[1][1].n = 0;"));
|
||
ASSERT_EQUALS("aT12,3,{1[=", testAst("a = T{1, 2, 3}[1];"));
|
||
|
||
// Type{data}()
|
||
ASSERT_EQUALS("ab{(=", testAst("a=b{}();"));
|
||
ASSERT_EQUALS("abc{((=", testAst("a=b(c{}());"));
|
||
ASSERT_EQUALS("xNULL!=0(x(:?", testAst("void f() { {} ((x != NULL) ? (void)0 : x()); }"));
|
||
|
||
// ({..})
|
||
ASSERT_EQUALS("a{+d+ bc+", testAst("a+({b+c;})+d"));
|
||
ASSERT_EQUALS("a{d*+ bc+", testAst("a+({b+c;})*d"));
|
||
ASSERT_EQUALS("xa{((= bc( yd{((= ef(",
|
||
testAst("x=(int)(a({b(c);}));" // don't hang
|
||
"y=(int)(d({e(f);}));"));
|
||
ASSERT_EQUALS("A{{,( x0= Bx1={x2={,(", // TODO: This is not perfect!!
|
||
testAst("A({},{x=0;});" // don't hang
|
||
"B({x=1},{x=2});"));
|
||
ASSERT_EQUALS("xMACROtype.T=value.1=,{({=",
|
||
testAst("x = { MACRO( { .type=T, .value=1 } ) }")); // don't hang: MACRO({..})
|
||
ASSERT_EQUALS("fori10=i{;;( i--", testAst("for (i=10;i;({i--;}) ) {}"));
|
||
ASSERT_EQUALS("c{0{,{(",
|
||
testAst("c({{}, {0}}, {0.0f});"));
|
||
|
||
// function pointer
|
||
TODO_ASSERT_EQUALS("todo", "va_argapvoid((,(*0=", testAst("*va_arg(ap, void(**) ()) = 0;"));
|
||
|
||
// struct initialization
|
||
ASSERT_EQUALS("name_bytes[bits~unusedBits>>unusedBits<<{=", testAst("const uint8_t name_bytes[] = { (~bits >> unusedBits) << unusedBits };"));
|
||
ASSERT_EQUALS("abuf.0{={=", testAst("a = { .buf = { 0 } };"));
|
||
ASSERT_EQUALS("ab2[a.0=b.0=,{a.0=b.0=,{,{=", testAst("struct AB ab[2] = { { .a=0, .b=0 }, { .a=0, .b=0 } };"));
|
||
ASSERT_EQUALS("tset{=", testAst("struct cgroup_taskset tset = {};"));
|
||
ASSERT_EQUALS("s1a&,{2b&,{,{=", testAst("s = { {1, &a}, {2, &b} };"));
|
||
ASSERT_EQUALS("s0[L.2[x={=", testAst("s = { [0].L[2] = x};"));
|
||
ASSERT_EQUALS("ac.0={(=", testAst("a = (b){.c=0,};")); // <- useless comma
|
||
ASSERT_EQUALS("xB[1y.z.1={(&=,{={=", testAst("x = { [B] = {1, .y = &(struct s) { .z=1 } } };"));
|
||
ASSERT_EQUALS("xab,c,{=", testAst("x={a,b,(c)};"));
|
||
ASSERT_EQUALS("x0fSa.1=b.2=,c.\"\"=,{(||=", testAst("x = 0 || f(S{.a = 1, .b = 2, .c = \"\" });"));
|
||
ASSERT_EQUALS("x0fSa.1{=b.2{,c.\"\"=,{(||=", testAst("x = 0 || f(S{.a = { 1 }, .b { 2 }, .c = \"\" });"));
|
||
ASSERT_EQUALS("a0{,( \"\"abc12:?,", testAst("a(0, {{\"\", (abc) ? 1 : 2}});"));
|
||
ASSERT_EQUALS("a0{,( \'\'abc12:?,", testAst("a(0, {{\'\', (abc) ? 1 : 2}});"));
|
||
|
||
// struct initialization hang
|
||
ASSERT_EQUALS("sbar.1{,{(={= forfieldfield++;;(",
|
||
testAst("struct S s = {.bar = (struct foo) { 1, { } } };\n"
|
||
"void f(struct cmd *) { for (; field; field++) {} }"));
|
||
|
||
// template parentheses: <>
|
||
ASSERT_EQUALS("stdfabs::m_similarity(numeric_limitsepsilon::(<=return", testAst("return std::fabs(m_similarity) <= numeric_limits<double>::epsilon();")); // #6195
|
||
|
||
// C++ initializer
|
||
ASSERT_EQUALS("Class{", testAst("Class{};"));
|
||
ASSERT_EQUALS("Class12,{", testAst("Class{1,2};"));
|
||
ASSERT_EQUALS("Class12,{", testAst("Class<X>{1,2};"));
|
||
ASSERT_EQUALS("abc{d:?=", testAst("a=b?c{}:d;"));
|
||
ASSERT_EQUALS("abc12,{d:?=", testAst("a=b?c{1,2}:d;"));
|
||
ASSERT_EQUALS("abc{d:?=", testAst("a=b?c<X>{}:d;"));
|
||
ASSERT_EQUALS("abc12,{d:?=", testAst("a=b?c<X>{1,2}:d;"));
|
||
ASSERT_EQUALS("a::12,{", testAst("::a{1,2};")); // operator precedence
|
||
ASSERT_EQUALS("Abc({newreturn", testAst("return new A {b(c)};"));
|
||
ASSERT_EQUALS("a{{return", testAst("return{{a}};"));
|
||
ASSERT_EQUALS("a{b{,{return", testAst("return{{a},{b}};"));
|
||
ASSERT_EQUALS("stdvector::", testAst("std::vector<std::vector<int>>{{},{}}"));
|
||
ASSERT_EQUALS("abR{{,P(,((", testAst("a(b(R{},{},P()));"));
|
||
}
|
||
|
||
void astbrackets() { // []
|
||
ASSERT_EQUALS("a23+[4+", testAst("a[2+3]+4"));
|
||
ASSERT_EQUALS("a1[0[", testAst("a[1][0]"));
|
||
ASSERT_EQUALS("ab0[=", testAst("a=(b)[0];"));
|
||
ASSERT_EQUALS("abc.0[=", testAst("a=b.c[0];"));
|
||
ASSERT_EQUALS("ab0[1[=", testAst("a=b[0][1];"));
|
||
}
|
||
|
||
void astvardecl() {
|
||
// Variable declaration
|
||
ASSERT_EQUALS("a1[\"\"=", testAst("char a[1]=\"\";"));
|
||
ASSERT_EQUALS("charp*(3[char5[3[new=", testAst("char (*p)[3] = new char[5][3];"));
|
||
ASSERT_EQUALS("varp=", testAst("const int *var = p;"));
|
||
|
||
// #9127
|
||
const char code1[] = "using uno::Ref;\n"
|
||
"Ref<X> r;\n"
|
||
"int var(0);";
|
||
ASSERT_EQUALS("unoRef:: var0(", testAst(code1));
|
||
|
||
ASSERT_EQUALS("vary=", testAst("std::string var = y;"));
|
||
|
||
// create ast for decltype
|
||
ASSERT_EQUALS("decltypex( var1=", testAst("decltype(x) var = 1;"));
|
||
}
|
||
|
||
void astunaryop() { // unary operators
|
||
ASSERT_EQUALS("1a--+", testAst("1 + --a"));
|
||
ASSERT_EQUALS("1a--+", testAst("1 + a--"));
|
||
ASSERT_EQUALS("ab+!", testAst("!(a+b)"));
|
||
ASSERT_EQUALS("ab.++", testAst("++a.b;"));
|
||
ASSERT_EQUALS("ab.++", testAst("a.b++;"));
|
||
ASSERT_EQUALS("ab::++", testAst("a::b++;"));
|
||
ASSERT_EQUALS("c5[--*", testAst("*c[5]--;"));
|
||
ASSERT_EQUALS("xreturn", testAst("return x;"));
|
||
ASSERT_EQUALS("x(throw", testAst(";throw x();"));
|
||
ASSERT_EQUALS("a*bc:?return", testAst("return *a ? b : c;"));
|
||
ASSERT_EQUALS("xy*--=", testAst("x = -- * y;"));
|
||
ASSERT_EQUALS("x(throw", testAst(";throw (foo) x;")); // #9955
|
||
|
||
// Unary :: operator
|
||
ASSERT_EQUALS("abcd::12,(e/:?=", testAst("a = b ? c : ::d(1,2) / e;"));
|
||
|
||
// how is "--" handled here:
|
||
ASSERT_EQUALS("ab4<<c--+1:?", testAst("a ? (b << 4) + --c : 1"));
|
||
ASSERT_EQUALS("ab4<<c--+1:?", testAst("a ? (b << 4) + c-- : 1"));
|
||
ASSERT_EQUALS("ai[i= i--", testAst("a[i]=i; --i;"));
|
||
}
|
||
|
||
void astfunction() { // function calls
|
||
ASSERT_EQUALS("1f(+2+", testAst("1+f()+2"));
|
||
ASSERT_EQUALS("1f2(+3+", testAst("1+f(2)+3"));
|
||
ASSERT_EQUALS("1f23,(+4+", testAst("1+f(2,3)+4"));
|
||
ASSERT_EQUALS("1f2a&,(+", testAst("1+f(2,&a)"));
|
||
ASSERT_EQUALS("argv[", testAst("int f(char argv[]);"));
|
||
ASSERT_EQUALS("", testAst("extern unsigned f(const char *);"));
|
||
ASSERT_EQUALS("charformat*...,", testAst("extern void f(const char *format, ...);"));
|
||
ASSERT_EQUALS("int((void,", testAst("extern int for_each_commit_graft(int (*)(int*), void *);"));
|
||
ASSERT_EQUALS("for;;(", testAst("for (;;) {}"));
|
||
ASSERT_EQUALS("xsizeofvoid(=", testAst("x=sizeof(void*)"));
|
||
ASSERT_EQUALS("abc{d{,{(=", testAst("a = b({ c{}, d{} });"));
|
||
ASSERT_EQUALS("abc;(", testAst("a(b;c)"));
|
||
ASSERT_EQUALS("x{( forbc;;(", testAst("x({ for(a;b;c){} });"));
|
||
}
|
||
|
||
void asttemplate() { // uninstantiated templates will have <,>,etc..
|
||
ASSERT_EQUALS("a(3==", testAst("a<int>()==3"));
|
||
ASSERT_EQUALS("ab(== f(", testAst("a == b<c>(); f();"));
|
||
ASSERT_EQUALS("static_casta(i[", testAst("; static_cast<char*>(a)[i];")); // #6203
|
||
ASSERT_EQUALS("reinterpret_castreinterpret_castptr(123&(",
|
||
testAst(";reinterpret_cast<void*>(reinterpret_cast<unsigned>(ptr) & 123);")); // #7253
|
||
ASSERT_EQUALS("bcd.(=", testAst(";a<int> && b = c->d();"));
|
||
|
||
// This two unit tests were added to avoid a crash. The actual correct AST result for non-executable code has not been determined so far.
|
||
ASSERT_EQUALS("Cpublica::b:::", testAst("class C : public ::a::b<bool> { };"));
|
||
ASSERT_EQUALS("AB: abc+=", testAst("struct A : public B<C*> { void f() { a=b+c; } };"));
|
||
|
||
ASSERT_EQUALS("xfts(=", testAst("; auto x = f(ts...);"));
|
||
}
|
||
|
||
void astcast() {
|
||
ASSERT_EQUALS("ac&(=", testAst("a = (long)&c;"));
|
||
ASSERT_EQUALS("ac*(=", testAst("a = (Foo*)*c;"));
|
||
ASSERT_EQUALS("ac-(=", testAst("a = (long)-c;"));
|
||
ASSERT_EQUALS("ac~(=", testAst("a = (b)~c;"));
|
||
ASSERT_EQUALS("ac(=", testAst("a = (some<strange, type>)c;"));
|
||
ASSERT_EQUALS("afoveon_avgimage((foveon_avgimage((+=", testAst("a = foveon_avg(((short(*)[4]) image)) + foveon_avg(((short(*)[4]) image));"));
|
||
ASSERT_EQUALS("c(40<<return", testAst("return (long long)c << 40;"));
|
||
ASSERT_EQUALS("ab-(=", testAst("a = ((int)-b)")); // Multiple subsequent unary operators (cast and -)
|
||
ASSERT_EQUALS("xdouble123(i*(=", testAst("x = (int)(double(123)*i);"));
|
||
ASSERT_EQUALS("ac(=", testAst("a = (::b)c;"));
|
||
ASSERT_EQUALS("abcd,({(=", testAst("a = (s){b(c, d)};"));
|
||
ASSERT_EQUALS("xatoistr({(=", testAst("x = (struct X){atoi(str)};"));
|
||
ASSERT_EQUALS("xa.0=b.0=,c.0=,{(=", testAst("x = (struct abc) { .a=0, .b=0, .c=0 };"));
|
||
|
||
ASSERT_EQUALS("yz.(return", testAst("return (x)(y).z;"));
|
||
|
||
ASSERT_EQUALS("fon!(restoring01:?,(", testAst("f((long) !on, restoring ? 0 : 1);"));
|
||
|
||
// not cast
|
||
ASSERT_EQUALS("AB||", testAst("(A)||(B)"));
|
||
ASSERT_EQUALS("abc[1&=", testAst("a = (b[c]) & 1;"));
|
||
ASSERT_EQUALS("abc::(=", testAst("a = (b::c)();"));
|
||
|
||
ASSERT_EQUALS("pcharnew(=", testAst("p = (void *)(new char);"));
|
||
}
|
||
|
||
void astlambda() {
|
||
// a lambda expression '[x](y){}' is compiled as:
|
||
// [
|
||
// `-(
|
||
// `-{
|
||
|
||
ASSERT_EQUALS("x{(a&[( ai=", testAst("x([&a](int i){a=i;});"));
|
||
ASSERT_EQUALS("{([(return 0return", testAst("return [](){ return 0; }();"));
|
||
|
||
// noexcept
|
||
ASSERT_EQUALS("x{([( ai=", testAst("x([](int i)noexcept{a=i;});"));
|
||
|
||
// ->
|
||
ASSERT_EQUALS("{([(return 0return", testAst("return []() -> int { return 0; }();"));
|
||
ASSERT_EQUALS("{(something[(return 0return", testAst("return [something]() -> int { return 0; }();"));
|
||
ASSERT_EQUALS("{([cd,(return 0return", testAst("return [](int a, int b) -> int { return 0; }(c, d);"));
|
||
ASSERT_EQUALS("{([return", testAst("return []() -> decltype(0) {};"));
|
||
ASSERT_EQUALS("x{(&[=", testAst("x = [&]()->std::string const & {};"));
|
||
ASSERT_EQUALS("f{([=", testAst("f = []() -> foo* {};"));
|
||
ASSERT_EQUALS("f{([=", testAst("f = [](void) mutable -> foo* {};"));
|
||
ASSERT_EQUALS("f{([=", testAst("f = []() mutable {};"));
|
||
|
||
ASSERT_EQUALS("x{([= 0return", testAst("x = [](){return 0; };"));
|
||
|
||
ASSERT_EQUALS("ab{&[(= cd=", testAst("a = b([&]{c=d;});"));
|
||
|
||
// 8628
|
||
ASSERT_EQUALS("f{([( switchx( 1case y++", testAst("f([](){switch(x){case 1:{++y;}}});"));
|
||
|
||
ASSERT_EQUALS("{(=[{return ab=",
|
||
testAst("return {\n"
|
||
" [=]() {\n"
|
||
" a = b;\n"
|
||
" }\n"
|
||
"};\n"));
|
||
ASSERT_EQUALS("{=[{return ab=",
|
||
testAst("return {\n"
|
||
" [=] {\n"
|
||
" a = b;\n"
|
||
" }\n"
|
||
"};\n"));
|
||
ASSERT_EQUALS("{(=[{return ab=",
|
||
testAst("return {\n"
|
||
" [=]() -> int {\n"
|
||
" a=b;\n"
|
||
" }\n"
|
||
"}"));
|
||
ASSERT_EQUALS("{(=[{return ab=",
|
||
testAst("return {\n"
|
||
" [=]() mutable -> int {\n"
|
||
" a=b;\n"
|
||
" }\n"
|
||
"}"));
|
||
|
||
// daca@home hang
|
||
ASSERT_EQUALS("a{(&[= 0return b{(=[= fori0=i10!=i++;;(",
|
||
testAst("a = [&]() -> std::pair<int, int> { return 0; };\n"
|
||
"b = [=]() { for (i = 0; i != 10; ++i); };"));
|
||
|
||
// #9662
|
||
ASSERT_EQUALS("b{[{ stdunique_ptr::0nullptrnullptr:?{", testAst("auto b{[] { std::unique_ptr<void *>{0 ? nullptr : nullptr}; }};"));
|
||
ASSERT_EQUALS("b{[=", testAst("void a() { [b = [] { ; }] {}; }"));
|
||
|
||
}
|
||
|
||
void astcase() {
|
||
ASSERT_EQUALS("0case", testAst("case 0:"));
|
||
ASSERT_EQUALS("12+case", testAst("case 1+2:"));
|
||
ASSERT_EQUALS("xyz:?case", testAst("case (x?y:z):"));
|
||
ASSERT_EQUALS("switchx( 1case y++ 2case", testAst("switch(x){case 1:{++y;break;case 2:break;}}"));
|
||
}
|
||
|
||
void astrefqualifier() {
|
||
ASSERT_EQUALS("b(int.", testAst("class a { auto b() -> int&; };"));
|
||
ASSERT_EQUALS("b(int.", testAst("class a { auto b() -> int&&; };"));
|
||
ASSERT_EQUALS("b(", testAst("class a { void b() &&; };"));
|
||
ASSERT_EQUALS("b(", testAst("class a { void b() &; };"));
|
||
ASSERT_EQUALS("b(", testAst("class a { void b() && {} };"));
|
||
ASSERT_EQUALS("b(", testAst("class a { void b() & {} };"));
|
||
}
|
||
|
||
//Verify that returning a newly constructed object generates the correct AST even when the class name is scoped
|
||
//Addresses https://trac.cppcheck.net/ticket/9700
|
||
void astnewscoped() {
|
||
ASSERT_EQUALS("(return (new A))", testAst("return new A;", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (( A)))", testAst("return new A();", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (( A true)))", testAst("return new A(true);", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (:: A B)))", testAst("return new A::B;", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (( (:: A B))))", testAst("return new A::B();", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (( (:: A B) true)))", testAst("return new A::B(true);", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (:: (:: A B) C)))", testAst("return new A::B::C;", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (( (:: (:: A B) C))))", testAst("return new A::B::C();", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (( (:: (:: A B) C) true)))", testAst("return new A::B::C(true);", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (:: (:: (:: A B) C) D)))", testAst("return new A::B::C::D;", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (( (:: (:: (:: A B) C) D))))", testAst("return new A::B::C::D();", AstStyle::Z3));
|
||
ASSERT_EQUALS("(return (new (( (:: (:: (:: A B) C) D) true)))", testAst("return new A::B::C::D(true);", AstStyle::Z3));
|
||
}
|
||
|
||
void compileLimits() {
|
||
const char raw_code[] = "#define PTR1 (* (* (* (* (* (* (* (* (* (*\n"
|
||
"#define PTR2 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1\n"
|
||
"#define PTR3 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2\n"
|
||
"#define PTR4 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3\n"
|
||
"#define PTR5 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4\n"
|
||
"#define PTR6 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5\n"
|
||
"\n"
|
||
"#define RBR1 ) ) ) ) ) ) ) ) ) )\n"
|
||
"#define RBR2 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1\n"
|
||
"#define RBR3 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2\n"
|
||
"#define RBR4 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3\n"
|
||
"#define RBR5 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4\n"
|
||
"#define RBR6 RBR5 RBR5 RBR5 RBR5 RBR5 RBR5 RBR5 RBR5 RBR5 RBR5\n"
|
||
"\n"
|
||
"int PTR4 q4_var RBR4 = 0;\n";
|
||
|
||
// Preprocess file..
|
||
Preprocessor preprocessor(settings0);
|
||
std::list<std::string> configurations;
|
||
std::string filedata;
|
||
std::istringstream fin(raw_code);
|
||
preprocessor.preprocess(fin, filedata, configurations, emptyString, settings0.includePaths);
|
||
const std::string code = preprocessor.getcode(filedata, emptyString, emptyString);
|
||
|
||
tokenizeAndStringify(code.c_str()); // just survive...
|
||
}
|
||
|
||
bool isStartOfExecutableScope(int offset, const char code[]) {
|
||
Tokenizer tokenizer(&settings0, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
|
||
return Tokenizer::startOfExecutableScope(tokenizer.tokens()->tokAt(offset)) != nullptr;
|
||
}
|
||
|
||
void startOfExecutableScope() {
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() const { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() volatile { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() override { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() noexcept { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() NOEXCEPT { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() CONST NOEXCEPT { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() const noexcept { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() noexcept(true) { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() const noexcept(true) { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() throw() { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() THROW() { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() CONST THROW() { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() const throw() { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() throw(int) { }"));
|
||
ASSERT(isStartOfExecutableScope(3, "void foo() const throw(int) { }"));
|
||
ASSERT(isStartOfExecutableScope(2, "foo() : a(1) { }"));
|
||
ASSERT(isStartOfExecutableScope(2, "foo() : a(1), b(2) { }"));
|
||
ASSERT(isStartOfExecutableScope(2, "foo() : a{1} { }"));
|
||
ASSERT(isStartOfExecutableScope(2, "foo() : a{1}, b{2} { }"));
|
||
}
|
||
|
||
void removeMacroInClassDef() { // #6058
|
||
ASSERT_EQUALS("class Fred { } ;", tokenizeAndStringify("class DLLEXPORT Fred { } ;"));
|
||
ASSERT_EQUALS("class Fred : Base { } ;", tokenizeAndStringify("class Fred FINAL : Base { } ;"));
|
||
// Regression for C code:
|
||
ASSERT_EQUALS("struct Fred { } ;", tokenizeAndStringify("struct DLLEXPORT Fred { } ;", false, true, Settings::Native, "test.c"));
|
||
}
|
||
|
||
void sizeofAddParentheses() {
|
||
ASSERT_EQUALS("sizeof ( sizeof ( 1 ) ) ;", tokenizeAndStringify("sizeof sizeof 1;"));
|
||
ASSERT_EQUALS("sizeof ( a . b ) + 3 ;", tokenizeAndStringify("sizeof a.b+3;"));
|
||
ASSERT_EQUALS("sizeof ( a [ 2 ] . b ) + 3 ;", tokenizeAndStringify("sizeof a[2].b+3;"));
|
||
ASSERT_EQUALS("f ( 0 , sizeof ( ptr . bar ) ) ;", tokenizeAndStringify("f(0, sizeof ptr->bar );"));
|
||
ASSERT_EQUALS("sizeof ( a ) > sizeof ( & main ) ;", tokenizeAndStringify("sizeof a > sizeof &main;"));
|
||
}
|
||
|
||
void reportUnknownMacros() {
|
||
const char code1[] = "MY_UNKNOWN_IMP1(IInStream)\n"
|
||
"STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) { if (ptr); }";
|
||
ASSERT_THROW(tokenizeAndStringify(code1), InternalError);
|
||
|
||
const char code2[] = "void foo() { dostuff(x 0); }";
|
||
ASSERT_THROW(tokenizeAndStringify(code2), InternalError);
|
||
|
||
const char code3[] = "f(\"1\" __stringify(48) \"1\");";
|
||
ASSERT_THROW(tokenizeAndStringify(code3), InternalError);
|
||
|
||
const char code4[] = "struct Foo {\n"
|
||
" virtual MACRO(int) f1() {}\n"
|
||
" virtual MACRO(int) f2() {}\n"
|
||
"};";
|
||
ASSERT_THROW(tokenizeAndStringify(code4), InternalError);
|
||
|
||
const char code5[] = "void foo() {\n"
|
||
" EVALUATE(123, int x=a; int y=b+c;);\n"
|
||
"}";
|
||
ASSERT_THROW(tokenizeAndStringify(code5), InternalError);
|
||
|
||
const char code6[] = "void foo() { dostuff(a, .x=0); }";
|
||
ASSERT_THROW(tokenizeAndStringify(code6), InternalError);
|
||
|
||
const char code7[] = "void foo() { dostuff(ZEND_NUM_ARGS() TSRMLS_CC, x, y); }"; // #9476
|
||
ASSERT_THROW(tokenizeAndStringify(code7), InternalError);
|
||
|
||
const char code8[] = "void foo() { a = [](int x, decltype(vec) y){}; }";
|
||
ASSERT_NO_THROW(tokenizeAndStringify(code8));
|
||
}
|
||
|
||
void findGarbageCode() { // Test Tokenizer::findGarbageCode()
|
||
// C++ try/catch in global scope
|
||
ASSERT_THROW_EQUALS(tokenizeAndStringify("void f() try { }"), InternalError, "syntax error: keyword 'try' is not allowed in global scope");
|
||
|
||
// before if|for|while|switch
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void f() { do switch (a) {} while (1); }"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void f() { label: switch (a) {} }"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void f() { UNKNOWN_MACRO if (a) {} }"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void f() { []() -> int * {}; }"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void f() { const char* var = \"1\" \"2\"; }"));
|
||
|
||
ASSERT_THROW(tokenizeAndStringify("void f() { MACRO(switch); }"), InternalError);
|
||
ASSERT_THROW(tokenizeAndStringify("void f() { MACRO(x,switch); }"), InternalError);
|
||
ASSERT_THROW(tokenizeAndStringify("void foo() { for_chain( if (!done) done = 1); }"), InternalError);
|
||
ASSERT_THROW(tokenizeAndStringify("void foo() { for_chain( a, b, if (!done) done = 1); }"), InternalError);
|
||
|
||
ASSERT_THROW_EQUALS(tokenizeAndStringify("void f() { if (retval==){} }"), InternalError, "syntax error: ==)");
|
||
|
||
// after (expr)
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void f() { switch (a) int b; }"));
|
||
|
||
ASSERT_NO_THROW(tokenizeAndStringify("S s = { .x=2, .y[0]=3 };"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("S s = { .ab.a=2, .ab.b=3 };"));
|
||
|
||
ASSERT_NO_THROW(tokenizeAndStringify("extern \"C\" typedef void FUNC();"));
|
||
|
||
// Ticket #9572
|
||
ASSERT_NO_THROW(tokenizeAndStringify("struct poc { "
|
||
" struct { int d; } port[1]; "
|
||
"}; "
|
||
"struct poc p = { .port[0] = {.d = 3} };"));
|
||
|
||
// op op
|
||
ASSERT_THROW_EQUALS(tokenizeAndStringify("void f() { dostuff (x==>y); }"), InternalError, "syntax error: == >");
|
||
|
||
// Ticket #9664
|
||
ASSERT_NO_THROW(tokenizeAndStringify("S s = { .x { 2 }, .y[0] { 3 } };"));
|
||
|
||
ASSERT_THROW_EQUALS(tokenizeAndStringify("void f() { assert(a==()); }"), InternalError, "syntax error: ==()");
|
||
ASSERT_THROW_EQUALS(tokenizeAndStringify("void f() { assert(a+()); }"), InternalError, "syntax error: +()");
|
||
|
||
// #9445 - typeof is not a keyword in C
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void foo() { char *typeof, *value; }", false, false, Settings::Native, "test.c"));
|
||
}
|
||
|
||
|
||
void checkEnableIf() {
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"template<\n"
|
||
" typename U,\n"
|
||
" typename std::enable_if<\n"
|
||
" std::is_convertible<U, T>{}>::type* = nullptr>\n"
|
||
"void foo(U x);\n"));
|
||
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"template<class t>\n"
|
||
"T f(const T a, const T b) {\n"
|
||
" return a < b ? b : a;\n"
|
||
"}\n"));
|
||
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"template<class T>\n"
|
||
"struct A {\n"
|
||
" T f(const T a, const T b) {\n"
|
||
" return a < b ? b : a;\n"
|
||
" }\n"
|
||
"};\n"));
|
||
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"const int a = 1;\n"
|
||
"const int b = 2;\n"
|
||
"template<class T>\n"
|
||
"struct A {\n"
|
||
" int x = a < b ? b : a;"
|
||
"};\n"));
|
||
|
||
}
|
||
|
||
void checkTemplates() {
|
||
// #9109
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"namespace {\n"
|
||
"template <typename> struct a;\n"
|
||
"template <typename> struct b {};\n"
|
||
"}\n"
|
||
"namespace {\n"
|
||
"template <typename> struct c;\n"
|
||
"template <typename d> struct e {\n"
|
||
" using f = a< b<typename c<d>::g> >;\n"
|
||
" bool h = f::h;\n"
|
||
"};\n"
|
||
"template <typename i> using j = typename e<i>::g;\n"
|
||
"}\n"));
|
||
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"template <typename = void> struct a {\n"
|
||
" void c();\n"
|
||
"};\n"
|
||
"void f() {\n"
|
||
" a<> b;\n"
|
||
" b.a<>::c();\n"
|
||
"}\n"));
|
||
|
||
// #9138
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"template <typename> struct a;\n"
|
||
"template <bool> using c = int;\n"
|
||
"template <bool b> c<b> d;\n"
|
||
"template <> struct a<int> {\n"
|
||
"template <typename e> constexpr auto g() { d<0 || e::f>; return 0; }\n"
|
||
"};\n"));
|
||
|
||
// #9144
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"namespace a {\n"
|
||
"template <typename b, bool = __is_empty(b) && __is_final(b)> struct c;\n"
|
||
"}\n"
|
||
"namespace boost {\n"
|
||
"using a::c;\n"
|
||
"}\n"
|
||
"namespace d = boost;\n"
|
||
"using d::c;\n"
|
||
"template <typename...> struct e {};\n"
|
||
"static_assert(sizeof(e<>) == sizeof(e<c<int>, c<int>, int>), \"\");\n"));
|
||
|
||
// #9146
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"template <int> struct a;\n"
|
||
"template <class, class b> using c = typename a<int{b::d}>::e;\n"
|
||
"template <class> struct f;\n"
|
||
"template <class b> using g = typename f<c<int, b>>::e;\n"));
|
||
|
||
// #9153
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"namespace {\n"
|
||
"template <class> struct a;\n"
|
||
"}\n"
|
||
"namespace {\n"
|
||
"namespace b {\n"
|
||
"template <int c> struct B { using B<c / 2>::d; };\n"
|
||
"}\n"
|
||
"template <class, class> using e = typename b::B<int{}>;\n"
|
||
"namespace b {\n"
|
||
"template <class> struct f;\n"
|
||
"}\n"
|
||
"template <class c> using g = b::f<e<int, c>>;\n"
|
||
"}\n"));
|
||
|
||
// #9154
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"template <bool> using a = int;\n"
|
||
"template <class b> using aa = a<b::c>;\n"
|
||
"template <class...> struct A;\n"
|
||
"template <class> struct d;\n"
|
||
"template <class... f> using e = typename d<f...>::g;\n"
|
||
"template <class> struct h;\n"
|
||
"template <class, class... b> using i = typename h<b...>::g;\n"
|
||
"template <class f, template <class> class j> using k = typename f::g;\n"
|
||
"template <class... b> using l = a<k<A<b...>, aa>::c>;\n"
|
||
"template <int> struct m;\n"
|
||
"template <class, class n> using o = typename m<int{n::c}>::g;\n"
|
||
"template <class> struct p;\n"
|
||
"template <class, class n> using q = typename p<o<A<>, n>>::g;\n"
|
||
"template <class f, class r, class... b> using c = e<i<q<f, r>, b...>>;\n"
|
||
"template <class, class> struct s;\n"
|
||
"template <template <class> class t, class... w, template <class> class x,\n"
|
||
" class... u>\n"
|
||
"struct s<t<w...>, x<u...>>;\n"));
|
||
|
||
// #9156
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"template <typename> struct a;\n"
|
||
"template <bool> struct b;\n"
|
||
"template <class k, class> using d = typename b<k::c>::e;\n"
|
||
"template <class> struct f;\n"
|
||
"template <template <class> class, class... g> using i = typename f<g...>::e;\n"
|
||
"template <template <class> class h, class... g> using ab = d<i<h, g...>, int>;\n"
|
||
"template <template <class> class h, class... g> struct j {\n"
|
||
" template <class... ag> using ah = typename ab<h, ag..., g...>::e;\n"
|
||
"};\n"
|
||
"template <class> struct F;\n"
|
||
"int main() { using T = void (*)(a<j<F, char[]>>); }\n"));
|
||
|
||
// #9340
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"struct a {\n"
|
||
" template <class... b> void c(b... p1) {\n"
|
||
" using d = a;\n"
|
||
" d e = {(p1)...};\n"
|
||
" }\n"
|
||
"};\n"));
|
||
|
||
// #9858
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"struct a {\n"
|
||
" struct b {};\n"
|
||
"};\n"
|
||
"void c(a::b, a::b);\n"
|
||
"void g(a::b f) { c(f, {a::b{}}); }\n"
|
||
"template <class> void h() {\n"
|
||
" int e;\n"
|
||
" for (int d = 0; d < e; d++)\n"
|
||
" ;\n"
|
||
"}\n"));
|
||
|
||
ASSERT_NO_THROW(tokenizeAndStringify("a<b?0:1>()==3;"));
|
||
}
|
||
|
||
void checkNamespaces() {
|
||
ASSERT_NO_THROW(tokenizeAndStringify("namespace x { namespace y { namespace z {}}}"));
|
||
}
|
||
|
||
void checkLambdas() {
|
||
ASSERT_NO_THROW(tokenizeAndStringify("auto f(int& i) { return [=, &i] {}; }"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("auto f(int& i) { return [&, i] {}; }"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("auto f(int& i) { return [&, i = std::move(i)] {}; }"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("auto f(int& i) { return [=, i = std::move(i)] {}; }"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("struct c {\n"
|
||
" void d() {\n"
|
||
" int a;\n"
|
||
" auto b = [this, a] {};\n"
|
||
" }\n"
|
||
"};\n"));
|
||
|
||
// #9525
|
||
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"
|
||
" template <class b> a(b) {}\n"
|
||
"};\n"
|
||
"auto c() -> a {\n"
|
||
" return {[] {\n"
|
||
" if (0) {}\n"
|
||
" }};\n"
|
||
"}\n"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"
|
||
" template <class b> a(b) {}\n"
|
||
"};\n"
|
||
"auto c() -> a {\n"
|
||
" return {[]() -> int {\n"
|
||
" if (0) {}\n"
|
||
" return 0;\n"
|
||
" }};\n"
|
||
"}\n"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"
|
||
" template <class b> a(b) {}\n"
|
||
"};\n"
|
||
"auto c() -> a {\n"
|
||
" return {[]() mutable -> int {\n"
|
||
" if (0) {}\n"
|
||
" return 0;\n"
|
||
" }};\n"
|
||
"}\n"));
|
||
// #0535
|
||
ASSERT_NO_THROW(tokenizeAndStringify("template <typename, typename> struct a;\n"
|
||
"template <typename, typename b> void c() {\n"
|
||
" ([]() -> decltype(0) {\n"
|
||
" if (a<b, decltype(0)>::d) {}\n"
|
||
" });\n"
|
||
"}\n"));
|
||
|
||
// #9563
|
||
ASSERT_NO_THROW(tokenizeAndStringify("template <typename> struct a;\n"
|
||
"template <typename b, typename... c> struct a<b(c...)> {\n"
|
||
" template <typename d> a(d);\n"
|
||
"};\n"
|
||
"void e(\n"
|
||
" int, a<void()> f = [] {});\n"));
|
||
|
||
// #9644
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void a() {\n"
|
||
" char b[]{};\n"
|
||
" auto c = [](int d) {\n"
|
||
" for (char e = 0; d;) {}\n"
|
||
" };\n"
|
||
"}\n"));
|
||
// #9537
|
||
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"
|
||
" template <typename b> a(b) {}\n"
|
||
"};\n"
|
||
"a c{[] {\n"
|
||
" if (0) {}\n"
|
||
"}};\n"));
|
||
// #9185
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void a() {\n"
|
||
" [b = [] { ; }] {};\n"
|
||
"}\n"));
|
||
}
|
||
void checkIfCppCast() {
|
||
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"
|
||
" int b();\n"
|
||
"};\n"
|
||
"struct c {\n"
|
||
" bool d() const;\n"
|
||
" a e;\n"
|
||
"};\n"
|
||
"bool c::d() const {\n"
|
||
" int f = 0;\n"
|
||
" if (!const_cast<a *>(&e)->b()) {}\n"
|
||
" return f;\n"
|
||
"}\n"));
|
||
}
|
||
|
||
void checkRefQualifiers() {
|
||
// #9511
|
||
ASSERT_NO_THROW(tokenizeAndStringify("class a {\n"
|
||
" void b() && {\n"
|
||
" if (this) {}\n"
|
||
" }\n"
|
||
"};\n"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("class a {\n"
|
||
" void b() & {\n"
|
||
" if (this) {}\n"
|
||
" }\n"
|
||
"};\n"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("class a {\n"
|
||
" auto b() && -> void {\n"
|
||
" if (this) {}\n"
|
||
" }\n"
|
||
"};\n"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("class a {\n"
|
||
" auto b() & -> void {\n"
|
||
" if (this) {}\n"
|
||
" }\n"
|
||
"};\n"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("class a {\n"
|
||
" auto b(int& x) -> int& {\n"
|
||
" if (this) {}\n"
|
||
" return x;\n"
|
||
" }\n"
|
||
"};\n"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("class a {\n"
|
||
" auto b(int& x) -> int&& {\n"
|
||
" if (this) {}\n"
|
||
" return x;\n"
|
||
" }\n"
|
||
"};\n"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("class a {\n"
|
||
" auto b(int& x) && -> int& {\n"
|
||
" if (this) {}\n"
|
||
" return x;\n"
|
||
" }\n"
|
||
"};\n"));
|
||
// #9524
|
||
ASSERT_NO_THROW(tokenizeAndStringify("auto f() -> int* {\n"
|
||
" if (0) {}\n"
|
||
" return 0;\n"
|
||
"};\n"));
|
||
ASSERT_NO_THROW(tokenizeAndStringify("auto f() -> int** {\n"
|
||
" if (0) {}\n"
|
||
" return 0;\n"
|
||
"};\n"));
|
||
|
||
}
|
||
|
||
void checkConditionBlock() {
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void a() {\n"
|
||
" for (auto b : std::vector<std::vector<int>>{{}, {}}) {}\n"
|
||
"}\n"));
|
||
}
|
||
|
||
void noCrash1() {
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"struct A {\n"
|
||
" A( const std::string &name = "" );\n"
|
||
"};\n"
|
||
"A::A( const std::string &name ) { return; }\n"));
|
||
}
|
||
|
||
// #9007
|
||
void noCrash2() {
|
||
ASSERT_NO_THROW(tokenizeAndStringify(
|
||
"class a {\n"
|
||
"public:\n"
|
||
" enum b {};\n"
|
||
"};\n"
|
||
"struct c;\n"
|
||
"template <class> class d {\n"
|
||
" d(const int &, a::b, double, double);\n"
|
||
" d(const d &);\n"
|
||
"};\n"
|
||
"template <> d<int>::d(const int &, a::b, double, double);\n"
|
||
"template <> d<int>::d(const d &) {}\n"
|
||
"template <> d<c>::d(const d &) {}\n"));
|
||
}
|
||
|
||
void noCrash3() {
|
||
ASSERT_NO_THROW(tokenizeAndStringify("void a(X<int> x, typename Y1::Y2<int, A::B::C, 2> y, Z z = []{});"));
|
||
}
|
||
|
||
void checkConfig(const char code[]) {
|
||
errout.str("");
|
||
|
||
Settings s;
|
||
s.checkConfiguration = true;
|
||
|
||
// tokenize..
|
||
Tokenizer tokenizer(&s, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
}
|
||
|
||
void checkConfiguration() {
|
||
ASSERT_THROW(checkConfig("void f() { DEBUG(x();y()); }"), InternalError);
|
||
//ASSERT_EQUALS("[test.cpp:1]: (information) Ensure that 'DEBUG' is defined either using -I, --include or -D.\n", errout.str());
|
||
}
|
||
|
||
void unknownType() { // #8952
|
||
// Clear the error log
|
||
errout.str("");
|
||
Settings settings;
|
||
settings.debugwarnings = true;
|
||
|
||
char code[] = "class A {\n"
|
||
"public:\n"
|
||
" enum Type { Null };\n"
|
||
"};\n"
|
||
"using V = A;\n"
|
||
"V::Type value;";
|
||
|
||
// Tokenize..
|
||
Tokenizer tokenizer(&settings, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
|
||
tokenizer.printUnknownTypes();
|
||
|
||
ASSERT_EQUALS("", errout.str());
|
||
}
|
||
|
||
void unknownMacroBeforeReturn() {
|
||
ASSERT_THROW(tokenizeAndStringify("int f() { X return 0; }"), InternalError);
|
||
}
|
||
|
||
void cppcast() {
|
||
const char code[] = "a = const_cast<int>(x);\n"
|
||
"a = dynamic_cast<int>(x);\n"
|
||
"a = reinterpret_cast<int>(x);\n"
|
||
"a = static_cast<int>(x);\n";
|
||
|
||
Settings settings;
|
||
Tokenizer tokenizer(&settings, this);
|
||
std::istringstream istr(code);
|
||
tokenizer.tokenize(istr, "test.cpp");
|
||
|
||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
|
||
ASSERT_EQUALS(tok->str() == "(", tok->isCast());
|
||
}
|
||
}
|
||
|
||
std::string checkHeaders(const char code[], bool checkHeadersFlag) {
|
||
// Clear the error buffer..
|
||
errout.str("");
|
||
|
||
Settings settings;
|
||
settings.checkHeaders = checkHeadersFlag;
|
||
|
||
// Raw tokens..
|
||
std::vector<std::string> files(1, "test.cpp");
|
||
std::istringstream istr(code);
|
||
const simplecpp::TokenList tokens1(istr, files, files[0]);
|
||
|
||
// Preprocess..
|
||
simplecpp::TokenList tokens2(files);
|
||
std::map<std::string, simplecpp::TokenList*> filedata;
|
||
simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI());
|
||
|
||
Preprocessor preprocessor(settings0, nullptr);
|
||
preprocessor.setDirectives(tokens1);
|
||
|
||
// Tokenizer..
|
||
Tokenizer tokenizer(&settings, this);
|
||
tokenizer.createTokens(std::move(tokens2));
|
||
tokenizer.simplifyTokens1("");
|
||
|
||
return tokenizer.tokens()->stringifyList();
|
||
}
|
||
|
||
void checkHeader1() {
|
||
// #9977
|
||
const char code[] = "# 1 \"test.h\"\n"
|
||
"struct A {\n"
|
||
" int a = 1;\n"
|
||
" void f() { g(1); }\n"
|
||
" template <typename T> void g(T x) { a = 2; }\n" // <- template is used and should be kept
|
||
"};";
|
||
|
||
ASSERT_EQUALS("\n\n##file 1\n"
|
||
"1: struct A {\n"
|
||
"2: int a ; a = 1 ;\n"
|
||
"3: void f ( ) { g<int> ( 1 ) ; }\n"
|
||
"4: void g<int> ( int x ) ;\n"
|
||
"5: } ; void A :: g<int> ( int x ) { a = 2 ; }\n",
|
||
checkHeaders(code, true));
|
||
|
||
ASSERT_EQUALS("\n\n##file 1\n\n"
|
||
"1:\n"
|
||
"|\n"
|
||
"4:\n"
|
||
"5: ;\n",
|
||
checkHeaders(code, false));
|
||
}
|
||
};
|
||
|
||
REGISTER_TEST(TestTokenizer)
|