<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Ah!  Thanks.  I’ll fix it now.<o:p></o:p></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></a></p>
<p class="MsoNormal"><a name="_____replyseparator"></a><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Richard Smith [mailto:richard@metafoo.co.uk]
<br>
<b>Sent:</b> Thursday, July 25, 2019 9:26 AM<br>
<b>To:</b> Keane, Erich <erich.keane@intel.com><br>
<b>Cc:</b> cfe-commits <cfe-commits@lists.llvm.org><br>
<b>Subject:</b> Re: r367027 - Implement P1771<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<div>
<div>
<p class="MsoNormal">On Thu, 25 Jul 2019, 08:10 Erich Keane via cfe-commits, <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">Author: erichkeane<br>
Date: Thu Jul 25 08:10:56 2019<br>
New Revision: 367027<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=367027&view=rev" target="_blank">
http://llvm.org/viewvc/llvm-project?rev=367027&view=rev</a><br>
Log:<br>
Implement P1771<br>
<br>
As passed in the Cologne meeting and treated by Core as a DR,<br>
[[nodiscard]] was applied to constructors so that they can be diagnosed<br>
in cases where the user forgets a variable name for a type.<br>
<br>
The intent is to enable the library to start using this on the<br>
constructors of scope_guard/lock_guard.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D64914" target="_blank">
https://reviews.llvm.org/D64914</a><br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/Attr.td<br>
    cfe/trunk/include/clang/Basic/AttrDocs.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/AST/Expr.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
    cfe/trunk/lib/Sema/SemaStmt.cpp<br>
    cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp<br>
    cfe/trunk/test/Preprocessor/has_attribute.cpp<br>
    cfe/trunk/www/cxx_status.html<br>
<br>
Modified: cfe/trunk/include/clang/Basic/Attr.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=367027&r1=367026&r2=367027&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=367027&r1=367026&r2=367027&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/Attr.td (original)<br>
+++ cfe/trunk/include/clang/Basic/Attr.td Thu Jul 25 08:10:56 2019<br>
@@ -2335,12 +2335,19 @@ def WarnUnused : InheritableAttr {<br>
 }<br>
<br>
 def WarnUnusedResult : InheritableAttr {<br>
-  let Spellings = [CXX11<"", "nodiscard", 201603>, C2x<"", "nodiscard">,<br>
+  let Spellings = [CXX11<"", "nodiscard", 201907>, C2x<"", "nodiscard">,<br>
                    CXX11<"clang", "warn_unused_result">,<br>
                    GCC<"warn_unused_result">];<br>
   let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike]>;<br>
   let Args = [StringArgument<"Message", 1>];<br>
   let Documentation = [WarnUnusedResultsDocs];<br>
+  let AdditionalMembers = [{<br>
+    // Check whether this the C++11 nodiscard version, even in non C++11<br>
+    // spellings.<br>
+    bool IsCXX11NoDiscard() const {<br>
+      return this->getSemanticSpelling() == CXX11_nodiscard;<br>
+    }<br>
+  }];<br>
 }<br>
<br>
 def Weak : InheritableAttr {<br>
<br>
Modified: cfe/trunk/include/clang/Basic/AttrDocs.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=367027&r1=367026&r2=367027&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=367027&r1=367026&r2=367027&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)<br>
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Thu Jul 25 08:10:56 2019<br>
@@ -1500,6 +1500,33 @@ in any resulting diagnostics.<br>
   }<br>
   error_info &foo();<br>
   void f() { foo(); } // Does not diagnose, error_info is a reference.<br>
+<br>
+Additionally, discarded temporaries resulting from a call to a constructor<br>
+marked with ``[[nodiscard]]`` or a constructor of a type marked<br>
+``[[nodiscard]]`` will also diagnose. This also applies to type conversions that<br>
+use the annotated ``[[nodiscard]]`` constructor or result in an annotated type.<br>
+<br>
+.. code-block: c++<br>
+  struct [[nodiscard]] marked_type {/*..*/ };<br>
+  struct marked_ctor {<br>
+    [[nodiscard]] marked_ctor();<br>
+    marked_ctor(int);<br>
+  };<br>
+<br>
+  struct S {<br>
+    operator marked_type() const;<br>
+    [[nodiscard]] operator int() const;<br>
+  };<br>
+<br>
+  void usages() {<br>
+    marked_type(); // diagnoses.<br>
+    marked_ctor(); // diagnoses.<br>
+    marked_ctor(3); // Does not diagnose, int constructor isn't marked nodiscard.<br>
+<br>
+    S s;<br>
+    static_cast<marked_type>(s); // diagnoses<br>
+    (int)s; // diagnoses<br>
+  }<br>
   }];<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=367027&r1=367026&r2=367027&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=367027&r1=367026&r2=367027&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jul 25 08:10:56 2019<br>
