[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