diff options
| author | Richard Trieu <rtrieu@google.com> | 2015-08-27 23:38:45 +0000 |
|---|---|---|
| committer | Richard Trieu <rtrieu@google.com> | 2015-08-27 23:38:45 +0000 |
| commit | a1d7ece05c9b4b33c45aea08efc5ac861052fed5 (patch) | |
| tree | 95a6c623c8671985cf392a16a36d28ef71fd7313 /clang | |
| parent | c269ed511584d9044a4e28a25fa6a0d24df68a9f (diff) | |
| download | bcm5719-llvm-a1d7ece05c9b4b33c45aea08efc5ac861052fed5.tar.gz bcm5719-llvm-a1d7ece05c9b4b33c45aea08efc5ac861052fed5.zip | |
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
llvm-svn: 246237
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Frontend/DiagnosticRenderer.cpp | 22 | ||||
| -rw-r--r-- | clang/test/Misc/diag-macro-backtrace2.c | 50 |
2 files changed, 64 insertions, 8 deletions
diff --git a/clang/lib/Frontend/DiagnosticRenderer.cpp b/clang/lib/Frontend/DiagnosticRenderer.cpp index 393d379048c..0c94083051d 100644 --- a/clang/lib/Frontend/DiagnosticRenderer.cpp +++ b/clang/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<CharSourceRange, 4> SpellingRanges; @@ -477,11 +471,23 @@ void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc, SmallVector<SourceLocation, 8> 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/clang/test/Misc/diag-macro-backtrace2.c b/clang/test/Misc/diag-macro-backtrace2.c new file mode 100644 index 00000000000..b5be0ae2fef --- /dev/null +++ b/clang/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. |

