Hi!<br><br><div class="gmail_quote">On Thu, Feb 21, 2013 at 1:53 PM, Ismail Pazarbasi <span dir="ltr"><<a href="mailto:ismail.pazarbasi@gmail.com" target="_blank">ismail.pazarbasi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi,<br>
<br>
when operand of a noexcept operator in a friend function definition<br>
involves a member of a template class enclosing the friend definition,<br>
Clang casts current context to either a CXXMethodDecl or a<br>
CXXRecordDecl. Since friend function is neither of these, cast fails.<br>
The same test in a non-template class works fine.<br>
<br>
The first patch tries to retrieve the lexical parent of the function<br>
definition (per class.friend/p6-7), which is expected to be a record<br>
type. A test is also provided (also, pasting below for reference).<br>
<br>
template<typename T><br>
class noexcept_member_operand_at_friend_definition {<br>
  T v_;<br>
  friend int add_to_v(noexcept_member_operand_at_friend_definition &t)<br>
noexcept(noexcept(v_ + 42))<br>
  {<br>
    return t.v_ + 42;<br>
  }<br>
};<br>
<br>
void this_expr()<br>
{<br>
  noexcept_member_operand_at_friend_definition<int> t;<br>
  add_to_v(t);<br>
}<br></blockquote><div><br></div><div>Thanks for looking into this. There is a more fundamental problem here, which this patch is masking rather than fixing. Per 5.1.1/3, 'this' is not permitted to appear in the declaration of a friend function, so per 9.3.1/3, we should not transform the mention of 'v_' into a class member access. Therefore, we should build a DeclRefExpr for the member, not a CXXMemberExpr, in this case. It looks like the bug is that Parser::ParseFunctionDeclarator's IsCXX11MemberFunction is not taking 'friend' into account when determining whether a function in a class is a member function.</div>
<div><br></div><div>To demonstrate the difference, here's a testcase which we should reject, but we currently accept (and still accept with your patch):</div><div><br></div><div>struct S {</div><div>  friend auto f() -> decltype(this);</div>
<div>};</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The second patch is a minor one; it merges two if statements that have<br>
the same condition.</blockquote><div><br></div><div>I don't think this patch is correct. Note that the body of the first 'if' statement can cause the condition of the second to no longer be 'true'. </div>
</div>