From: Richard Trieu Date: Thu, 24 Sep 2015 01:21:01 +0000 (+0000) Subject: Improve the printing of ranges when macros are involved. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9fed9c10d9fd6d6cff915080b104f3d481ac10aa;p=clang Improve the printing of ranges when macros are involved. Trace the ranges through the macro backtrace better. This allows better range highlighting through all levels of the macro bracktrace. Also some improvements to backtrace printer for omitting different backtraces. Patch by Zhengkai Wu. Differential Revision: http://reviews.llvm.org/D12379 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@248454 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index ec8903e139..8efcd79cbc 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -1146,10 +1146,14 @@ public: /// \brief Tests whether the given source location represents a macro /// argument's expansion into the function-like macro definition. /// + /// \param StartLoc If non-null and function returns true, it is set to the + /// start location of the macro argument expansion. + /// /// Such source locations only appear inside of the expansion /// locations representing where a particular function-like macro was /// expanded. - bool isMacroArgExpansion(SourceLocation Loc) const; + bool isMacroArgExpansion(SourceLocation Loc, + SourceLocation *StartLoc = nullptr) const; /// \brief Tests whether the given source location represents the expansion of /// a macro body. diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 32894f2eb5..5e408c98d3 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -1004,12 +1004,17 @@ SourceManager::getExpansionRange(SourceLocation Loc) const { return Res; } -bool SourceManager::isMacroArgExpansion(SourceLocation Loc) const { +bool SourceManager::isMacroArgExpansion(SourceLocation Loc, + SourceLocation *StartLoc) const { if (!Loc.isMacroID()) return false; FileID FID = getFileID(Loc); const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion(); - return Expansion.isMacroArgExpansion(); + if (!Expansion.isMacroArgExpansion()) return false; + + if (StartLoc) + *StartLoc = Expansion.getExpansionLocStart(); + return true; } bool SourceManager::isMacroBodyExpansion(SourceLocation Loc) const { diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp index 0c94083051..923d5e97c1 100644 --- a/lib/Frontend/DiagnosticRenderer.cpp +++ b/lib/Frontend/DiagnosticRenderer.cpp @@ -306,6 +306,38 @@ void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) { } } +/// A recursive function to trace all possible backtrace locations +/// to match the \p CaretLocFileID. +static SourceLocation retrieveMacroLocation(SourceLocation Loc, + FileID MacroFileID, + FileID CaretFileID, + bool getBeginLoc, + const SourceManager *SM) { + if (MacroFileID == CaretFileID) return Loc; + if (!Loc.isMacroID()) return SourceLocation(); + + SourceLocation MacroLocation, MacroArgLocation; + + if (SM->isMacroArgExpansion(Loc)) { + MacroLocation = SM->getImmediateSpellingLoc(Loc); + MacroArgLocation = getBeginLoc ? SM->getImmediateExpansionRange(Loc).first + : SM->getImmediateExpansionRange(Loc).second; + } else { + MacroLocation = getBeginLoc ? SM->getImmediateExpansionRange(Loc).first + : SM->getImmediateExpansionRange(Loc).second; + MacroArgLocation = SM->getImmediateSpellingLoc(Loc); + } + + MacroFileID = SM->getFileID(MacroLocation); + MacroLocation = retrieveMacroLocation(MacroLocation, MacroFileID, CaretFileID, + getBeginLoc, SM); + if (MacroLocation.isValid()) return MacroLocation; + + MacroFileID = SM->getFileID(MacroArgLocation); + return retrieveMacroLocation(MacroArgLocation, MacroFileID, CaretFileID, + getBeginLoc, SM); +} + // Helper function to fix up source ranges. It takes in an array of ranges, // and outputs an array of ranges where we want to draw the range highlighting // around the location specified by CaretLoc. @@ -323,9 +355,9 @@ static void mapDiagnosticRanges( const SourceManager *SM) { FileID CaretLocFileID = SM->getFileID(CaretLoc); - for (ArrayRef::const_iterator I = Ranges.begin(), - E = Ranges.end(); - I != E; ++I) { + for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { + if (I->isInvalid()) continue; + SourceLocation Begin = I->getBegin(), End = I->getEnd(); bool IsTokenRange = I->isTokenRange(); @@ -354,27 +386,17 @@ static void mapDiagnosticRanges( } } - while (Begin.isMacroID() && BeginFileID != CaretLocFileID) { - if (SM->isMacroArgExpansion(Begin)) { - Begin = SM->getImmediateSpellingLoc(Begin); - End = SM->getImmediateSpellingLoc(End); - } else { - Begin = SM->getImmediateExpansionRange(Begin).first; - End = SM->getImmediateExpansionRange(End).second; - } - BeginFileID = SM->getFileID(Begin); - if (BeginFileID != SM->getFileID(End)) { - // FIXME: Ugly hack to stop a crash; this code is making bad - // assumptions and it's too complicated for me to reason - // about. - Begin = End = SourceLocation(); - break; - } - } + // Do the backtracking. + Begin = retrieveMacroLocation(Begin, BeginFileID, CaretLocFileID, + true /*getBeginLoc*/, SM); + End = retrieveMacroLocation(End, BeginFileID, CaretLocFileID, + false /*getBeginLoc*/, SM); + if (Begin.isInvalid() || End.isInvalid()) continue; // Return the spelling location of the beginning and end of the range. Begin = SM->getSpellingLoc(Begin); End = SM->getSpellingLoc(End); + SpellingRanges.push_back(CharSourceRange(SourceRange(Begin, End), IsTokenRange)); } @@ -417,20 +439,37 @@ void DiagnosticRenderer::emitSingleMacroExpansion( SpellingRanges, None, &SM); } +/// Check that the macro argument location of Loc starts with ArgumentLoc. +/// The starting location of the macro expansions is used to differeniate +/// different macro expansions. +static bool checkLocForMacroArgExpansion(SourceLocation Loc, + const SourceManager &SM, + SourceLocation ArgumentLoc) { + SourceLocation MacroLoc; + if (SM.isMacroArgExpansion(Loc, &MacroLoc)) { + if (ArgumentLoc == MacroLoc) return true; + } + + return false; +} + +/// Check if all the locations in the range have the same macro argument +/// expansion, and that that expansion starts with ArgumentLoc. static bool checkRangeForMacroArgExpansion(CharSourceRange Range, - const SourceManager &SM) { + const SourceManager &SM, + SourceLocation ArgumentLoc) { SourceLocation BegLoc = Range.getBegin(), EndLoc = Range.getEnd(); while (BegLoc != EndLoc) { - if (!SM.isMacroArgExpansion(BegLoc)) + if (!checkLocForMacroArgExpansion(BegLoc, SM, ArgumentLoc)) return false; BegLoc.getLocWithOffset(1); } - return SM.isMacroArgExpansion(BegLoc); + return checkLocForMacroArgExpansion(BegLoc, SM, ArgumentLoc); } -/// A helper function to check if the current ranges are all inside -/// the macro expansions. +/// A helper function to check if the current ranges are all inside the same +/// macro argument expansion as Loc. static bool checkRangesForMacroArgExpansion(SourceLocation Loc, ArrayRef Ranges, const SourceManager &SM) { @@ -439,12 +478,26 @@ static bool checkRangesForMacroArgExpansion(SourceLocation Loc, SmallVector SpellingRanges; mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM); - if (!SM.isMacroArgExpansion(Loc)) + /// Count all valid ranges. + unsigned ValidCount = 0; + for (auto I : Ranges) + if (I.isValid()) ValidCount++; + + if (ValidCount > SpellingRanges.size()) return false; - for (auto I = SpellingRanges.begin(), E = SpellingRanges.end(); I != E; ++I) - if (!checkRangeForMacroArgExpansion(*I, SM)) + /// To store the source location of the argument location. + SourceLocation ArgumentLoc; + + /// Set the ArgumentLoc to the beginning location of the expansion of Loc + /// so to check if the ranges expands to the same beginning location. + if (!SM.isMacroArgExpansion(Loc,&ArgumentLoc)) + return false; + + for (auto I = SpellingRanges.begin(), E = SpellingRanges.end(); I != E; ++I) { + if (!checkRangeForMacroArgExpansion(*I, SM, ArgumentLoc)) return false; + } return true; } diff --git a/test/Index/fix-its.m b/test/Index/fix-its.m index fabcdb2905..65aa81dc86 100644 --- a/test/Index/fix-its.m +++ b/test/Index/fix-its.m @@ -20,7 +20,3 @@ void _rdar_12584554_A (volatile const void * object, volatile const void * selec @end // CHECK: FIX-IT: Insert "@" at 18:22 -// CHECK: fix-its.m:9:28: note: expanded from macro '_rdar_12584554_C' -// CHECK: Number FIX-ITs = 0 -// CHECK: fix-its.m:7:77: note: expanded from macro '_rdar_12584554_B' -// CHECK: Number FIX-ITs = 0 diff --git a/test/Misc/caret-diags-macros.c b/test/Misc/caret-diags-macros.c index 316454c513..d499400b28 100644 --- a/test/Misc/caret-diags-macros.c +++ b/test/Misc/caret-diags-macros.c @@ -16,9 +16,6 @@ void foo() { void bar() { C(1); // CHECK: {{.*}}:17:5: warning: expression result unused - // CHECK: {{.*}}:15:16: note: expanded from macro 'C' - // CHECK: {{.*}}:14:16: note: expanded from macro 'B' - // CHECK: {{.*}}:13:14: note: expanded from macro 'A' } // rdar://7597492 @@ -41,48 +38,45 @@ void baz(char *Msg) { void test() { macro_args3(11); - // CHECK: {{.*}}:43:15: warning: expression result unused + // CHECK: {{.*}}:40:15: warning: expression result unused // Also check that the 'caret' printing agrees with the location here where // its easy to FileCheck. // CHECK-NEXT: macro_args3(11); // CHECK-NEXT: {{^ \^~}} - // CHECK: {{.*}}:36:36: note: expanded from macro 'macro_args3' - // CHECK: {{.*}}:35:36: note: expanded from macro 'macro_args2' - // CHECK: {{.*}}:34:24: note: expanded from macro 'macro_args1' macro_many_args3( 1, 2, 3); - // CHECK: {{.*}}:55:5: warning: expression result unused - // CHECK: {{.*}}:40:55: note: expanded from macro 'macro_many_args3' - // CHECK: {{.*}}:39:55: note: expanded from macro 'macro_many_args2' - // CHECK: {{.*}}:38:35: note: expanded from macro 'macro_many_args1' + // CHECK: {{.*}}:49:5: warning: expression result unused + // CHECK: {{.*}}:37:55: note: expanded from macro 'macro_many_args3' + // CHECK: {{.*}}:36:55: note: expanded from macro 'macro_many_args2' + // CHECK: {{.*}}:35:35: note: expanded from macro 'macro_many_args1' macro_many_args3( 1, M2, 3); - // CHECK: {{.*}}:64:5: warning: expression result unused + // CHECK: {{.*}}:58:5: warning: expression result unused // CHECK: {{.*}}:4:12: note: expanded from macro 'M2' - // CHECK: {{.*}}:40:55: note: expanded from macro 'macro_many_args3' - // CHECK: {{.*}}:39:55: note: expanded from macro 'macro_many_args2' - // CHECK: {{.*}}:38:35: note: expanded from macro 'macro_many_args1' + // CHECK: {{.*}}:37:55: note: expanded from macro 'macro_many_args3' + // CHECK: {{.*}}:36:55: note: expanded from macro 'macro_many_args2' + // CHECK: {{.*}}:35:35: note: expanded from macro 'macro_many_args1' macro_many_args3( 1, macro_args2(22), 3); - // CHECK: {{.*}}:74:17: warning: expression result unused + // CHECK: {{.*}}:68:17: warning: expression result unused // This caret location needs to be printed *inside* a different macro's // arguments. // CHECK-NEXT: macro_args2(22), // CHECK-NEXT: {{^ \^~}} - // CHECK: {{.*}}:35:36: note: expanded from macro 'macro_args2' - // CHECK: {{.*}}:34:24: note: expanded from macro 'macro_args1' - // CHECK: {{.*}}:40:55: note: expanded from macro 'macro_many_args3' - // CHECK: {{.*}}:39:55: note: expanded from macro 'macro_many_args2' - // CHECK: {{.*}}:38:35: note: expanded from macro 'macro_many_args1' + // CHECK: {{.*}}:32:36: note: expanded from macro 'macro_args2' + // CHECK: {{.*}}:31:24: note: expanded from macro 'macro_args1' + // CHECK: {{.*}}:37:55: note: expanded from macro 'macro_many_args3' + // CHECK: {{.*}}:36:55: note: expanded from macro 'macro_many_args2' + // CHECK: {{.*}}:35:35: note: expanded from macro 'macro_many_args1' } #define variadic_args1(x, y, ...) y @@ -91,12 +85,12 @@ void test() { void test2() { variadic_args3(1, 22, 3, 4); - // CHECK: {{.*}}:93:21: warning: expression result unused + // CHECK: {{.*}}:87:21: warning: expression result unused // CHECK-NEXT: variadic_args3(1, 22, 3, 4); // CHECK-NEXT: {{^ \^~}} - // CHECK: {{.*}}:90:53: note: expanded from macro 'variadic_args3' - // CHECK: {{.*}}:89:50: note: expanded from macro 'variadic_args2' - // CHECK: {{.*}}:88:35: note: expanded from macro 'variadic_args1' + // CHECK: {{.*}}:84:53: note: expanded from macro 'variadic_args3' + // CHECK: {{.*}}:83:50: note: expanded from macro 'variadic_args2' + // CHECK: {{.*}}:82:35: note: expanded from macro 'variadic_args1' } #define variadic_pasting_args1(x, y, z) y @@ -107,35 +101,35 @@ void test2() { void test3() { variadic_pasting_args3(1, 2, 3, 4); - // CHECK: {{.*}}:109:32: warning: expression result unused - // CHECK: {{.*}}:105:72: note: expanded from macro 'variadic_pasting_args3' - // CHECK: {{.*}}:103:68: note: expanded from macro 'variadic_pasting_args2' - // CHECK: {{.*}}:102:41: note: expanded from macro 'variadic_pasting_args1' + // CHECK: {{.*}}:103:32: warning: expression result unused + // CHECK: {{.*}}:99:72: note: expanded from macro 'variadic_pasting_args3' + // CHECK: {{.*}}:97:68: note: expanded from macro 'variadic_pasting_args2' + // CHECK: {{.*}}:96:41: note: expanded from macro 'variadic_pasting_args1' variadic_pasting_args3a(1, 2, 3, 4); - // CHECK: {{.*}}:115:3: warning: expression result unused + // CHECK: {{.*}}:109:3: warning: expression result unused // CHECK-NEXT: variadic_pasting_args3a(1, 2, 3, 4); - // CHECK-NEXT: {{ \^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}} - // CHECK: {{.*}}:106:44: note: expanded from macro 'variadic_pasting_args3a' + // CHECK-NEXT: {{ \^~~~~~~~~~~~~~~~~~~~~~~}} + // CHECK: {{.*}}:100:44: note: expanded from macro 'variadic_pasting_args3a' // CHECK-NEXT: #define variadic_pasting_args3a(x, y, ...) variadic_pasting_args2a(x, y, __VA_ARGS__) - // CHECK-NEXT: {{ \^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}} - // CHECK: {{.*}}:104:70: note: expanded from macro 'variadic_pasting_args2a' + // CHECK-NEXT: {{ \^~~~~~~~~~~~~~~~~~~~~~~}} + // CHECK: {{.*}}:98:70: note: expanded from macro 'variadic_pasting_args2a' // CHECK-NEXT: #define variadic_pasting_args2a(x, y, ...) variadic_pasting_args1(x, y ## __VA_ARGS__) // CHECK-NEXT: {{ \^~~~~~~~~~~~~~~~}} - // CHECK: {{.*}}:102:41: note: expanded from macro 'variadic_pasting_args1' + // CHECK: {{.*}}:96:41: note: expanded from macro 'variadic_pasting_args1' // CHECK-NEXT: #define variadic_pasting_args1(x, y, z) y // CHECK-NEXT: {{ \^}} } #define BAD_CONDITIONAL_OPERATOR (2<3)?2:3 int test4 = BAD_CONDITIONAL_OPERATOR+BAD_CONDITIONAL_OPERATOR; -// CHECK: {{.*}}:130:39: note: expanded from macro 'BAD_CONDITIONAL_OPERATOR' +// CHECK: {{.*}}:124:39: note: expanded from macro 'BAD_CONDITIONAL_OPERATOR' // CHECK-NEXT: #define BAD_CONDITIONAL_OPERATOR (2<3)?2:3 // CHECK-NEXT: {{^ \^}} -// CHECK: {{.*}}:130:39: note: expanded from macro 'BAD_CONDITIONAL_OPERATOR' +// CHECK: {{.*}}:124:39: note: expanded from macro 'BAD_CONDITIONAL_OPERATOR' // CHECK-NEXT: #define BAD_CONDITIONAL_OPERATOR (2<3)?2:3 // CHECK-NEXT: {{^ \^}} -// CHECK: {{.*}}:130:39: note: expanded from macro 'BAD_CONDITIONAL_OPERATOR' +// CHECK: {{.*}}:124:39: note: expanded from macro 'BAD_CONDITIONAL_OPERATOR' // CHECK-NEXT: #define BAD_CONDITIONAL_OPERATOR (2<3)?2:3 // CHECK-NEXT: {{^ ~~~~~\^~~~}} @@ -143,32 +137,32 @@ int test4 = BAD_CONDITIONAL_OPERATOR+BAD_CONDITIONAL_OPERATOR; #define TWOL (2< #define X 1+TWOL 3) QMARK 4:5 int x = X; -// CHECK: {{.*}}:145:9: note: place parentheses around the '+' expression to silence this warning +// CHECK: {{.*}}:139:9: note: place parentheses around the '+' expression to silence this warning // CHECK-NEXT: int x = X; // CHECK-NEXT: {{^ \^}} -// CHECK-NEXT: {{.*}}:144:21: note: expanded from macro 'X' +// CHECK-NEXT: {{.*}}:138:21: note: expanded from macro 'X' // CHECK-NEXT: #define X 1+TWOL 3) QMARK 4:5 // CHECK-NEXT: {{^ ~~~~~~~~~ \^}} -// CHECK-NEXT: {{.*}}:142:15: note: expanded from macro 'QMARK' +// CHECK-NEXT: {{.*}}:136:15: note: expanded from macro 'QMARK' // CHECK-NEXT: #define QMARK ? // CHECK-NEXT: {{^ \^}} -// CHECK-NEXT: {{.*}}:145:9: note: place parentheses around the '?:' expression to evaluate it first +// CHECK-NEXT: {{.*}}:139:9: note: place parentheses around the '?:' expression to evaluate it first // CHECK-NEXT: int x = X; // CHECK-NEXT: {{^ \^}} -// CHECK-NEXT: {{.*}}:144:21: note: expanded from macro 'X' +// CHECK-NEXT: {{.*}}:138:21: note: expanded from macro 'X' // CHECK-NEXT: #define X 1+TWOL 3) QMARK 4:5 // CHECK-NEXT: {{^ ~~~~~~~~\^~~~~~~~~}} #define ONEPLUS 1+ #define Y ONEPLUS (2<3) QMARK 4:5 int y = Y; -// CHECK: {{.*}}:164:9: warning: operator '?:' has lower precedence than '+'; '+' will be evaluated first +// CHECK: {{.*}}:158:9: warning: operator '?:' has lower precedence than '+'; '+' will be evaluated first // CHECK-NEXT: int y = Y; // CHECK-NEXT: {{^ \^}} -// CHECK-NEXT: {{.*}}:163:25: note: expanded from macro 'Y' +// CHECK-NEXT: {{.*}}:157:25: note: expanded from macro 'Y' // CHECK-NEXT: #define Y ONEPLUS (2<3) QMARK 4:5 // CHECK-NEXT: {{^ ~~~~~~~~~~~~~ \^}} -// CHECK-NEXT: {{.*}}:142:15: note: expanded from macro 'QMARK' +// CHECK-NEXT: {{.*}}:136:15: note: expanded from macro 'QMARK' // CHECK-NEXT: #define QMARK ? // CHECK-NEXT: {{^ \^}} @@ -179,10 +173,10 @@ void foo_aa(char* s) #define /* */ BARC(c, /* */b, a) (a + b ? c : c) iequals(__LINE__, BARC(123, (456 < 345), 789), 8); } -// CHECK: {{.*}}:180:21: warning: operator '?:' has lower precedence than '+' +// CHECK: {{.*}}:174:21: warning: operator '?:' has lower precedence than '+' // CHECK-NEXT: iequals(__LINE__, BARC(123, (456 < 345), 789), 8); // CHECK-NEXT: {{^ \^~~~~~~~~~~~~~~~~~~~~~~~~~~}} -// CHECK-NEXT: {{.*}}:179:41: note: expanded from macro 'BARC' +// CHECK-NEXT: {{.*}}:173:41: note: expanded from macro 'BARC' // CHECK-NEXT: #define /* */ BARC(c, /* */b, a) (a + b ? c : c) // CHECK-NEXT: {{^ ~~~~~ \^}} @@ -193,16 +187,16 @@ void foo_aa(char* s) #if UTARG_MAX_U #endif -// CHECK: {{.*}}:193:5: warning: left side of operator converted from negative value to unsigned: -1 to 18446744073709551615 +// CHECK: {{.*}}:187:5: warning: left side of operator converted from negative value to unsigned: -1 to 18446744073709551615 // CHECK-NEXT: #if UTARG_MAX_U // CHECK-NEXT: {{^ \^~~~~~~~~~~}} -// CHECK-NEXT: {{.*}}:191:21: note: expanded from macro 'UTARG_MAX_U' +// CHECK-NEXT: {{.*}}:185:21: note: expanded from macro 'UTARG_MAX_U' // CHECK-NEXT: #define UTARG_MAX_U APPEND (MAX_UINT, UL) // CHECK-NEXT: {{^ \^~~~~~~~~~~~~~~~~~~~~}} -// CHECK-NEXT: {{.*}}:190:27: note: expanded from macro 'APPEND' +// CHECK-NEXT: {{.*}}:184:27: note: expanded from macro 'APPEND' // CHECK-NEXT: #define APPEND(NUM, SUFF) APPEND2(NUM, SUFF) // CHECK-NEXT: {{^ \^~~~~~~~~~~~~~~~~~}} -// CHECK-NEXT: {{.*}}:189:31: note: expanded from macro 'APPEND2' +// CHECK-NEXT: {{.*}}:183:31: note: expanded from macro 'APPEND2' // CHECK-NEXT: #define APPEND2(NUM, SUFF) -1 != NUM ## SUFF // CHECK-NEXT: {{^ ~~ \^ ~~~~~~~~~~~}} @@ -213,15 +207,16 @@ unsigned long strlen_test(const char *s); #define Cstrlen(a) strlen_test(a) #define Csprintf sprintf2 void f(char* pMsgBuf, char* pKeepBuf) { -Csprintf(pMsgBuf,"\nEnter minimum anagram length (2-%1d): ", Cstrlen(pKeepBuf)); +Csprintf(pMsgBuf,"\nEnter minimum anagram length (2-%1d): ", strlen_test(pKeepBuf)); +// FIXME: Change test to use 'Cstrlen' instead of 'strlen_test' when macro printing is fixed. } -// CHECK: {{.*}}:216:62: warning: format specifies type 'int' but the argument has type 'unsigned long' -// CHECK-NEXT: Csprintf(pMsgBuf,"\nEnter minimum anagram length (2-%1d): ", Cstrlen(pKeepBuf)); -// CHECK-NEXT: {{^ ~~~ \^}} +// CHECK: {{.*}}:210:62: warning: format specifies type 'int' but the argument has type 'unsigned long' +// CHECK-NEXT: Csprintf(pMsgBuf,"\nEnter minimum anagram length (2-%1d): ", strlen_test(pKeepBuf)); +// CHECK-NEXT: {{^ ~~~ \^~~~~~~~~~~~~~~~~~~~~}} // CHECK-NEXT: {{^ %1lu}} -// CHECK-NEXT: {{.*}}:213:21: note: expanded from macro 'Cstrlen' -// CHECK-NEXT: #define Cstrlen(a) strlen_test(a) +// CHECK-NEXT: {{.*}}:208:21: note: expanded from macro 'Csprintf' +// CHECK-NEXT: #define Csprintf sprintf2 // CHECK-NEXT: {{^ \^}} -// CHECK-NEXT: {{.*}}:212:56: note: expanded from macro 'sprintf2' +// CHECK-NEXT: {{.*}}:206:56: note: expanded from macro 'sprintf2' // CHECK-NEXT: __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__) -// CHECK-NEXT: {{^ \^}} +// CHECK-NEXT: {{^ \^~~~~~~~~~~}} diff --git a/test/Misc/diag-macro-backtrace2.c b/test/Misc/diag-macro-backtrace2.c index b5be0ae2fe..af79bbde60 100644 --- a/test/Misc/diag-macro-backtrace2.c +++ b/test/Misc/diag-macro-backtrace2.c @@ -16,7 +16,7 @@ void PR16799() { // CHECK: :15:3: error: invalid operands to binary expression // CHECK: ('const char *' and 'int') // CHECK: a(str); - // CHECK: ^ ~~~ + // CHECK: ^~~~~~ // CHECK: :3:11: note: expanded from macro 'a' // CHECK: #define a b // CHECK: ^ @@ -28,7 +28,7 @@ void PR16799() { // CHECK: ^~~~ // CHECK: :6:15: note: expanded from macro 'd' // CHECK: #define d(x) x*1 - // CHECK: ^~ + // CHECK: ~^~ e(str); // CHECK: :33:5: warning: expression result unused diff --git a/test/Misc/reduced-diags-macros.cpp b/test/Misc/reduced-diags-macros.cpp index d64c267a9e..1ee6311d19 100644 --- a/test/Misc/reduced-diags-macros.cpp +++ b/test/Misc/reduced-diags-macros.cpp @@ -11,7 +11,7 @@ NO_DEFINITION(b); // CHECK-NEXT: ~~~~~~~~~~~~~~^~ // CHECK-NEXT: {{.*}}:3:34: note: expanded from macro 'NO_INITIATION' // CHECK-NEXT: #define NO_INITIATION(x) int a = x * 2 -// CHECK-NEXT: ^ +// CHECK-NEXT: ~ ^ // CHECK: {{.*}}:7:15: error: use of undeclared identifier 'b' // CHECK-NEXT: NO_DEFINITION(b); @@ -27,3 +27,18 @@ int p = SWAP_ARGU(3, x); // CHECK: {{.*}}:25:23: error: use of undeclared identifier 'x' // CHECK-NEXT: int p = SWAP_ARGU(3, x); // CHECK-NEXT: ^ + +#define APPLY(f,x,y) x f y + +struct node { +}; + +node ff; + +int r = APPLY(+,ff,1); +// CHECK: {{.*}}:38:15: error: invalid operands to binary expression ('node' and 'int') +// CHECK-NEXT: int r = APPLY(+,ff,1); +// CHECK-NEXT: ^ ~~ ~ +// CHECK-NEXT: {{.*}}:31:24: note: expanded from macro 'APPLY' +// CHECK-NEXT: #define APPLY(f,x,y) x f y +// CHECK-NEXT: ~ ^ ~ \ No newline at end of file diff --git a/test/Misc/serialized-diags.c b/test/Misc/serialized-diags.c index 1290b4ea9f..e401477a2e 100644 --- a/test/Misc/serialized-diags.c +++ b/test/Misc/serialized-diags.c @@ -55,7 +55,6 @@ void rdar11040133() { // CHECK: Range: {{.*[/\\]}}serialized-diags.c:22:3 {{.*[/\\]}}serialized-diags.c:22:6 // CHECK: Range: {{.*[/\\]}}serialized-diags.c:22:13 {{.*[/\\]}}serialized-diags.c:22:18 // CHECK: +-{{.*[/\\]}}serialized-diags.c:20:15: note: expanded from macro 'false' [] -// CHECK: +-Range: {{.*[/\\]}}serialized-diags.c:22:3 {{.*[/\\]}}serialized-diags.c:22:6 // CHECK: +-Range: {{.*[/\\]}}serialized-diags.c:20:15 {{.*[/\\]}}serialized-diags.c:20:16 // CHECK: +-{{.*[/\\]}}serialized-diags.c:19:1: note: 'taz' declared here [] // CHECK: {{.*[/\\]}}serialized-diags.h:5:7: warning: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int' [-Wint-conversion]