diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-03-12 23:14:33 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-03-12 23:14:33 +0000 |
commit | 8e6002f3bd52a87d697b348ac5d049898c8214d5 (patch) | |
tree | 2704abd975118fcf98e6cd20b6b270e4331d05bb /clang/lib/Sema/SemaDecl.cpp | |
parent | 8a5a590cd1a058bf7227daf8b0de43a84822200b (diff) | |
download | bcm5719-llvm-8e6002f3bd52a87d697b348ac5d049898c8214d5.tar.gz bcm5719-llvm-8e6002f3bd52a87d697b348ac5d049898c8214d5.zip |
Fix crash if delayed template parsing meets an erroneous trailing return type.
Based on a patch and test by Stephan Tolksdorf! Refactoring and fixing adjacent
brokenness by me.
llvm-svn: 203733
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 521fc3f2cbc..ec062852789 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9695,6 +9695,30 @@ void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { const_cast<VarDecl*>(NRVOCandidate)->setNRVOVariable(true); } +bool Sema::canDelayFunctionBody(const Declarator &D) { + // We can't delay parsing the body of a constexpr function template (yet). + if (D.getDeclSpec().isConstexprSpecified()) + return false; + + // We can't delay parsing the body of a function template with a deduced + // return type (yet). + if (D.getDeclSpec().containsPlaceholderType()) { + // If the placeholder introduces a non-deduced trailing return type, + // we can still delay parsing it. + if (D.getNumTypeObjects()) { + const auto &Outer = D.getTypeObject(D.getNumTypeObjects() - 1); + if (Outer.Kind == DeclaratorChunk::Function && + Outer.Fun.hasTrailingReturnType()) { + QualType Ty = GetTypeFromParser(Outer.Fun.getTrailingReturnType()); + return Ty.isNull() || !Ty->isUndeducedType(); + } + } + return false; + } + + return true; +} + bool Sema::canSkipFunctionBody(Decl *D) { // We cannot skip the body of a function (or function template) which is // constexpr, since we may need to evaluate its body in order to parse the |