On 6/14/19 4:54 PM, Marek Polacek wrote:
On Tue, Jun 11, 2019 at 11:46:05PM -0400, Jason Merrill wrote:
On 6/3/19 9:01 PM, Marek Polacek wrote:

I sort of ended up going down a rathole, but then I realized we don't need to
delay parsing of noexcept-specifiers of member friend function declarations,
because they aren't members of the class.

Where are you getting this from?  I'm definitely sympathetic to the idea
that noexcept-specifiers of friend functions shouldn't need to be
complete-class contexts, but 10.3 doesn't make that distinction that I can
see.

When I tested my patch I noticed that none of the 3 compilers I tried handled
this scenario, so I thought I was missing something.  But if the standard
really doesn't say that noexcept-specifiers of friend functions don't have to
be complete-class contexts, then perhaps it needs to say so.  Should I raise
this on the reflector?

Sounds good.

This was a huge relief because
member friend function declarations can be redeclared, so we'd have to make
sure to check if their noexcept-specifiers match.  But member function decls
can't be redeclared.  I updated the comment to better reflect why what I'm
doing there is correct, along with an assert.

But then why do you still need this:

+  /* We can't compare unparsed noexcept-specifiers.  Save the decl
+     and check this again after we've parsed the noexcept-specifiers
+     for real.  */
+  if (UNPARSED_NOEXCEPT_SPEC_P (new_exceptions))
+    {
+      DEFARG_DECL (TREE_PURPOSE (new_exceptions)) = copy_decl (old_decl);
+      return;
+    }

?

Eh... I don't.  The following version is with the DEFARG_DECL junk removed.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2019-06-14  Marek Polacek  <pola...@redhat.com>

        PR c++/86476 - noexcept-specifier is a complete-class context.
        PR c++/52869
        * cp-tree.def (DEFAULT_ARG): Update commentary.

I'd still like to rename this, can you do that in a follow-up?

@@ -25203,6 +25379,26 @@ cp_parser_noexcept_specification_opt (cp_parser* 
parser,
    if (cp_parser_is_keyword (token, RID_NOEXCEPT))
      {
        tree expr;
+
+      /* [class.mem]/6 says that a noexcept-specifer (within the
+        member-specification of the class) is a complete-class context of
+        a class.  So, if the noexcept-specifier has the optional expression,
+        just save the tokens, and reparse this after we're done with the
+        class.  */
+      if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN)
+         /* No need to delay parsing for a number literal or true/false.  */
+         && !cp_lexer_nth_token_is (parser->lexer, 3, CPP_NUMBER)
+         && !(cp_lexer_nth_token_is (parser->lexer, 3, CPP_KEYWORD)
+              && (cp_lexer_nth_token_is_keyword (parser->lexer, 3, RID_FALSE)
+                  || cp_lexer_nth_token_is_keyword (parser->lexer, 3,
+                                                    RID_TRUE)))

Maybe do immediate parsing for any keyword, not just true/false? I can't think of a keyword that delayed parsing would make a difference for.

I think we also need to check that token 4 is close paren, so we still get delayed parsing for noexcept (1 + foo).

Jason

Reply via email to