diff options
author | Nikola Smiljanic <popizdeh@gmail.com> | 2014-07-01 04:17:53 +0000 |
---|---|---|
committer | Nikola Smiljanic <popizdeh@gmail.com> | 2014-07-01 04:17:53 +0000 |
commit | 3fe1e09a6e285a4792224969b582ada1bd6747f8 (patch) | |
tree | dbeabf1d47e710f355cbc56f42f50e56feb42649 /clang/lib/AST/ASTDiagnostic.cpp | |
parent | c8caa1702a743b67d15db444e1817a55ca0fb0a3 (diff) | |
download | bcm5719-llvm-3fe1e09a6e285a4792224969b582ada1bd6747f8.tar.gz bcm5719-llvm-3fe1e09a6e285a4792224969b582ada1bd6747f8.zip |
PR15677 - Crash in template diffing. Check that expression is evaluatable before evaluating it.
llvm-svn: 212090
Diffstat (limited to 'clang/lib/AST/ASTDiagnostic.cpp')
-rw-r--r-- | clang/lib/AST/ASTDiagnostic.cpp | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 6919ee2e4a8..2ee26fb7a74 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -959,25 +959,27 @@ class TemplateDiff { ToIter.isEnd() && ToExpr); if (DefaultNTTPD->getType()->isIntegralOrEnumerationType()) { if (FromExpr) - FromInt = GetInt(FromIter, FromExpr); + HasFromInt = GetInt(FromIter, FromExpr, FromInt); if (ToExpr) - ToInt = GetInt(ToIter, ToExpr); - Tree.SetNode(FromInt, ToInt, FromExpr, ToExpr); + HasToInt = GetInt(ToIter, ToExpr, ToInt); + } + if (HasFromInt && HasToInt) { + Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt)); Tree.SetKind(DiffTree::Integer); + } else if (HasFromInt || HasToInt) { + Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); + Tree.SetSame(false); + Tree.SetKind(DiffTree::Integer); } else { Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr)); Tree.SetKind(DiffTree::Expression); } } else if (HasFromInt || HasToInt) { - if (!HasFromInt && FromExpr) { - FromInt = GetInt(FromIter, FromExpr); - HasFromInt = true; - } - if (!HasToInt && ToExpr) { - ToInt = GetInt(ToIter, ToExpr); - HasToInt = true; - } + if (!HasFromInt && FromExpr) + HasFromInt = GetInt(FromIter, FromExpr, FromInt); + if (!HasToInt && ToExpr) + HasToInt = GetInt(ToIter, ToExpr, ToInt); Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt)); Tree.SetDefault(FromIter.isEnd() && HasFromInt, @@ -1121,20 +1123,28 @@ class TemplateDiff { /// GetInt - Retrieves the template integer argument, including evaluating /// default arguments. - llvm::APInt GetInt(const TSTiterator &Iter, Expr *ArgExpr) { + bool GetInt(const TSTiterator &Iter, Expr *ArgExpr, llvm::APInt &Int) { // Default, value-depenedent expressions require fetching - // from the desugared TemplateArgument - if (Iter.isEnd() && ArgExpr->isValueDependent()) + // from the desugared TemplateArgument, otherwise expression needs to + // be evaluatable. + if (Iter.isEnd() && ArgExpr->isValueDependent()) { switch (Iter.getDesugar().getKind()) { case TemplateArgument::Integral: - return Iter.getDesugar().getAsIntegral(); + Int = Iter.getDesugar().getAsIntegral(); + return true; case TemplateArgument::Expression: ArgExpr = Iter.getDesugar().getAsExpr(); - return ArgExpr->EvaluateKnownConstInt(Context); + Int = ArgExpr->EvaluateKnownConstInt(Context); + return true; default: llvm_unreachable("Unexpected template argument kind"); } - return ArgExpr->EvaluateKnownConstInt(Context); + } else if (ArgExpr->isEvaluatable(Context)) { + Int = ArgExpr->EvaluateKnownConstInt(Context); + return true; + } + + return false; } /// GetValueDecl - Retrieves the template Decl argument, including @@ -1517,6 +1527,8 @@ class TemplateDiff { Bold(); } OS << Val.toString(10); + } else if (E) { + PrintExpr(E); } else { OS << "(no argument)"; } |