summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp20
1 files changed, 18 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index f84b4dae8d5..518197e17b9 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5282,8 +5282,24 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
// Parse exception-specification[opt].
bool Delayed = D.isFirstDeclarationOfMember() &&
- D.isFunctionDeclaratorAFunctionDeclaration() &&
- !Actions.isLibstdcxxEagerExceptionSpecHack(D);
+ D.isFunctionDeclaratorAFunctionDeclaration();
+ if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
+ GetLookAheadToken(0).is(tok::kw_noexcept) &&
+ GetLookAheadToken(1).is(tok::l_paren) &&
+ GetLookAheadToken(2).is(tok::kw_noexcept) &&
+ GetLookAheadToken(3).is(tok::l_paren) &&
+ GetLookAheadToken(4).is(tok::identifier) &&
+ GetLookAheadToken(4).getIdentifierInfo()->isStr("swap")) {
+ // HACK: We've got an exception-specification
+ // noexcept(noexcept(swap(...)))
+ // or
+ // noexcept(noexcept(swap(...)) && noexcept(swap(...)))
+ // on a 'swap' member function. This is a libstdc++ bug; the lookup
+ // for 'swap' will only find the function we're currently declaring,
+ // whereas it expects to find a non-member swap through ADL. Turn off
+ // delayed parsing to give it a chance to find what it expects.
+ Delayed = false;
+ }
ESpecType = tryParseExceptionSpecification(Delayed,
ESpecRange,
DynamicExceptions,
OpenPOWER on IntegriCloud