@@ -7430,6 +7430,12 @@ def warn_unused_container_subscript_expr<br>
 def warn_unused_call : Warning<<br>
   "ignoring return value of function declared with %0 attribute">,<br>
   InGroup<UnusedValue>;<br>
+def warn_unused_constructor : Warning<<br>
+  "ignoring temporary created by a constructor declared with %0 attribute">,<br>
+  InGroup<UnusedValue>;<br>
+def warn_unused_constructor_msg : Warning<<br>
+  "ignoring temporary created by a constructor declared with %0 attribute: %1">,<br>
+  InGroup<UnusedValue>;<br>
 def warn_side_effects_unevaluated_context : Warning<<br>
   "expression with side effects has no effect in an unevaluated context">,<br>
   InGroup<UnevaluatedExpression>;<br>
<br>
Modified: cfe/trunk/lib/AST/Expr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=367027&r1=367026&r2=367027&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=367027&r1=367026&r2=367027&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/Expr.cpp (original)<br>
+++ cfe/trunk/lib/AST/Expr.cpp Thu Jul 25 08:10:56 2019<br>
@@ -2563,13 +2563,31 @@ bool Expr::isUnusedResultAWarning(const<br>
   case CXXTemporaryObjectExprClass:<br>
   case CXXConstructExprClass: {<br>
     if (const CXXRecordDecl *Type = getType()->getAsCXXRecordDecl()) {<br>
-      if (Type->hasAttr<WarnUnusedAttr>()) {<br>
+      const auto *WarnURAttr = Type->getAttr<WarnUnusedResultAttr>();<br>
+      if (Type->hasAttr<WarnUnusedAttr>() ||<br>
+          (WarnURAttr && WarnURAttr->IsCXX11NoDiscard())) {<br>
         WarnE = this;<br>
         Loc = getBeginLoc();<br>
         R1 = getSourceRange();<br>
         return true;<br>
       }<br>
     }<br>
+<br>
+    const auto *CE = cast<CXXConstructExpr>(this);<br>
+    if (const CXXConstructorDecl *Ctor = CE->getConstructor()) {<br>
+      const auto *WarnURAttr = Ctor->getAttr<WarnUnusedResultAttr>();<br>
+      if (WarnURAttr && WarnURAttr->IsCXX11NoDiscard()) {<br>
+        WarnE = this;<br>
+        Loc = getBeginLoc();<br>
+        R1 = getSourceRange();<br>
+<br>
+        if (unsigned NumArgs = CE->getNumArgs())<br>
+          R2 = SourceRange(CE->getArg(0)->getBeginLoc(),<br>
+                           CE->getArg(NumArgs - 1)->getEndLoc());<br>
+        return true;<br>
+      }<br>
+    }<br>
+<br>
     return false;<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=367027&r1=367026&r2=367027&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=367027&r1=367026&r2=367027&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Jul 25 08:10:56 2019<br>
@@ -2831,7 +2831,8 @@ static void handleSentinelAttr(Sema &S,<br>
<br>
 static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {<br>
   if (D->getFunctionType() &&<br>
-      D->getFunctionType()->getReturnType()->isVoidType()) {<br>
+      D->getFunctionType()->getReturnType()->isVoidType() &&<br>
+      !isa<CXXConstructorDecl>(D)) {<br>
     S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 0;<br>
     return;<br>
   }<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=367027&r1=367026&r2=367027&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=367027&r1=367026&r2=367027&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Jul 25 08:10:56 2019<br>
@@ -196,6 +196,25 @@ static bool DiagnoseUnusedComparison(Sem<br>
   return true;<br>
 }<br>
<br>
+static bool DiagnoseNoDiscard(Sema &S, const WarnUnusedResultAttr *A,<br>
+                              SourceLocation Loc, SourceRange R1,<br>
+                              SourceRange R2, bool IsCtor) {<br>
+  if (!A)<br>
+    return false;<br>
+  StringRef Msg = A->getMessage();<br>
+<br>
+  if (Msg.empty()) {<br>
+    if (IsCtor)<br>
+      return S.Diag(Loc, diag::warn_unused_constructor) << A << R1 << R2;<br>
+    return S.Diag(Loc, diag::warn_unused_result) << A << R1 << R2;<br>
+  }<br>
+<br>
+  if (IsCtor)<br>
+    return S.Diag(Loc, diag::warn_unused_constructor_msg) << A << Msg << R1<br>
+                                                          << R2;<br>
+  return S.Diag(Loc, diag::warn_unused_result_msg) << A << Msg << R1 << R2;<br>
+}<br>
+<br>
 void Sema::DiagnoseUnusedExprResult(const Stmt *S) {<br>
   if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))<br>
     return DiagnoseUnusedExprResult(Label->getSubStmt());<br>
@@ -254,19 +273,19 @@ void Sema::DiagnoseUnusedExprResult(cons<br>
     return;<br>
<br>
   E = WarnExpr;<br>
+  if (const auto *Cast = dyn_cast<CastExpr>(E))<br>
+    if (Cast->getCastKind() == CK_NoOp ||<br>
+        Cast->getCastKind() == CK_ConstructorConversion)<br>
+      E = Cast->getSubExpr()->IgnoreImpCasts();<br>
+<br>
   if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {<br>
     if (E->getType()->isVoidType())<br>
       return;<br>
<br>
-    if (const auto *A = cast_or_null<WarnUnusedResultAttr>(<br>
-            CE->getUnusedResultAttr(Context))) {<br>
-      StringRef Msg = A->getMessage();<br>
-      if (!Msg.empty())<br>
-        Diag(Loc, diag::warn_unused_result_msg) << A << Msg << R1 << R2;<br>
-      else<br>
-        Diag(Loc, diag::warn_unused_result) << A << R1 << R2;<br>
+    if (DiagnoseNoDiscard(*this, cast_or_null<WarnUnusedResultAttr>(<br>
+                                     CE->getUnusedResultAttr(Context)),<br>
+                          Loc, R1, R2, /*isCtor=*/false))<br>
       return;<br>
-    }<br>
<br>
     // If the callee has attribute pure, const, or warn_unused_result, warn with<br>
     // a more specific message to make it clear what is happening. If the call<br>
@@ -284,9 +303,24 @@ void Sema::DiagnoseUnusedExprResult(cons<br>
         return;<br>
       }<br>
     }<br>
+  } else if (const auto *CE = dyn_cast<CXXConstructExpr>(E)) {<br>
+    if (const CXXConstructorDecl *Ctor = CE->getConstructor()) {<br>
+      const auto *A = Ctor->getAttr<WarnUnusedResultAttr>();<br>
+      A = A ? A : Ctor->getParent()->getAttr<WarnUnusedResultAttr>();<br>
+      if (DiagnoseNoDiscard(*this, A, Loc, R1, R2, /*isCtor=*/true))<br>
+        return;<br>
+    }<br>
+  } else if (const auto *ILE = dyn_cast<InitListExpr>(E)) {<br>
+    if (const TagDecl *TD = ILE->getType()->getAsTagDecl()) {<br>
+<br>
+      if (DiagnoseNoDiscard(*this, TD->getAttr<WarnUnusedResultAttr>(), Loc, R1,<br>
+                            R2, /*isCtor=*/false))<br>
+        return;<br>
+    }<br>
   } else if (ShouldSuppress)<br>
     return;<br>
<br>
+  E = WarnExpr;<br>
   if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {<br>
     if (getLangOpts().ObjCAutoRefCount && ME->isDelegateInitCall()) {<br>
       Diag(Loc, diag::err_arc_unused_init_message) << R1;<br>
@@ -294,14 +328,9 @@ void Sema::DiagnoseUnusedExprResult(cons<br>
     }<br>
     const ObjCMethodDecl *MD = ME->getMethodDecl();<br>
     if (MD) {<br>
-      if (const auto *A = MD->getAttr<WarnUnusedResultAttr>()) {<br>
-        StringRef Msg = A->getMessage();<br>
-        if (!Msg.empty())<br>
-          Diag(Loc, diag::warn_unused_result_msg) << A << Msg << R1 << R2;<br>
-        else<br>
-          Diag(Loc, diag::warn_unused_result) << A << R1 << R2;<br>
+      if (DiagnoseNoDiscard(*this, MD->getAttr<WarnUnusedResultAttr>(), Loc, R1,<br>
+                            R2, /*isCtor=*/false))<br>
         return;<br>
-      }<br>
     }<br>
   } else if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {<br>
     const Expr *Source = POE->getSyntacticForm();<br>
<br>
Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp?rev=367027&r1=367026&r2=367027&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp?rev=367027&r1=367026&r2=367027&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp (original)<br>
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp Thu Jul 25 08:10:56 2019<br>
@@ -80,6 +80,50 @@ void cxx2a_use() {<br>
   conflicting_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: special reason}}<br>
 }<br>
<br>
+namespace p1771 {<br>
+struct[[nodiscard("Don't throw me away!")]] ConvertTo{};<br>
+struct S {<br>
+  [[nodiscard]] S();<br>
+  [[nodiscard("Don't let that S-Char go!")]] S(char);<br>
+  S(int);<br>
+  [[gnu::warn_unused_result]] S(double);<br>
+  operator ConvertTo();<br>
+  [[nodiscard]] operator int();<br>
+  [[nodiscard("Don't throw away as a double")]] operator double();<br>
+};<br>
+<br>
+struct[[nodiscard("Don't throw me away either!")]] Y{};<br>
+<br>
+void usage() {<br>
+  S();    // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}<br>
+  S('A'); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't let that S-Char go!}}<br>
+  S(1);<br>
+  S(2.2);<br>
+  Y(); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't throw me away either!}}<br>
+  S s;<br>
+  ConvertTo{}; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw me away!}}<br>
+<br>
+// AST is different in C++20 mode, pre-2017 a move ctor for ConvertTo is there<br>
+// as well, hense the constructor warning.<br>
+#if __cplusplus >= 201703L<br>
+// expected-warning@+4 {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw me away!}}<br>
+#else<br>
+// expected-warning@+2 {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't throw me away!}}<br>
+#endif<br>
+  (ConvertTo) s;<br>
+  (int)s; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}<br>
+  (S)'c'; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't let that S-Char go!}}<br>
+#if __cplusplus >= 201703L<br>
+// expected-warning@+4 {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw me away!}}<br>
+#else<br>
+// expected-warning@+2 {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't throw me away!}}<br>
+#endif<br>
+  static_cast<ConvertTo>(s);<br>
+  static_cast<int>(s); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}<br>
+  static_cast<double>(s); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw away as a double}}<br>
+}<br>
+}; // namespace p1771<br>
+<br>
 #ifdef EXT<br>
 // expected-warning@5 {{use of the 'nodiscard' attribute is a C++17 extension}}<br>
 // expected-warning@9 {{use of the 'nodiscard' attribute is a C++17 extension}}<br>
