[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cfe-commits
Subject:    Re: [PATCH] D11778: Improvements on Diagnostic in Macro Expansions
From:       Zhengkai Wu <zhengkai () google ! com>
Date:       2015-08-06 0:58:24
Message-ID: b3d3a039281d91477594694f3f02fd7d () localhost ! localdomain
[Download RAW message or body]

zhengkai updated this revision to Diff 31425.
zhengkai added a comment.

Bug fixed


http://reviews.llvm.org/D11778

Files:
  lib/Frontend/DiagnosticRenderer.cpp
  test/Misc/diag-presumed.c
  test/Misc/reduced-diags-macros-backtrace.cpp
  test/Misc/reduced-diags-macros.cpp
  test/Preprocessor/macro_arg_slocentry_merge.c


["D11778.31425.patch" (text/x-patch)]

Index: test/Preprocessor/macro_arg_slocentry_merge.c
===================================================================
--- test/Preprocessor/macro_arg_slocentry_merge.c
+++ test/Preprocessor/macro_arg_slocentry_merge.c
@@ -3,5 +3,3 @@
 #include "macro_arg_slocentry_merge.h"
 
 // CHECK: macro_arg_slocentry_merge.h:7:19: error: unknown type name 'win'
-// CHECK: macro_arg_slocentry_merge.h:5:16: note: expanded from macro 'WINDOW'
-// CHECK: macro_arg_slocentry_merge.h:6:18: note: expanded from macro 'P_'
Index: test/Misc/reduced-diags-macros.cpp
===================================================================
--- test/Misc/reduced-diags-macros.cpp
+++ test/Misc/reduced-diags-macros.cpp
@@ -0,0 +1,29 @@
+// RUN: not %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck %s -strict-whitespace
+
+#define NO_INITIATION(x) int a = x * 2
+#define NO_DEFINITION(x) int c = x * 2
+
+NO_INITIATION(a);
+NO_DEFINITION(b);
+
+// CHECK: {{.*}}:6:15: warning: variable 'a' is uninitialized when used within its \
own initialization +// CHECK-NEXT: NO_INITIATION(a);
+// 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: {{.*}}:7:15: error: use of undeclared identifier 'b'
+// CHECK-NEXT: NO_DEFINITION(b);
+// CHECK-NEXT:               ^
+
+
+#define F(x) x + 1
+#define ADD(x,y) y + F(x)
+#define SWAP_ARGU(x,y) ADD(y,x)
+
+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:                       ^
Index: test/Misc/reduced-diags-macros-backtrace.cpp
===================================================================
--- test/Misc/reduced-diags-macros-backtrace.cpp
+++ test/Misc/reduced-diags-macros-backtrace.cpp
@@ -0,0 +1,47 @@
+// RUN: not %clang_cc1 -fsyntax-only -fmacro-backtrace-limit 0 %s 2>&1 | FileCheck \
%s --check-prefix=ALL +// RUN: not %clang_cc1 -fsyntax-only -fmacro-backtrace-limit 2 \
%s 2>&1 | FileCheck %s --check-prefix=SKIP +
+#define F(x) x + 1
+#define G(x) F(x) + 2
+#define ADD(x,y) G(x) + y
+#define LEVEL4(x) ADD(p,x)
+#define LEVEL3(x) LEVEL4(x)
+#define LEVEL2(x) LEVEL3(x)
+#define LEVEL1(x) LEVEL2(x)
+
+int a = LEVEL1(b);
+
+// ALL: {{.*}}:12:9: error: use of undeclared identifier 'p'
+// ALL-NEXT: int a = LEVEL1(b);
+// ALL-NEXT:         ^
+// ALL-NEXT: {{.*}}:10:19: note: expanded from macro 'LEVEL1'
+// ALL-NEXT: #define LEVEL1(x) LEVEL2(x)
+// ALL-NEXT:                   ^
+// ALL-NEXT: {{.*}}:9:19: note: expanded from macro 'LEVEL2'
+// ALL-NEXT: #define LEVEL2(x) LEVEL3(x)
+// ALL-NEXT:                   ^
+// ALL-NEXT: {{.*}}:8:19: note: expanded from macro 'LEVEL3'
+// ALL-NEXT: #define LEVEL3(x) LEVEL4(x)
+// ALL-NEXT:                   ^
+// ALL-NEXT: {{.*}}:7:23: note: expanded from macro 'LEVEL4'
+// ALL-NEXT: #define LEVEL4(x) ADD(p,x)
+// ALL-NEXT:                       ^
+// ALL-NEXT: {{.*}}:12:16: error: use of undeclared identifier 'b'
+// ALL-NEXT: int a = LEVEL1(b);
+// ALL-NEXT:                ^
+// ALL-NEXT: 2 errors generated.
+
+// SKIP: {{.*}}:12:9: error: use of undeclared identifier 'p'
+// SKIP-NEXT: int a = LEVEL1(b);
+// SKIP-NEXT:         ^
+// SKIP-NEXT: {{.*}}:10:19: note: expanded from macro 'LEVEL1'
+// SKIP-NEXT: #define LEVEL1(x) LEVEL2(x)
+// SKIP-NEXT:                   ^
+// SKIP-NEXT: note: (skipping 2 expansions in backtrace; use \
-fmacro-backtrace-limit=0 to see all) +// SKIP-NEXT: {{.*}}:7:23: note: expanded from \
macro 'LEVEL4' +// SKIP-NEXT: #define LEVEL4(x) ADD(p,x)
+// SKIP-NEXT:                       ^
+// SKIP-NEXT: {{.*}}:12:16: error: use of undeclared identifier 'b'
+// SKIP-NEXT: int a = LEVEL1(b);
+// SKIP-NEXT:                ^
+// SKIP-NEXT: 2 errors generated.
Index: test/Misc/diag-presumed.c
===================================================================
--- test/Misc/diag-presumed.c
+++ test/Misc/diag-presumed.c
@@ -6,13 +6,11 @@
 X(int n = error);
 
 // PRESUMED: diag-presumed.c:101:11: error: use of undeclared identifier 'error'
