diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 52313e6a15ff1..c5d5d03cc99c7 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1979,6 +1979,10 @@ void clang::inferNoReturnAttr(Sema &S, const Decl *D) { if (!FD->hasAttr() && !FD->hasAttr() && isKnownToAlwaysThrow(FD)) { NonConstFD->addAttr(InferredNoReturnAttr::CreateImplicit(S.Context)); + + // Emit a diagnostic suggesting the function being marked [[noreturn]]. + S.Diag(FD->getLocation(), diag::warn_suggest_noreturn_function) + << /*isFunction=*/0 << FD; } } diff --git a/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp new file mode 100644 index 0000000000000..7548ba8904a71 --- /dev/null +++ b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wreturn-type -Wmissing-noreturn -verify %s + +namespace std { + class string { + public: + string(const char*); + }; + class runtime_error { + public: + runtime_error(const string&); + }; +} + +// This function always throws. Suggest [[noreturn]]. +void throwError(const std::string& msg) { // expected-warning {{function 'throwError' could be declared with attribute 'noreturn'}} + throw std::runtime_error(msg); +} + +// The non-void caller should not warn about missing return. +int ensureZero(int i) { + if (i == 0) return 0; + throwError("ERROR"); // no-warning +}