Path: blob/main_old/src/tests/preprocessor_tests/define_test.cpp
1693 views
//1// Copyright 2012 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56#include <sstream>78#include "PreprocessorTest.h"9#include "compiler/preprocessor/Token.h"1011namespace angle12{1314using testing::_;1516class DefineTest : public SimplePreprocessorTest17{};1819TEST_F(DefineTest, NonIdentifier)20{21const char *input =22"#define 2 foo\n"23"2\n";24const char *expected =25"\n"26"2\n";2728EXPECT_CALL(mDiagnostics,29print(pp::Diagnostics::PP_UNEXPECTED_TOKEN, pp::SourceLocation(0, 1), "2"));3031preprocess(input, expected);32}3334TEST_F(DefineTest, RedefinePredefined)35{36const char *input =37"#define __LINE__ 10\n"38"__LINE__\n"39"#define __FILE__ 20\n"40"__FILE__\n"41"#define __VERSION__ 200\n"42"__VERSION__\n"43"#define GL_ES 0\n"44"GL_ES\n";45const char *expected =46"\n"47"2\n"48"\n"49"0\n"50"\n"51"100\n"52"\n"53"1\n";5455EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,56pp::SourceLocation(0, 1), "__LINE__"));57EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,58pp::SourceLocation(0, 3), "__FILE__"));59EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,60pp::SourceLocation(0, 5), "__VERSION__"));61EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,62pp::SourceLocation(0, 7), "GL_ES"));6364preprocess(input, expected);65}6667TEST_F(DefineTest, ReservedUnderScore1)68{69const char *input =70"#define __foo bar\n"71"__foo\n";72const char *expected =73"\n"74"bar\n";7576EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_WARNING_MACRO_NAME_RESERVED,77pp::SourceLocation(0, 1), "__foo"));7879preprocess(input, expected);80}8182TEST_F(DefineTest, ReservedUnderScore2)83{84const char *input =85"#define foo__bar baz\n"86"foo__bar\n";87const char *expected =88"\n"89"baz\n";9091EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_WARNING_MACRO_NAME_RESERVED,92pp::SourceLocation(0, 1), "foo__bar"));9394preprocess(input, expected);95}9697TEST_F(DefineTest, ReservedGL)98{99const char *input =100"#define GL_foo bar\n"101"GL_foo\n";102const char *expected =103"\n"104"GL_foo\n";105106EXPECT_CALL(mDiagnostics,107print(pp::Diagnostics::PP_MACRO_NAME_RESERVED, pp::SourceLocation(0, 1), "GL_foo"));108109preprocess(input, expected);110}111112TEST_F(DefineTest, ObjRedefineValid)113{114const char *input =115"#define foo (1-1)\n"116"#define foo /* whitespace */ (1-1) /* other */ \n"117"foo\n";118const char *expected =119"\n"120"\n"121"(1-1)\n";122// No error or warning.123using testing::_;124EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);125126preprocess(input, expected);127}128129TEST_F(DefineTest, ObjRedefineInvalid)130{131const char *input =132"#define foo (0)\n"133"#define foo (1-1)\n"134"foo\n";135const char *expected =136"\n"137"\n"138"(0)\n";139140EXPECT_CALL(mDiagnostics,141print(pp::Diagnostics::PP_MACRO_REDEFINED, pp::SourceLocation(0, 2), "foo"));142143preprocess(input, expected);144}145146TEST_F(DefineTest, FuncRedefineValid)147{148const char *input =149"#define foo(a) ( a )\n"150"#define foo( a )( /* whitespace */ a /* other */ )\n"151"foo(b)\n";152const char *expected =153"\n"154"\n"155"( b )\n";156// No error or warning.157using testing::_;158EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);159160preprocess(input, expected);161}162163TEST_F(DefineTest, FuncRedefineInvalid)164{165const char *input =166"#define foo(b) ( a )\n"167"#define foo(b) ( b )\n"168"foo(1)\n";169const char *expected =170"\n"171"\n"172"( a )\n";173174EXPECT_CALL(mDiagnostics,175print(pp::Diagnostics::PP_MACRO_REDEFINED, pp::SourceLocation(0, 2), "foo"));176177preprocess(input, expected);178}179180TEST_F(DefineTest, ObjBasic)181{182const char *input =183"#define foo 1\n"184"foo\n";185const char *expected =186"\n"187"1\n";188189preprocess(input, expected);190}191192TEST_F(DefineTest, ObjEmpty)193{194const char *input =195"#define foo\n"196"foo\n";197const char *expected =198"\n"199"\n";200201preprocess(input, expected);202}203204TEST_F(DefineTest, ObjChain)205{206const char *input =207"#define foo 1\n"208"#define bar foo\n"209"bar\n";210const char *expected =211"\n"212"\n"213"1\n";214215preprocess(input, expected);216}217218TEST_F(DefineTest, ObjChainReverse)219{220const char *input =221"#define bar foo\n"222"#define foo 1\n"223"bar\n";224const char *expected =225"\n"226"\n"227"1\n";228229preprocess(input, expected);230}231232TEST_F(DefineTest, ObjRecursive)233{234const char *input =235"#define foo bar\n"236"#define bar baz\n"237"#define baz foo\n"238"foo\n"239"bar\n"240"baz\n";241const char *expected =242"\n"243"\n"244"\n"245"foo\n"246"bar\n"247"baz\n";248249preprocess(input, expected);250}251252TEST_F(DefineTest, ObjCompositeChain)253{254const char *input =255"#define foo 1\n"256"#define bar a foo\n"257"bar\n";258const char *expected =259"\n"260"\n"261"a 1\n";262263preprocess(input, expected);264}265266TEST_F(DefineTest, ObjCompositeChainReverse)267{268const char *input =269"#define bar a foo\n"270"#define foo 1\n"271"bar\n";272const char *expected =273"\n"274"\n"275"a 1\n";276277preprocess(input, expected);278}279280TEST_F(DefineTest, ObjCompositeRecursive)281{282const char *input =283"#define foo a bar\n"284"#define bar b baz\n"285"#define baz c foo\n"286"foo\n"287"bar\n"288"baz\n";289const char *expected =290"\n"291"\n"292"\n"293"a b c foo\n"294"b c a bar\n"295"c a b baz\n";296297preprocess(input, expected);298}299300TEST_F(DefineTest, ObjChainSelfRecursive)301{302const char *input =303"#define foo foo\n"304"#define bar foo\n"305"bar\n";306const char *expected =307"\n"308"\n"309"foo\n";310311preprocess(input, expected);312}313314TEST_F(DefineTest, ObjectLikeWithParens)315{316const char *input =317"#define foo ()1\n"318"foo()\n"319"#define bar ()2\n"320"bar()\n";321const char *expected =322"\n"323"()1()\n"324"\n"325"()2()\n";326327preprocess(input, expected);328}329330TEST_F(DefineTest, FuncEmpty)331{332const char *input =333"#define foo()\n"334"foo()\n";335const char *expected =336"\n"337"\n";338339preprocess(input, expected);340}341342TEST_F(DefineTest, FuncNoArgs)343{344const char *input =345"#define foo() bar\n"346"foo()\n";347const char *expected =348"\n"349"bar\n";350351preprocess(input, expected);352}353354TEST_F(DefineTest, FuncOneArgUnused)355{356const char *input =357"#define foo(x) 1\n"358"foo(bar)\n";359const char *expected =360"\n"361"1\n";362363preprocess(input, expected);364}365366TEST_F(DefineTest, FuncTwoArgsUnused)367{368const char *input =369"#define foo(x,y) 1\n"370"foo(bar,baz)\n";371const char *expected =372"\n"373"1\n";374375preprocess(input, expected);376}377378TEST_F(DefineTest, FuncOneArg)379{380const char *input =381"#define foo(x) ((x)+1)\n"382"foo(bar)\n";383const char *expected =384"\n"385"((bar)+1)\n";386387preprocess(input, expected);388}389390TEST_F(DefineTest, FuncTwoArgs)391{392const char *input =393"#define foo(x,y) ((x)*(y))\n"394"foo(bar,baz)\n";395const char *expected =396"\n"397"((bar)*(baz))\n";398399preprocess(input, expected);400}401402TEST_F(DefineTest, FuncEmptyArgs)403{404const char *input =405"#define zero() pass\n"406"#define one(x) pass\n"407"#define two(x,y) pass\n"408"zero()\n"409"one()\n"410"two(,)\n";411const char *expected =412"\n"413"\n"414"\n"415"pass\n"416"pass\n"417"pass\n";418419preprocess(input, expected);420}421422TEST_F(DefineTest, FuncMacroAsParam)423{424const char *input =425"#define x 0\n"426"#define foo(x) x\n"427"foo(1)\n";428const char *expected =429"\n"430"\n"431"1\n";432433preprocess(input, expected);434}435436TEST_F(DefineTest, FuncOneArgMulti)437{438const char *input =439"#define foo(x) (x)\n"440"foo(this is a multi-word argument)\n";441const char *expected =442"\n"443"(this is a multi-word argument)\n";444445preprocess(input, expected);446}447448TEST_F(DefineTest, FuncTwoArgsMulti)449{450const char *input =451"#define foo(x,y) x,two fish,red fish,y\n"452"foo(one fish, blue fish)\n";453const char *expected =454"\n"455"one fish,two fish,red fish,blue fish\n";456457preprocess(input, expected);458}459460TEST_F(DefineTest, FuncCompose)461{462const char *input =463"#define bar(x) (1+(x))\n"464"#define foo(y) (2*(y))\n"465"foo(bar(3))\n";466const char *expected =467"\n"468"\n"469"(2*((1+(3))))\n";470471preprocess(input, expected);472}473474TEST_F(DefineTest, FuncArgWithParens)475{476const char *input =477"#define foo(x) (x)\n"478"foo(argument(with parens) FTW)\n";479const char *expected =480"\n"481"(argument(with parens) FTW)\n";482483preprocess(input, expected);484}485486TEST_F(DefineTest, FuncMacroAsNonMacro)487{488const char *input =489"#define foo(bar) bar\n"490"foo bar\n";491const char *expected =492"\n"493"foo bar\n";494495preprocess(input, expected);496}497498TEST_F(DefineTest, FuncExtraNewlines)499{500const char *input =501"#define foo(a) (a)\n"502"foo\n"503"(\n"504"1\n"505")\n";506const char *expected =507"\n"508"\n"509"\n"510"\n"511"(1)\n";512513preprocess(input, expected);514}515516TEST_F(DefineTest, ChainObjToFunc)517{518const char *input =519"#define foo() pass\n"520"#define bar foo()\n"521"bar\n";522const char *expected =523"\n"524"\n"525"pass\n";526527preprocess(input, expected);528}529530TEST_F(DefineTest, ChainObjToNonFunc)531{532const char *input =533"#define pass() fail\n"534"#define bar pass\n"535"bar\n";536const char *expected =537"\n"538"\n"539"pass\n";540541preprocess(input, expected);542}543544TEST_F(DefineTest, ChainObjToFuncWithArgs)545{546const char *input =547"#define foo(fail) fail\n"548"#define bar foo(pass)\n"549"bar\n";550const char *expected =551"\n"552"\n"553"pass\n";554555preprocess(input, expected);556}557558TEST_F(DefineTest, ChainObjToFuncCompose)559{560const char *input =561"#define baz(fail) fail\n"562"#define bar(fail) fail\n"563"#define foo bar(baz(pass))\n"564"foo\n";565const char *expected =566"\n"567"\n"568"\n"569"pass\n";570571preprocess(input, expected);572}573574TEST_F(DefineTest, ChainObjToFuncParensInText1)575{576const char *input =577"#define fail() pass\n"578"#define foo fail\n"579"foo()\n";580const char *expected =581"\n"582"\n"583"pass\n";584585preprocess(input, expected);586}587588TEST_F(DefineTest, ChainObjToFuncParensInText2)589{590const char *input =591"#define bar with,embedded,commas\n"592"#define func(x) pass\n"593"#define foo func\n"594"foo(bar)\n";595const char *expected =596"\n"597"\n"598"\n"599"pass\n";600601preprocess(input, expected);602}603604TEST_F(DefineTest, ChainObjToFuncMultiLevel)605{606const char *input =607"#define foo(x) pass\n"608"#define bar foo\n"609"#define baz bar\n"610"#define joe baz\n"611"joe (fail)\n";612const char *expected =613"\n"614"\n"615"\n"616"\n"617"pass\n";618619preprocess(input, expected);620}621622TEST_F(DefineTest, ObjToFuncRecursive)623{624const char *input =625"#define A(a,b) B(a,b)\n"626"#define C A(0,C)\n"627"C\n";628const char *expected =629"\n"630"\n"631"B(0,C)\n";632633preprocess(input, expected);634}635636TEST_F(DefineTest, ChainFuncToFuncCompose)637{638const char *input =639"#define baz(fail) fail\n"640"#define bar(fail) fail\n"641"#define foo() bar(baz(pass))\n"642"foo()\n";643const char *expected =644"\n"645"\n"646"\n"647"pass\n";648649preprocess(input, expected);650}651652TEST_F(DefineTest, FuncSelfRecursive)653{654const char *input =655"#define foo(a) foo(2*(a))\n"656"foo(3)\n";657const char *expected =658"\n"659"foo(2*(3))\n";660661preprocess(input, expected);662}663664TEST_F(DefineTest, FuncSelfCompose)665{666const char *input =667"#define foo(a) foo(2*(a))\n"668"foo(foo(3))\n";669const char *expected =670"\n"671"foo(2*(foo(2*(3))))\n";672673preprocess(input, expected);674}675676TEST_F(DefineTest, FuncSelfComposeNonFunc)677{678const char *input =679"#define foo(bar) bar\n"680"foo(foo)\n";681const char *expected =682"\n"683"foo\n";684685preprocess(input, expected);686}687688TEST_F(DefineTest, FuncSelfComposeNonFuncMultiTokenArg)689{690const char *input =691"#define foo(bar) bar\n"692"foo(1+foo)\n";693const char *expected =694"\n"695"1+foo\n";696697preprocess(input, expected);698}699700TEST_F(DefineTest, FinalizeUnexpandedMacro)701{702const char *input =703"#define expand(x) expand(x once)\n"704"#define foo(x) x\n"705"foo(expand(just))\n";706const char *expected =707"\n"708"\n"709"expand(just once)\n";710711preprocess(input, expected);712}713714TEST_F(DefineTest, FuncArgWithCommas)715{716const char *input =717"#define foo(x) pass\n"718"foo(argument (with,embedded, commas) -- baz)\n";719const char *expected =720"\n"721"pass\n";722723preprocess(input, expected);724}725726TEST_F(DefineTest, FuncArgObjMaroWithComma)727{728const char *input =729"#define foo(a) (a)\n"730"#define bar two,words\n"731"foo(bar)\n";732const char *expected =733"\n"734"\n"735"(two,words)\n";736737preprocess(input, expected);738}739740TEST_F(DefineTest, FuncLeftParenInMacroRightParenInText)741{742const char *input =743"#define bar(a) a*2\n"744"#define foo bar(\n"745"foo b)\n";746const char *expected =747"\n"748"\n"749"b*2\n";750751preprocess(input, expected);752}753754TEST_F(DefineTest, RepeatedArg)755{756const char *input =757"#define double(x) x x\n"758"double(1)\n";759const char *expected =760"\n"761"1 1\n";762763preprocess(input, expected);764}765766TEST_F(DefineTest, FuncMissingRightParen)767{768const char *input =769"#define foo(x) (2*(x))\n"770"foo(3\n";771const char *expected =772"\n"773"\n";774775EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION,776pp::SourceLocation(0, 2), "foo"));777778preprocess(input, expected);779}780781TEST_F(DefineTest, FuncIncorrectArgCount)782{783const char *input =784"#define foo(x,y) ((x)+(y))\n"785"foo()\n"786"foo(1)\n"787"foo(1,2,3)\n";788const char *expected =789"\n"790"\n"791"\n"792"\n";793794EXPECT_CALL(mDiagnostics,795print(pp::Diagnostics::PP_MACRO_TOO_FEW_ARGS, pp::SourceLocation(0, 2), "foo"));796EXPECT_CALL(mDiagnostics,797print(pp::Diagnostics::PP_MACRO_TOO_FEW_ARGS, pp::SourceLocation(0, 3), "foo"));798EXPECT_CALL(mDiagnostics,799print(pp::Diagnostics::PP_MACRO_TOO_MANY_ARGS, pp::SourceLocation(0, 4), "foo"));800801preprocess(input, expected);802}803804TEST_F(DefineTest, Undef)805{806const char *input =807"#define foo 1\n"808"foo\n"809"#undef foo\n"810"foo\n";811const char *expected =812"\n"813"1\n"814"\n"815"foo\n";816817preprocess(input, expected);818}819820TEST_F(DefineTest, UndefPredefined)821{822const char *input =823"#undef __LINE__\n"824"__LINE__\n"825"#undef __FILE__\n"826"__FILE__\n"827"#undef __VERSION__\n"828"__VERSION__\n"829"#undef GL_ES\n"830"GL_ES\n";831const char *expected =832"\n"833"2\n"834"\n"835"0\n"836"\n"837"100\n"838"\n"839"1\n";840841EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,842pp::SourceLocation(0, 1), "__LINE__"));843EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,844pp::SourceLocation(0, 3), "__FILE__"));845EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,846pp::SourceLocation(0, 5), "__VERSION__"));847EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,848pp::SourceLocation(0, 7), "GL_ES"));849850preprocess(input, expected);851}852853TEST_F(DefineTest, UndefRedefine)854{855const char *input =856"#define foo 1\n"857"foo\n"858"#undef foo\n"859"foo\n"860"#define foo 2\n"861"foo\n";862const char *expected =863"\n"864"1\n"865"\n"866"foo\n"867"\n"868"2\n";869870preprocess(input, expected);871}872873// Example from C99 standard section 6.10.3.5 Scope of macro definitions874TEST_F(DefineTest, C99Example)875{876const char *input =877"#define x 3 \n"878"#define f(a) f(x * (a)) \n"879"#undef x \n"880"#define x 2 \n"881"#define g f \n"882"#define z z[0] \n"883"#define h g(~ \n"884"#define m(a) a(w) \n"885"#define w 0,1 \n"886"#define t(a) a \n"887"#define p() int \n"888"#define q(x) x \n"889" \n"890"f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);\n"891"g(x+(3,4)-w) | h 5) & m\n"892" (f)^m(m);\n"893"p() i[q()] = { q(1), 23, 4, 5, };\n";894const char *expected =895"\n"896"\n"897"\n"898"\n"899"\n"900"\n"901"\n"902"\n"903"\n"904"\n"905"\n"906"\n"907"\n"908"f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);\n"909"f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) &\n"910" f(2 * (0,1))^m(0,1);\n"911"int i[] = { 1, 23, 4, 5, };\n";912913preprocess(input, expected);914}915916TEST_F(DefineTest, Predefined_GL_ES)917{918const char *input = "GL_ES\n";919const char *expected = "1\n";920921preprocess(input, expected);922}923924TEST_F(DefineTest, Predefined_VERSION)925{926const char *input = "__VERSION__\n";927const char *expected = "100\n";928929preprocess(input, expected);930}931932TEST_F(DefineTest, Predefined_LINE1)933{934const char *str = "\n\n__LINE__";935936pp::Token token;937lexSingleToken(str, &token);938EXPECT_EQ(pp::Token::CONST_INT, token.type);939EXPECT_EQ("3", token.text);940}941942TEST_F(DefineTest, Predefined_LINE2)943{944const char *str =945"#line 10\n"946"__LINE__\n";947948pp::Token token;949lexSingleToken(str, &token);950EXPECT_EQ(pp::Token::CONST_INT, token.type);951EXPECT_EQ("10", token.text);952}953954TEST_F(DefineTest, Predefined_FILE1)955{956const char *const str[] = {"", "", "__FILE__"};957958pp::Token token;959lexSingleToken(3, str, &token);960EXPECT_EQ(pp::Token::CONST_INT, token.type);961EXPECT_EQ("2", token.text);962}963964TEST_F(DefineTest, Predefined_FILE2)965{966const char *const str[] = {"#line 10 20\n", "__FILE__"};967968pp::Token token;969lexSingleToken(2, str, &token);970EXPECT_EQ(pp::Token::CONST_INT, token.type);971EXPECT_EQ("21", token.text);972}973974// Defined operator produced by macro expansion should be parsed inside #if directives975TEST_F(DefineTest, ExpandedDefinedParsedInsideIf)976{977const char *input =978"#define bar 1\n"979"#define foo defined(bar)\n"980"#if foo\n"981"bar\n"982"#endif\n";983const char *expected =984"\n"985"\n"986"\n"987"1\n"988"\n";989preprocess(input, expected);990}991992// Defined operator produced by macro expansion should not be parsed outside #if directives993TEST_F(DefineTest, ExpandedDefinedNotParsedOutsideIf)994{995const char *input =996"#define foo defined(bar)\n"997"foo\n";998const char *expected =999"\n"1000"defined(bar)\n";1001preprocess(input, expected);1002}10031004// Test that line directive expressions give errors on negative or undefined shifts.1005TEST_F(DefineTest, NegativeShiftInLineDirective)1006{1007const char *input =1008"#line 1 << -1\n"1009"#line 1 >> -1\n"1010"#line 1 << x\n"1011"#line 1 >> x\n";1012const char *expected =1013"\n"1014"\n"1015"\n"1016"\n";10171018EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_UNDEFINED_SHIFT, _, _)).Times(4);1019EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_INVALID_LINE_NUMBER, _, _)).Times(2);1020preprocess(input, expected);1021}10221023// Undefining a macro in its invocation parameters produces and error1024TEST_F(DefineTest, UndefineInInvocation)1025{1026const char *input =1027"#define G(a, b) a b\n"1028"G(\n"1029"#undef G\n"1030"1, 2)\n";1031const char *expected = "\n\n\n1 2\n";10321033EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED,1034pp::SourceLocation(0, 3), _));10351036preprocess(input, expected);1037}10381039// Undefining a macro before its invocation parameters produces and error1040TEST_F(DefineTest, UndefineInInvocationPreLParen)1041{1042const char *input =1043"#define G(a, b) a b\n"1044"G\n"1045"#undef G\n"1046"(1, 2)\n";1047const char *expected = "\n\n\n1 2\n";10481049EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED,1050pp::SourceLocation(0, 3), _));10511052preprocess(input, expected);1053}10541055// The name of the macro "a" is inside an incomplete macro invocation of macro "m()" in its own1056// expansion. This should not result in infinite recursion.1057TEST_F(DefineTest, RecursiveMacroNameInsideIncompleteMacroInvocationInMacroExpansion)1058{1059const char *input =1060"#define m(a)\n"1061"#define a m((a)\n"1062"a)\n";1063const char *expected =1064"\n"1065"\n"1066"\n";1067preprocess(input, expected);1068}10691070// The name of the macro "a" is inside an incomplete macro invocation of macro "m()" in its own1071// expansion. Then the macro "a" is undef'd. This is a regression test for a memory management bug1072// where macro "a" would be freed on undef even though cleaning up the recursive macro invocation1073// would still need to refer to macro "a".1074TEST_F(DefineTest, UndefInsideRecursiveMacroInvocation)1075{1076const char *input =1077"#define m(a)\n"1078"#define a m((a)\n"1079"a\n"1080"#undef a\n"1081")\n";1082const char *expected =1083"\n"1084"\n"1085"\n"1086"\n"1087"\n";1088preprocess(input, expected);1089}10901091// The macro invocations form a long chain. The macro expander should protect against stack overflow1092// and generate an error in this case.1093TEST_F(DefineTest, LongMacroInvocationChain)1094{1095std::stringstream inputStream;1096std::stringstream expectedStream;10971098inputStream << "#define b(x) x\n";1099inputStream << "#define a0(x) foo x\n";1100for (int i = 1; i < 20; ++i)1101{1102inputStream << "#define a" << i << "(x) b(a" << (i - 1) << "(x))\n";1103}1104inputStream << "a19(y)\n";11051106EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_INVOCATION_CHAIN_TOO_DEEP,1107pp::SourceLocation(0, 22), _));11081109pp::PreprocessorSettings settings(SH_GLES2_SPEC);1110settings.maxMacroExpansionDepth = 19;11111112preprocess(inputStream.str().c_str(), settings);1113}11141115} // namespace angle111611171118