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@-1 {{call to deleted member function 'await_transform'}} // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}} + // expected-note@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@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@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@-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@-1{{support for std::experimental::coroutine_traits will be removed}} + // expected-note@Inputs/std-coroutine-exp-namespace.h:8 {{'coroutine_traits' declared here}} + // expected-note@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@-1{{support for std::experimental::coroutine_traits will be removed}} + // expected-note@Inputs/std-coroutine-exp-namespace.h:8 {{'coroutine_traits' declared here}} + // expected-note@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@-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@-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@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@-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@-1{{declared here}} } // namespace experimental } // namespace std _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits