diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-11-20 22:32:11 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-11-20 22:32:11 +0000 |
commit | 3ef3e899a9f0a640f179a4d50f1e8ab31b419fbb (patch) | |
tree | cff91cac381915b93673b27d78c4b5a3ac5834ea /clang/lib | |
parent | 8489349fdca5fe57991bf6c683fd20c02301b0e0 (diff) | |
download | bcm5719-llvm-3ef3e899a9f0a640f179a4d50f1e8ab31b419fbb.tar.gz bcm5719-llvm-3ef3e899a9f0a640f179a4d50f1e8ab31b419fbb.zip |
PR21565: Further refine the conditions for enabling eager parsing of
std::X::swap exception specifications (allowing parsing of non-conforming code
in libstdc++). The old conditions also matched the functions in MSVC's STL,
which were relying on deferred parsing here.
llvm-svn: 222471
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 20 |
2 files changed, 24 insertions, 9 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 8469fb96911..e1a5b8e9945 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -416,13 +416,12 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { Diag(Tok.getLocation(), diag::err_except_spec_unparsed); // Attach the exception-specification to the method. - if (EST != EST_None) - Actions.actOnDelayedExceptionSpecification(LM.Method, EST, - SpecificationRange, - DynamicExceptions, - DynamicExceptionRanges, - NoexceptExpr.isUsable()? - NoexceptExpr.get() : nullptr); + Actions.actOnDelayedExceptionSpecification(LM.Method, EST, + SpecificationRange, + DynamicExceptions, + DynamicExceptionRanges, + NoexceptExpr.isUsable()? + NoexceptExpr.get() : nullptr); assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, Tok.getLocation()) && 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, |