diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2019-07-20 07:56:34 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2019-07-20 07:56:34 +0000 |
commit | 3bef014e7d79b7aa58d968fd24e20669ac63d956 (patch) | |
tree | 8a9371f455736af9da9f1132ff98ac92de7a6a3f /clang/lib/Sema | |
parent | 41affad967d48b8223dd8cfee254ee787b87a7e6 (diff) | |
download | bcm5719-llvm-3bef014e7d79b7aa58d968fd24e20669ac63d956.tar.gz bcm5719-llvm-3bef014e7d79b7aa58d968fd24e20669ac63d956.zip |
Implement P1301R4, which allows specifying an optional message on the [[nodiscard]] attribute.
This also bumps the attribute feature test value and introduces the notion of a C++2a extension warning.
llvm-svn: 366626
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 28 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 15 |
2 files changed, 34 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 5f0b3697d3d..d800f79e532 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2841,14 +2841,30 @@ static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) { return; } - // If this is spelled as the standard C++17 attribute, but not in C++17, warn - // about using it as an extension. - if (!S.getLangOpts().CPlusPlus17 && AL.isCXX11Attribute() && - !AL.getScopeName()) - S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL; + StringRef Str; + if ((AL.isCXX11Attribute() || AL.isC2xAttribute()) && !AL.getScopeName()) { + // If this is spelled as the standard C++17 attribute, but not in C++17, + // warn about using it as an extension. If there are attribute arguments, + // then claim it's a C++2a extension instead. + // FIXME: If WG14 does not seem likely to adopt the same feature, add an + // extension warning for C2x mode. + const LangOptions &LO = S.getLangOpts(); + if (AL.getNumArgs() == 1) { + if (LO.CPlusPlus && !LO.CPlusPlus2a) + S.Diag(AL.getLoc(), diag::ext_cxx2a_attr) << AL; + + // Since this this is spelled [[nodiscard]], get the optional string + // literal. If in C++ mode, but not in C++2a mode, diagnose as an + // extension. + // FIXME: C2x should support this feature as well, even as an extension. + if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr)) + return; + } else if (LO.CPlusPlus && !LO.CPlusPlus17) + S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL; + } D->addAttr(::new (S.Context) - WarnUnusedResultAttr(AL.getRange(), S.Context, + WarnUnusedResultAttr(AL.getRange(), S.Context, Str, AL.getAttributeSpellingListIndex())); } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 480155df899..3400f7d3fea 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -258,8 +258,13 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { if (E->getType()->isVoidType()) return; - if (const Attr *A = CE->getUnusedResultAttr(Context)) { - Diag(Loc, diag::warn_unused_result) << A << R1 << R2; + if (const auto *A = cast_or_null<WarnUnusedResultAttr>( + CE->getUnusedResultAttr(Context))) { + StringRef Msg = A->getMessage(); + if (!Msg.empty()) + Diag(Loc, diag::warn_unused_result_msg) << A << Msg << R1 << R2; + else + Diag(Loc, diag::warn_unused_result) << A << R1 << R2; return; } @@ -290,7 +295,11 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { const ObjCMethodDecl *MD = ME->getMethodDecl(); if (MD) { if (const auto *A = MD->getAttr<WarnUnusedResultAttr>()) { - Diag(Loc, diag::warn_unused_result) << A << R1 << R2; + StringRef Msg = A->getMessage(); + if (!Msg.empty()) + Diag(Loc, diag::warn_unused_result_msg) << A << Msg << R1 << R2; + else + Diag(Loc, diag::warn_unused_result) << A << R1 << R2; return; } } |