-// PRESUMED: diag-presumed.c:100:14: note: expanded from
 // SPELLING: diag-presumed.c:6:11: error: use of undeclared identifier 'error'
-// SPELLING: diag-presumed.c:5:14: note: expanded from
 
 ;
-// PRESUMED: diag-presumed.c:108:1: error: extra ';' outside of a functio
-// SPELLING: diag-presumed.c:13:1: error: extra ';' outside of a functio
+// PRESUMED: diag-presumed.c:106:1: error: extra ';' outside of a functio
+// SPELLING: diag-presumed.c:11:1: error: extra ';' outside of a functio
 
 # 1 "thing1.cc" 1
 # 1 "thing1.h" 1
@@ -24,13 +22,13 @@
 // SPELLING-NOT: extra ';'
 
 another error;
-// PRESUMED: included from {{.*}}diag-presumed.c:112:
+// PRESUMED: included from {{.*}}diag-presumed.c:110:
 // PRESUMED: from thing1.cc:1:
 // PRESUMED: from thing1.h:1:
 // PRESUMED: systemheader.h:7:1: error: unknown type name 'another'
 
 // SPELLING-NOT: included from
-// SPELLING: diag-presumed.c:26:1: error: unknown type name 'another'
+// SPELLING: diag-presumed.c:24:1: error: unknown type name 'another'
 
 # 1 "thing1.h" 2
 # 1 "thing1.cc" 2
Index: lib/Frontend/DiagnosticRenderer.cpp
===================================================================
--- lib/Frontend/DiagnosticRenderer.cpp
+++ lib/Frontend/DiagnosticRenderer.cpp
@@ -425,6 +425,40 @@
                  SpellingRanges, None, &SM);
 }
 
+
+static bool checkRangeForMacroArgExpansion(CharSourceRange Range,
+                                           const SourceManager &SM) {
+  SourceLocation BegLoc = Range.getBegin(), EndLoc = Range.getEnd();
+  while (BegLoc != EndLoc) {
+    if (!SM.isMacroArgExpansion(BegLoc)) return false;
+    BegLoc.getLocWithOffset(1);
+  }
+
+  return SM.isMacroArgExpansion(BegLoc);
+}
+
+/// A helper function to check if the current ranges are all inside 
+/// the macro expansions.
+
+static bool checkRangesForMacroArgExpansion(SourceLocation Loc,
+                                            ArrayRef<CharSourceRange> Ranges,
+                                            const SourceManager &SM) {
+  assert(Loc.isMacroID() && "Must be a macro expansion!");
+
+  SmallVector<CharSourceRange, 4> SpellingRanges;
+  mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
+
+  if (!SM.isMacroArgExpansion(Loc)) return false;
+
+  for (auto I = SpellingRanges.begin(), E = SpellingRanges.end();
+       I != E; ++I) {
+    if (!checkRangeForMacroArgExpansion(*I, SM))
+      return false;
+  }
+    
+  return true;
+}
+
 /// \brief Recursively emit notes for each macro expansion and caret
 /// diagnostics where appropriate.
 ///
@@ -445,12 +479,19 @@
 
   // Produce a stack of macro backtraces.
   SmallVector<SourceLocation, 8> LocationStack;
+  unsigned IgnoredEnd = 0;
   while (Loc.isMacroID()) {
     LocationStack.push_back(Loc);
+    if (checkRangesForMacroArgExpansion(Loc, Ranges, SM)) {
+        IgnoredEnd = LocationStack.size();
+    }
     Loc = SM.getImmediateMacroCallerLoc(Loc);
     assert(!Loc.isInvalid() && "must have a valid source location here");
   }
 
+  LocationStack.erase(LocationStack.begin(), 
+                      LocationStack.begin() + IgnoredEnd);
+
   unsigned MacroDepth = LocationStack.size();
   unsigned MacroLimit = DiagOpts->MacroBacktraceLimit;
   if (MacroDepth <= MacroLimit || MacroLimit == 0) {


[Attachment #4 (text/plain)]

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic