[clang] d4f0978 - [clang] More informative mixed namespace diagnostics

Nathan Sidwell via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 2 09:24:28 PST 2022


Author: Nathan Sidwell
Date: 2022-01-02T12:23:13-05:00
New Revision: d4f09786e079361eba1ade1e351be8771d016f29

URL: https://github.com/llvm/llvm-project/commit/d4f09786e079361eba1ade1e351be8771d016f29
DIFF: https://github.com/llvm/llvm-project/commit/d4f09786e079361eba1ade1e351be8771d016f29.diff

LOG: [clang] More informative mixed namespace diagnostics

First, let's check we get a TemplateDecl, before complaining about
where it might have been found.

Second, if it came from an unexpected place, show where that location is.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D116164

Added: 
    

Modified: 
    clang/lib/Sema/SemaCoroutine.cpp
    clang/test/SemaCXX/co_await-range-for-exp-namespace.cpp
    clang/test/SemaCXX/coreturn-eh-exp-namespace.cpp
    clang/test/SemaCXX/coreturn-exp-namespace.cpp
    clang/test/SemaCXX/coroutine-final-suspend-noexcept-exp-namespace.cpp
    clang/test/SemaCXX/coroutine-mixed-exp-namespace.cpp
    clang/test/SemaCXX/coroutine-mixed2-exp-namespace.cpp
    clang/test/SemaCXX/coroutine-rvo-exp-namespace.cpp
    clang/test/SemaCXX/coroutine-seh-exp-namespace.cpp
    clang/test/SemaCXX/coroutine-traits-undefined-template-exp-namespace.cpp
    clang/test/SemaCXX/coroutine-unhandled_exception-warning-exp-namespace.cpp
    clang/test/SemaCXX/coroutine_handle-address-return-type-exp-namespace.cpp
    clang/test/SemaCXX/coroutines-exp-namespace.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index e89cecd08ccae..3a6d9f0b9f265 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -1740,30 +1740,38 @@ ClassTemplateDecl *Sema::lookupCoroutineTraits(SourceLocation KwLoc,
       return nullptr;
     }
 
-    if (!InStd) {
-      // Found only in std::experimental.
-      Diag(KwLoc, diag::warn_deprecated_coroutine_namespace)
-          << "coroutine_traits";
-    } else if (InExp) {
-      // Found in std and std::experimental.
-      Diag(KwLoc,
-           diag::err_mixed_use_std_and_experimental_namespace_for_coroutine);
-      Diag(KwLoc, diag::warn_deprecated_coroutine_namespace)
-          << "coroutine_traits";
-      return nullptr;
-    }
-
     // Prefer ::std to std::experimental.
     auto &Result = InStd ? ResStd : ResExp;
     CoroTraitsNamespaceCache = InStd ? StdSpace : ExpSpace;
 
     // coroutine_traits is required to be a class template.
-    if (!(StdCoroutineTraitsCache = Result.getAsSingle<ClassTemplateDecl>())) {
+    StdCoroutineTraitsCache = Result.getAsSingle<ClassTemplateDecl>();
+    if (!StdCoroutineTraitsCache) {
       Result.suppressDiagnostics();
       NamedDecl *Found = *Result.begin();
       Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
       return nullptr;
     }
+
+    if (InExp) {
+      // Found in std::experimental
+      Diag(KwLoc, diag::warn_deprecated_coroutine_namespace)
+          << "coroutine_traits";
+      ResExp.suppressDiagnostics();
+      auto *Found = *ResExp.begin();
+      Diag(Found->getLocation(), diag::note_entity_declared_at) << Found;
+
+      if (InStd) {
+        // Also found in std
+        Diag(KwLoc,
+             diag::err_mixed_use_std_and_experimental_namespace_for_coroutine);
+        Diag(StdCoroutineTraitsCache->getLocation(),
+             diag::note_entity_declared_at)
+            << StdCoroutineTraitsCache;
+
+        return nullptr;
+      }
+    }
   }
   Namespace = CoroTraitsNamespaceCache;
   return StdCoroutineTraitsCache;

diff  --git a/clang/test/SemaCXX/co_await-range-for-exp-namespace.cpp b/clang/test/SemaCXX/co_await-range-for-exp-namespace.cpp
index 75568505ab552..df6b8a4e86b36 100644
--- a/clang/test/SemaCXX/co_await-range-for-exp-namespace.cpp
+++ b/clang/test/SemaCXX/co_await-range-for-exp-namespace.cpp
@@ -53,6 +53,7 @@ MyForLoopArrayAwaiter g() {
   for co_await (auto i : arr) {} // expected-warning {{support for std::experimental::coroutine_traits will be removed}}
   // expected-error at -1 {{call to deleted member function 'await_transform'}}
   // expected-note at -2 {{'await_transform' implicitly required by 'co_await' here}}
+  // expected-note at Inputs/std-coroutine-exp-namespace.h:8 {{'coroutine_traits' declared here}}
 }
 
 struct ForLoopAwaiterBadBeginTransform {

diff  --git a/clang/test/SemaCXX/coreturn-eh-exp-namespace.cpp b/clang/test/SemaCXX/coreturn-eh-exp-namespace.cpp
index 7d85c924f6690..facdedf14d01d 100644
--- a/clang/test/SemaCXX/coreturn-eh-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coreturn-eh-exp-namespace.cpp
@@ -40,6 +40,7 @@ VoidTagReturnValue test() {
   object x = {};
   try {
     co_return {}; // expected-warning {{support for std::experimental::coroutine_traits will be removed}}
+    // expected-note at Inputs/std-coroutine-exp-namespace.h:8 {{'coroutine_traits' declared here}}
   } catch (...) {
     throw;
   }

diff  --git a/clang/test/SemaCXX/coreturn-exp-namespace.cpp b/clang/test/SemaCXX/coreturn-exp-namespace.cpp
index c4023c2a94fa8..f45b030f322b2 100644
--- a/clang/test/SemaCXX/coreturn-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coreturn-exp-namespace.cpp
@@ -84,6 +84,7 @@ template <typename... T>
 struct std::experimental::coroutine_traits<int, T...> { using promise_type = promise_int; };
 
 void test0() { co_await a; } // expected-warning {{support for std::experimental::coroutine_traits will be removed}}
+// expected-note at Inputs/std-coroutine-exp-namespace.h:8 {{'coroutine_traits' declared here}}
 float test1() { co_await a; }
 
 int test2() {

diff  --git a/clang/test/SemaCXX/coroutine-final-suspend-noexcept-exp-namespace.cpp b/clang/test/SemaCXX/coroutine-final-suspend-noexcept-exp-namespace.cpp
index 5e4e4802eb487..131bae0d294fe 100644
--- a/clang/test/SemaCXX/coroutine-final-suspend-noexcept-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coroutine-final-suspend-noexcept-exp-namespace.cpp
@@ -7,6 +7,7 @@ namespace std {
 namespace experimental {
 template <class Ret, typename... T>
 struct coroutine_traits { using promise_type = typename Ret::promise_type; };
+// expected-note at -1{{declared here}}
 
 template <class Promise = void>
 struct coroutine_handle {

diff  --git a/clang/test/SemaCXX/coroutine-mixed-exp-namespace.cpp b/clang/test/SemaCXX/coroutine-mixed-exp-namespace.cpp
index 8f64573551906..5c214ca732bed 100644
--- a/clang/test/SemaCXX/coroutine-mixed-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coroutine-mixed-exp-namespace.cpp
@@ -3,7 +3,7 @@
 // RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
 
 #include "Inputs/std-coroutine-exp-namespace.h"
-#include "Inputs/std-coroutine.h"
+#include "Inputs/std-coroutine.h" // Second
 
 struct my_awaitable {
   bool await_ready() noexcept;
@@ -25,4 +25,6 @@ struct std::coroutine_traits<void> { using promise_type = promise_void; };
 void test() {
   co_return; // expected-error {{mixed use of std and std::experimental namespaces for coroutine components}}
   // expected-warning at -1{{support for std::experimental::coroutine_traits will be removed}}
+  // expected-note at Inputs/std-coroutine-exp-namespace.h:8 {{'coroutine_traits' declared here}}
+  // expected-note at Inputs/std-coroutine.h:8 {{'coroutine_traits' declared here}}
 }

diff  --git a/clang/test/SemaCXX/coroutine-mixed2-exp-namespace.cpp b/clang/test/SemaCXX/coroutine-mixed2-exp-namespace.cpp
index 67cb42afa90df..3d37b34c642e6 100644
--- a/clang/test/SemaCXX/coroutine-mixed2-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coroutine-mixed2-exp-namespace.cpp
@@ -1,10 +1,10 @@
 // This file is to test the mixed use of `std::experimental::coroutine_traits` and `std::coroutine_traits`
-// which is similar to coroutine-mixed-exp-namesapce. This file tests the relative order of
+// which is similar to coroutine-mixed-exp-namespace. This file tests the relative order of
 // included header wouldn't affect the diagnostic messages.
 // RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
 
+#include "Inputs/std-coroutine.h" // First
 #include "Inputs/std-coroutine-exp-namespace.h"
-#include "Inputs/std-coroutine.h"
 
 struct my_awaitable {
   bool await_ready() noexcept;
@@ -26,4 +26,6 @@ struct std::coroutine_traits<void> { using promise_type = promise_void; };
 void test() {
   co_return; // expected-error {{mixed use of std and std::experimental namespaces for coroutine components}}
   // expected-warning at -1{{support for std::experimental::coroutine_traits will be removed}}
+  // expected-note at Inputs/std-coroutine-exp-namespace.h:8 {{'coroutine_traits' declared here}}
+  // expected-note at Inputs/std-coroutine.h:8 {{'coroutine_traits' declared here}}
 }

diff  --git a/clang/test/SemaCXX/coroutine-rvo-exp-namespace.cpp b/clang/test/SemaCXX/coroutine-rvo-exp-namespace.cpp
index f73ff3880c046..f8941f8ed2dcf 100644
--- a/clang/test/SemaCXX/coroutine-rvo-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coroutine-rvo-exp-namespace.cpp
@@ -30,6 +30,7 @@ struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
 
 template <class Ret, class... Args>
 struct coroutine_traits : public traits_sfinae_base<Ret> {};
+// expected-note at -1{{declared here}}
 } // namespace std::experimental
 
 struct suspend_never {

diff  --git a/clang/test/SemaCXX/coroutine-seh-exp-namespace.cpp b/clang/test/SemaCXX/coroutine-seh-exp-namespace.cpp
index 9384397687dba..bfe421595c002 100644
--- a/clang/test/SemaCXX/coroutine-seh-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coroutine-seh-exp-namespace.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -triple x86_64-windows-msvc -fms-extensions
 namespace std::experimental {
 template <typename... T> struct coroutine_traits;
+// expected-note at -1{{declared here}}
 
 template <class Promise = void> struct coroutine_handle {
   coroutine_handle() = default;

diff  --git a/clang/test/SemaCXX/coroutine-traits-undefined-template-exp-namespace.cpp b/clang/test/SemaCXX/coroutine-traits-undefined-template-exp-namespace.cpp
index 649249f814d4e..c71023ad5af5c 100644
--- a/clang/test/SemaCXX/coroutine-traits-undefined-template-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coroutine-traits-undefined-template-exp-namespace.cpp
@@ -6,7 +6,7 @@
 namespace std {
 namespace experimental {
 template <typename... T>
-struct coroutine_traits {
+struct coroutine_traits { // expected-note{{declared here}}
   struct promise_type {};
 };
 

diff  --git a/clang/test/SemaCXX/coroutine-unhandled_exception-warning-exp-namespace.cpp b/clang/test/SemaCXX/coroutine-unhandled_exception-warning-exp-namespace.cpp
index 76d5ae87e3658..1987eeaa90ae9 100644
--- a/clang/test/SemaCXX/coroutine-unhandled_exception-warning-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coroutine-unhandled_exception-warning-exp-namespace.cpp
@@ -33,6 +33,7 @@ struct std::experimental::coroutine_traits<void, T...> { using promise_type = pr
 #ifndef DISABLE_WARNING
 void test0() { // expected-warning {{'promise_void' is required to declare the member 'unhandled_exception()' when exceptions are enabled}}
   co_return;   // expected-warning {{support for std::experimental::coroutine_traits will be removed}}
+  // expected-note at Inputs/std-coroutine-exp-namespace.h:8 {{'coroutine_traits' declared here}}
 }
 #else
 void test0() { // expected-no-diagnostics

diff  --git a/clang/test/SemaCXX/coroutine_handle-address-return-type-exp-namespace.cpp b/clang/test/SemaCXX/coroutine_handle-address-return-type-exp-namespace.cpp
index c722495db3902..f167d167746a7 100644
--- a/clang/test/SemaCXX/coroutine_handle-address-return-type-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coroutine_handle-address-return-type-exp-namespace.cpp
@@ -32,6 +32,7 @@ struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
 
 template <class Ret, class... Args>
 struct coroutine_traits : public traits_sfinae_base<Ret> {};
+// expected-note at -1{{declared here}}
 } // namespace std::experimental
 
 struct suspend_never {

diff  --git a/clang/test/SemaCXX/coroutines-exp-namespace.cpp b/clang/test/SemaCXX/coroutines-exp-namespace.cpp
index a5ad37e338d2d..caa141367d87f 100644
--- a/clang/test/SemaCXX/coroutines-exp-namespace.cpp
+++ b/clang/test/SemaCXX/coroutines-exp-namespace.cpp
@@ -45,6 +45,7 @@ struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
 
 template <class Ret, class... Args>
 struct coroutine_traits : public traits_sfinae_base<Ret> {};
+// expected-note at -1{{declared here}}
 } // namespace experimental
 } // namespace std
 


        


More information about the cfe-commits mailing list