From bef82968592ec63b3371a1bf3548effa239c6281 Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Thu, 27 Aug 2015 23:38:45 +0000 Subject: [PATCH] Fix macro backtrace printing. Sometimes, a macro that expands to another macro name will not be printed in the macro backtrace. This patch finds the missed macro expansions and prints them. Fixes PR16799 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@246237 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Frontend/DiagnosticRenderer.cpp | 22 ++++++++----- test/Misc/diag-macro-backtrace2.c | 50 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 test/Misc/diag-macro-backtrace2.c diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp index 393d379048..0c94083051 100644 --- a/lib/Frontend/DiagnosticRenderer.cpp +++ b/lib/Frontend/DiagnosticRenderer.cpp @@ -399,13 +399,7 @@ void DiagnosticRenderer::emitSingleMacroExpansion( const SourceManager &SM) { // Find the spelling location for the macro definition. We must use the // spelling location here to avoid emitting a macro backtrace for the note. - SourceLocation SpellingLoc = Loc; - - // If this is the expansion of a macro argument, point the caret at the - // use of the argument in the definition of the macro, not the expansion. - if (SM.isMacroArgExpansion(Loc)) - SpellingLoc = SM.getImmediateExpansionRange(Loc).first; - SpellingLoc = SM.getSpellingLoc(SpellingLoc); + SourceLocation SpellingLoc = SM.getSpellingLoc(Loc); // Map the ranges into the FileID of the diagnostic location. SmallVector SpellingRanges; @@ -477,11 +471,23 @@ void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc, SmallVector LocationStack; unsigned IgnoredEnd = 0; while (Loc.isMacroID()) { - LocationStack.push_back(Loc); + // If this is the expansion of a macro argument, point the caret at the + // use of the argument in the definition of the macro, not the expansion. + if (SM.isMacroArgExpansion(Loc)) + LocationStack.push_back(SM.getImmediateExpansionRange(Loc).first); + else + LocationStack.push_back(Loc); + if (checkRangesForMacroArgExpansion(Loc, Ranges, SM)) IgnoredEnd = LocationStack.size(); Loc = SM.getImmediateMacroCallerLoc(Loc); + + // Once the location no longer points into a macro, try stepping through + // the last found location. This sometimes produces additional useful + // backtraces. + if (Loc.isFileID()) + Loc = SM.getImmediateMacroCallerLoc(LocationStack.back()); assert(!Loc.isInvalid() && "must have a valid source location here"); } diff --git a/test/Misc/diag-macro-backtrace2.c b/test/Misc/diag-macro-backtrace2.c new file mode 100644 index 0000000000..b5be0ae2fe --- /dev/null +++ b/test/Misc/diag-macro-backtrace2.c @@ -0,0 +1,50 @@ +// RUN: not %clang -cc1 -fsyntax-only %s 2>&1 | FileCheck %s + +#define a b +#define b c +#define c(x) d(x) +#define d(x) x*1 + +#define e f +#define f g +#define g(x) h(x) +#define h(x) x + +void PR16799() { + const char str[] = "string"; + a(str); + // CHECK: :15:3: error: invalid operands to binary expression + // CHECK: ('const char *' and 'int') + // CHECK: a(str); + // CHECK: ^ ~~~ + // CHECK: :3:11: note: expanded from macro 'a' + // CHECK: #define a b + // CHECK: ^ + // CHECK: :4:11: note: expanded from macro 'b' + // CHECK: #define b c + // CHECK: ^ + // CHECK: :5:14: note: expanded from macro 'c' + // CHECK: #define c(x) d(x) + // CHECK: ^~~~ + // CHECK: :6:15: note: expanded from macro 'd' + // CHECK: #define d(x) x*1 + // CHECK: ^~ + + e(str); + // CHECK: :33:5: warning: expression result unused + // CHECK: e(str); + // CHECK: ^~~ + // CHECK: :8:11: note: expanded from macro 'e' + // CHECK: #define e f + // CHECK: ^ + // CHECK: :9:11: note: expanded from macro 'f' + // CHECK: #define f g + // CHECK: ^ + // CHECK: :10:16: note: expanded from macro 'g' + // CHECK: #define g(x) h(x) + // CHECK: ^ + // CHECK: :11:14: note: expanded from macro 'h' + // CHECK: #define h(x) x + // CHECK: ^ +} +// CHECK: 1 warning and 1 error generated. -- 2.40.0