@@ -91,4 +135,10 @@ void cxx2a_use() {<br>
 // expected-warning@71 {{use of the 'nodiscard' attribute is a C++2a extension}}<br>
 // expected-warning@73 {{use of the 'nodiscard' attribute is a C++2a extension}}<br>
 // expected-warning@74 {{use of the 'nodiscard' attribute is a C++2a extension}}<br>
+// expected-warning@84 {{use of the 'nodiscard' attribute is a C++2a extension}}<br>
+// expected-warning@86 {{use of the 'nodiscard' attribute is a C++17 extension}}<br>
+// expected-warning@87 {{use of the 'nodiscard' attribute is a C++2a extension}}<br>
+// expected-warning@91 {{use of the 'nodiscard' attribute is a C++17 extension}}<br>
+// expected-warning@92 {{use of the 'nodiscard' attribute is a C++2a extension}}<br>
+// expected-warning@95 {{use of the 'nodiscard' attribute is a C++2a extension}}<br>
 #endif<br>
<br>
Modified: cfe/trunk/test/Preprocessor/has_attribute.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/has_attribute.cpp?rev=367027&r1=367026&r2=367027&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/has_attribute.cpp?rev=367027&r1=367026&r2=367027&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Preprocessor/has_attribute.cpp (original)<br>
+++ cfe/trunk/test/Preprocessor/has_attribute.cpp Thu Jul 25 08:10:56 2019<br>
@@ -63,7 +63,7 @@ CXX11(unlikely)<br>
 // CHECK: maybe_unused: 201603L<br>
 // ITANIUM: no_unique_address: 201803L<br>
 // WINDOWS: no_unique_address: 0<br>
-// CHECK: nodiscard: 201603L<br>
+// CHECK: nodiscard: 201907L<br>
 // CHECK: noreturn: 200809L<br>
 // FIXME(201803L) CHECK: unlikely: 0<br>
<br>
<br>
Modified: cfe/trunk/www/cxx_status.html<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=367027&r1=367026&r2=367027&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=367027&r1=367026&r2=367027&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/www/cxx_status.html (original)<br>
+++ cfe/trunk/www/cxx_status.html Thu Jul 25 08:10:56 2019<br>
@@ -664,7 +664,7 @@ version 3.7.<br>
     </tr><br>
       <tr> <!-- from Cologne 2019 --><br>
         <td><a href="<a href="http://wg21.link/p1771r1" target="_blank">http://wg21.link/p1771r1</a>">P1771R1</a> (<a href="#dr">DR</a>)</td><br>
-        <td class="none" align="center">No</td><br>
+        <td class="none" align="center">SVN</td><o:p></o:p></p>
</blockquote>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">This should be class="svn"<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">       </tr><br>
     <tr><br>
       <td><tt>[[maybe_unused]]</tt> attribute</td><br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><o:p></o:p></p>
</blockquote>
</div>
</div>
</div>
</div>
</body>
</html>