@@ -7416,12 +7416,20 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
7416
7416
std::optional<Sema::CXXThisScopeRAII> ThisScope;
7417
7417
InitCXXThisScopeForDeclaratorIfRelevant (D, DS, ThisScope);
7418
7418
7419
- // Parse exception-specification[opt].
7420
- // FIXME: Per [class.mem]p6, all exception-specifications at class scope
7421
- // should be delayed, including those for non-members (eg, friend
7422
- // declarations). But only applying this to member declarations is
7423
- // consistent with what other implementations do.
7424
- bool Delayed = D.isFirstDeclarationOfMember () &&
7419
+ // C++ [class.mem.general]p8:
7420
+ // A complete-class context of a class (template) is a
7421
+ // - function body,
7422
+ // - default argument,
7423
+ // - default template argument,
7424
+ // - noexcept-specifier, or
7425
+ // - default member initializer
7426
+ // within the member-specification of the class or class template.
7427
+ //
7428
+ // Parse exception-specification[opt]. If we are in the
7429
+ // member-specification of a class or class template, this is a
7430
+ // complete-class context and parsing of the noexcept-specifier should be
7431
+ // delayed (even if this is a friend declaration).
7432
+ bool Delayed = D.getContext () == DeclaratorContext::Member &&
7425
7433
D.isFunctionDeclaratorAFunctionDeclaration ();
7426
7434
if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack (D) &&
7427
7435
GetLookAheadToken (0 ).is (tok::kw_noexcept) &&
0 commit comments