summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-11-20 22:32:11 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-11-20 22:32:11 +0000
commit3ef3e899a9f0a640f179a4d50f1e8ab31b419fbb (patch)
treecff91cac381915b93673b27d78c4b5a3ac5834ea /clang/lib
parent8489349fdca5fe57991bf6c683fd20c02301b0e0 (diff)
downloadbcm5719-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.cpp13
-rw-r--r--clang/lib/Parse/ParseDecl.cpp20
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,
OpenPOWER on IntegriCloud