r319408 - Preserve the "last diagnostic was suppressed" flag across SFINAE checks.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 30 00:18:21 PST 2017


Author: rsmith
Date: Thu Nov 30 00:18:21 2017
New Revision: 319408

URL: http://llvm.org/viewvc/llvm-project?rev=319408&view=rev
Log:
Preserve the "last diagnostic was suppressed" flag across SFINAE checks.

Sometimes we check the validity of some construct between producing a
diagnostic and producing its notes. Ideally, we wouldn't do that, but in
practice running code that "cannot possibly produce a diagnostic" in such a
situation should be safe, and reasonable factoring of some code requires it
with our current diagnostics infrastruture. If this does happen, a diagnostic
that's suppressed due to SFINAE should not cause notes connected to the prior
diagnostic to be suppressed.

Modified:
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/test/CXX/drs/dr4xx.cpp
    cfe/trunk/test/SemaCXX/overload-call.cpp

Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=319408&r1=319407&r2=319408&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Thu Nov 30 00:18:21 2017
@@ -575,13 +575,15 @@ public:
   OverloadsShown getShowOverloads() const { return ShowOverloads; }
   
   /// \brief Pretend that the last diagnostic issued was ignored, so any
-  /// subsequent notes will be suppressed.
+  /// subsequent notes will be suppressed, or restore a prior ignoring
+  /// state after ignoring some diagnostics and their notes, possibly in
+  /// the middle of another diagnostic.
   ///
   /// This can be used by clients who suppress diagnostics themselves.
-  void setLastDiagnosticIgnored() {
+  void setLastDiagnosticIgnored(bool Ignored = true) {
     if (LastDiagLevel == DiagnosticIDs::Fatal)
       FatalErrorOccurred = true;
-    LastDiagLevel = DiagnosticIDs::Ignored;
+    LastDiagLevel = Ignored ? DiagnosticIDs::Ignored : DiagnosticIDs::Warning;
   }
 
   /// \brief Determine whether the previous diagnostic was ignored. This can

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=319408&r1=319407&r2=319408&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Nov 30 00:18:21 2017
@@ -7428,13 +7428,16 @@ public:
     unsigned PrevSFINAEErrors;
     bool PrevInNonInstantiationSFINAEContext;
     bool PrevAccessCheckingSFINAE;
+    bool PrevLastDiagnosticIgnored;
 
   public:
     explicit SFINAETrap(Sema &SemaRef, bool AccessCheckingSFINAE = false)
       : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors),
         PrevInNonInstantiationSFINAEContext(
                                       SemaRef.InNonInstantiationSFINAEContext),
-        PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE)
+        PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE),
+        PrevLastDiagnosticIgnored(
+            SemaRef.getDiagnostics().isLastDiagnosticIgnored())
     {
       if (!SemaRef.isSFINAEContext())
         SemaRef.InNonInstantiationSFINAEContext = true;
@@ -7446,6 +7449,8 @@ public:
       SemaRef.InNonInstantiationSFINAEContext
         = PrevInNonInstantiationSFINAEContext;
       SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE;
+      SemaRef.getDiagnostics().setLastDiagnosticIgnored(
+          PrevLastDiagnosticIgnored);
     }
 
     /// \brief Determine whether any SFINAE errors have been trapped.

Modified: cfe/trunk/test/CXX/drs/dr4xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?rev=319408&r1=319407&r2=319408&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr4xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr4xx.cpp Thu Nov 30 00:18:21 2017
@@ -22,6 +22,9 @@ namespace dr401 { // dr401: yes
   class B {
   protected:
     typedef int type; // expected-note {{protected}}
+#if __cplusplus == 199711L
+    // expected-note at -2 {{protected}}
+#endif
   };
 
   class C {

Modified: cfe/trunk/test/SemaCXX/overload-call.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-call.cpp?rev=319408&r1=319407&r2=319408&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/overload-call.cpp (original)
+++ cfe/trunk/test/SemaCXX/overload-call.cpp Thu Nov 30 00:18:21 2017
@@ -658,3 +658,11 @@ namespace StringLiteralToCharAmbiguity {
   // expected-note at -5 {{candidate function}}
 #endif
 }
+
+namespace ProduceNotesAfterSFINAEFailure {
+  struct A {
+    template<typename T, typename U = typename T::x> A(T); // expected-warning 0-1{{extension}}
+  };
+  void f(void*, A); // expected-note {{candidate function not viable}}
+  void g() { f(1, 2); } // expected-error {{no matching function}}
+}




More information about the cfe-commits mailing list