diff options
author | Olivier Goffart <ogoffart@woboq.com> | 2016-02-12 12:34:44 +0000 |
---|---|---|
committer | Olivier Goffart <ogoffart@woboq.com> | 2016-02-12 12:34:44 +0000 |
commit | 8bc0caa2e9494524860f35f37fbfc875ac0c329b (patch) | |
tree | a4d396d1fc5469ea1b3e4d164a1bca323926fad2 /clang/lib/AST/ExprConstant.cpp | |
parent | 867aa20b1ec9833fd510e7990aa7894a995cb414 (diff) | |
download | bcm5719-llvm-8bc0caa2e9494524860f35f37fbfc875ac0c329b.tar.gz bcm5719-llvm-8bc0caa2e9494524860f35f37fbfc875ac0c329b.zip |
Fix ICE with constexpr and friend functions
Fix a crash while parsing this code:
struct X {
friend constexpr int foo(X*) { return 12; }
static constexpr int j = foo(static_cast<X*>(nullptr));
};
Differential Revision: http://reviews.llvm.org/D16973
llvm-svn: 260675
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index eaa61ea5c4f..739649234a2 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -3736,7 +3736,8 @@ static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, /// expression. static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, - const FunctionDecl *Definition) { + const FunctionDecl *Definition, + const Stmt *Body) { // Potential constant expressions can contain calls to declared, but not yet // defined, constexpr functions. if (Info.checkingPotentialConstantExpression() && !Definition && @@ -3749,7 +3750,8 @@ static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, return false; // Can we evaluate this function call? - if (Definition && Definition->isConstexpr() && !Definition->isInvalidDecl()) + if (Definition && Definition->isConstexpr() && + !Definition->isInvalidDecl() && Body) return true; if (Info.getLangOpts().CPlusPlus11) { @@ -4275,7 +4277,7 @@ public: const FunctionDecl *Definition = nullptr; Stmt *Body = FD->getBody(Definition); - if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition) || + if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body) || !HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, Info, Result, ResultSlot)) return false; @@ -5483,9 +5485,9 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) { } const FunctionDecl *Definition = nullptr; - FD->getBody(Definition); + auto Body = FD->getBody(Definition); - if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition)) + if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body)) return false; // Avoid materializing a temporary for an elidable copy/move constructor. @@ -5971,9 +5973,9 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, } const FunctionDecl *Definition = nullptr; - FD->getBody(Definition); + auto Body = FD->getBody(Definition); - if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition)) + if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body)) return false; if (ZeroInit && !HadZeroInit) { |