<div style="font-family: arial, helvetica, sans-serif; font-size: 10pt">On Mon, Nov 12, 2012 at 3:56 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br>
<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Mon, Nov 12, 2012 at 3:48 PM, Kaelyn Uhrain <<a href="mailto:rikka@google.com">rikka@google.com</a>> wrote:<br>

> Author: rikka<br>
> Date: Mon Nov 12 17:48:05 2012<br>
> New Revision: 167783<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=167783&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=167783&view=rev</a><br>
> Log:<br>
> Enable C++11 attribute syntax for warn_unused_result and allow it to be<br>
> applied to CXXRecordDecls, where functions with that return type will<br>
> inherit the warn_unused_result attribute.<br>
><br>
> Also includes a tiny fix (with no discernable behavior change for<br>
> existing code) to re-sync AttributeDeclKind enum and<br>
> err_attribute_wrong_decl_type with warn_attribute_wrong_decl_type since<br>
> the enum is used with both diagnostic messages to chose the correct<br>
> description.<br>
><br>
> Modified:<br>
>     cfe/trunk/include/clang/Basic/Attr.td<br>
>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
>     cfe/trunk/lib/Sema/SemaDecl.cpp<br>
>     cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
>     cfe/trunk/test/SemaCXX/warn-unused-result.cpp<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=167783&r1=167782&r2=167783&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=167783&r1=167782&r2=167783&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/Attr.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/Attr.td Mon Nov 12 17:48:05 2012<br>
> @@ -699,7 +699,7 @@<br>
>  }<br>
><br>
>  def WarnUnusedResult : InheritableAttr {<br>
> -  let Spellings = [GNU<"warn_unused_result">];<br>
> +  let Spellings = [GNU<"warn_unused_result">, CXX11<"","warn_unused_result">];<br>
<br>
</div></div>Please use CXX11<"clang", "warn_unused_result">.<br></blockquote><div><br></div><div>Fixed in r167791.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><div class="h5"><br>
>  }<br>
><br>
>  def Weak : InheritableAttr {<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=167783&r1=167782&r2=167783&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=167783&r1=167782&r2=167783&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Nov 12 17:48:05 2012<br>
> @@ -1773,17 +1773,18 @@<br>
>  def warn_attribute_wrong_decl_type : Warning<<br>
>    "%0 attribute only applies to %select{functions|unions|"<br>
>    "variables and functions|functions and methods|parameters|"<br>
> -  "functions, methods and blocks|functions, methods, and parameters|"<br>
> -  "classes|variables|methods|variables, functions and labels|"<br>
> -  "fields and global variables|structs|"<br>
> +  "functions, methods and blocks|functions, methods, and classes|"<br>
> +  "functions, methods, and parameters|classes|variables|methods|"<br>
> +  "variables, functions and labels|fields and global variables|structs|"<br>
>    "variables, functions and tag types|thread-local variables}1">,<br>
>    InGroup<IgnoredAttributes>;<br>
>  def err_attribute_wrong_decl_type : Error<<br>
>    "%0 attribute only applies to %select{functions|unions|"<br>
>    "variables and functions|functions and methods|parameters|"<br>
> -  "functions, methods and blocks|functions, methods, and parameters|"<br>
> -  "classes|variables|methods|variables, functions and labels|"<br>
> -  "fields and global variables|structs|thread-local variables}1">;<br>
> +  "functions, methods and blocks|functions, methods, and classes|"<br>
> +  "functions, methods, and parameters|classes|variables|methods|"<br>
> +  "variables, functions and labels|fields and global variables|structs|"<br>
> +  "variables, functions and tag types|thread-local variables}1">;<br>
>  def warn_function_attribute_wrong_type : Warning<<br>
>    "'%0' only applies to function types; type here is %1">,<br>
>    InGroup<IgnoredAttributes>;<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=167783&r1=167782&r2=167783&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=167783&r1=167782&r2=167783&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Nov 12 17:48:05 2012<br>
> @@ -5691,6 +5691,14 @@<br>
>    ProcessDeclAttributes(S, NewFD, D,<br>
>                          /*NonInheritable=*/false, /*Inheritable=*/true);<br>
><br>
> +  QualType RetType = NewFD->getResultType();<br>
> +  const CXXRecordDecl *Ret = RetType->isRecordType() ?<br>
> +      RetType->getAsCXXRecordDecl() : RetType->getPointeeCXXRecordDecl();<br>
> +  if (!NewFD->isInvalidDecl() && !NewFD->hasAttr<WarnUnusedResultAttr>() &&<br>
> +      Ret && Ret->hasAttr<WarnUnusedResultAttr>()) {<br>
> +    NewFD->addAttr(new (Context) WarnUnusedResultAttr(SourceRange(), Context));<br>
> +  }<br>
> +<br>
>    if (!getLangOpts().CPlusPlus) {<br>
>      // Perform semantic checking on the function declaration.<br>
>      bool isExplicitSpecialization=false;<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=167783&r1=167782&r2=167783&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=167783&r1=167782&r2=167783&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Nov 12 17:48:05 2012<br>
> @@ -37,6 +37,7 @@<br>
>    ExpectedFunctionOrMethod,<br>
>    ExpectedParameter,<br>
>    ExpectedFunctionMethodOrBlock,<br>
> +  ExpectedFunctionMethodOrClass,<br>
>    ExpectedFunctionMethodOrParameter,<br>
>    ExpectedClass,<br>
>    ExpectedVariable,<br>
> @@ -44,6 +45,7 @@<br>
>    ExpectedVariableFunctionOrLabel,<br>
>    ExpectedFieldOrGlobalVar,<br>
>    ExpectedStruct,<br>
> +  ExpectedVariableFunctionOrTag,<br>
<br>
</div></div>Is this enum value used anywhere?<br></blockquote><div><br></div><div>Not currently, but without it the enum doesn't match up to the choices in (warn|err)_attribute_wrong_decl_type--specifically ExpectedTLSVar, which had the right value for one of the diagnostics but not the other. The two diagnostics being out of sync with each other and with this enum is also a potential landmine for anyone modifying either diagnostic in the future, particularly since the comment on the enum claims it matches the choices in both diagnostics.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im"><br>
>    ExpectedTLSVar<br>
>  };<br>
><br>
> @@ -2445,7 +2447,7 @@<br>
>    if (!checkAttributeNumArgs(S, Attr, 0))<br>
>      return;<br>
><br>
> -  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {<br>
> +  if (!isFunction(D) && !isa<ObjCMethodDecl>(D) && !isa<CXXRecordDecl>(D)) {<br>
>      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)<br>
>        << Attr.getName() << ExpectedFunctionOrMethod;<br>
<br>
</div>Should this be updated to ExpectedFunctionMethodOrClass?<br></blockquote><div><br></div><div>Whoops! Good catch :) </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="HOEnZb"><div class="h5"><br>
>      return;<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/warn-unused-result.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unused-result.cpp?rev=167783&r1=167782&r2=167783&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unused-result.cpp?rev=167783&r1=167782&r2=167783&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/SemaCXX/warn-unused-result.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/warn-unused-result.cpp Mon Nov 12 17:48:05 2012<br>
> @@ -1,4 +1,4 @@<br>
> -// RUN: %clang_cc1 -fsyntax-only -verify %s<br>
> +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s<br>
><br>
>  int f() __attribute__((warn_unused_result));<br>
><br>
> @@ -42,3 +42,33 @@<br>
>    x.foo(); // expected-warning {{ignoring return value}}<br>
>    x2->foo(); // expected-warning {{ignoring return value}}<br>
>  }<br>
> +<br>
> +namespace warn_unused_CXX11 {<br>
> +struct [[warn_unused_result]] Status {<br>
> +  bool ok() const;<br>
> +};<br>
> +Status DoSomething();<br>
> +Status& DoSomethingElse();<br>
> +Status* DoAnotherThing();<br>
> +Status** DoYetAnotherThing();<br>
> +void lazy() {<br>
> +  Status s = DoSomething();<br>
> +  if (!s.ok()) return;<br>
> +  Status &rs = DoSomethingElse();<br>
> +  if (!rs.ok()) return;<br>
> +  Status *ps = DoAnotherThing();<br>
> +  if (!ps->ok()) return;<br>
> +  Status **pps = DoYetAnotherThing();<br>
> +  if (!(*pps)->ok()) return;<br>
> +<br>
> +  (void)DoSomething();<br>
> +  (void)DoSomethingElse();<br>
> +  (void)DoAnotherThing();<br>
> +  (void)DoYetAnotherThing();<br>
> +<br>
> +  DoSomething(); // expected-warning {{ignoring return value}}<br>
> +  DoSomethingElse(); // expected-warning {{ignoring return value}}<br>
> +  DoAnotherThing(); // expected-warning {{ignoring return value}}<br>
> +  DoYetAnotherThing();<br>
> +}<br>
> +}<br>
</div></div></blockquote></div><br></div>