Fix a crasher in Template Diffing.
Value depenedent expressions for default arguments cannot be evaluated.
Instead, use the desugared template type to get an argument expression that
can be used. This is needed for both integer and declaration arguements.
Also, move this common code into a separate function.
Patch by Olivier Goffart!
llvm-svn: 178609
diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp
index b9c57ab..419152d 100644
--- a/clang/lib/AST/ASTDiagnostic.cpp
+++ b/clang/lib/AST/ASTDiagnostic.cpp
@@ -913,47 +913,11 @@
ToIter.isEnd() && ToExpr);
if ((FromExpr && FromExpr->getType()->isIntegerType()) ||
(ToExpr && ToExpr->getType()->isIntegerType())) {
- HasFromInt = FromExpr;
- HasToInt = ToExpr;
- if (FromExpr) {
- // Getting the integer value from the expression.
- // Default, value-depenedent expressions require fetching
- // from the desugared TemplateArgument
- if (FromIter.isEnd() && FromExpr->isValueDependent())
- switch (FromIter.getDesugar().getKind()) {
- case TemplateArgument::Integral:
- FromInt = FromIter.getDesugar().getAsIntegral();
- break;
- case TemplateArgument::Expression:
- FromExpr = FromIter.getDesugar().getAsExpr();
- FromInt = FromExpr->EvaluateKnownConstInt(Context);
- break;
- default:
- assert(0 && "Unexpected template argument kind");
- }
- else
- FromInt = FromExpr->EvaluateKnownConstInt(Context);
- }
- if (ToExpr) {
- // Getting the integer value from the expression.
- // Default, value-depenedent expressions require fetching
- // from the desugared TemplateArgument
- if (ToIter.isEnd() && ToExpr->isValueDependent())
- switch (ToIter.getDesugar().getKind()) {
- case TemplateArgument::Integral:
- ToInt = ToIter.getDesugar().getAsIntegral();
- break;
- case TemplateArgument::Expression:
- ToExpr = ToIter.getDesugar().getAsExpr();
- ToInt = ToExpr->EvaluateKnownConstInt(Context);
- break;
- default:
- assert(0 && "Unexpected template argument kind");
- }
- else
- ToInt = ToExpr->EvaluateKnownConstInt(Context);
- }
- Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
+ if (FromExpr)
+ FromInt = GetInt(FromIter, FromExpr);
+ if (ToExpr)
+ ToInt = GetInt(ToIter, ToExpr);
+ Tree.SetNode(FromInt, ToInt, FromExpr, ToExpr);
Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
Tree.SetKind(DiffTree::Integer);
} else {
@@ -962,11 +926,11 @@
}
} else if (HasFromInt || HasToInt) {
if (!HasFromInt && FromExpr) {
- FromInt = FromExpr->EvaluateKnownConstInt(Context);
+ FromInt = GetInt(FromIter, FromExpr);
HasFromInt = true;
}
if (!HasToInt && ToExpr) {
- ToInt = ToExpr->EvaluateKnownConstInt(Context);
+ ToInt = GetInt(ToIter, ToExpr);
HasToInt = true;
}
Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
@@ -975,14 +939,10 @@
ToIter.isEnd() && HasToInt);
Tree.SetKind(DiffTree::Integer);
} else {
- if (!HasFromValueDecl && FromExpr) {
- DeclRefExpr *DRE = cast<DeclRefExpr>(FromExpr);
- FromValueDecl = cast<ValueDecl>(DRE->getDecl());
- }
- if (!HasToValueDecl && ToExpr) {
- DeclRefExpr *DRE = cast<DeclRefExpr>(ToExpr);
- ToValueDecl = cast<ValueDecl>(DRE->getDecl());
- }
+ if (!HasFromValueDecl && FromExpr)
+ FromValueDecl = GetValueDecl(FromIter, FromExpr);
+ if (!HasToValueDecl && ToExpr)
+ ToValueDecl = GetValueDecl(ToIter, ToExpr);
Tree.SetNode(FromValueDecl, ToValueDecl);
Tree.SetSame(FromValueDecl->getCanonicalDecl() ==
ToValueDecl->getCanonicalDecl());
@@ -1101,6 +1061,42 @@
ArgExpr = SNTTPE->getReplacement();
}
+ /// GetInt - Retrieves the template integer argument, including evaluating
+ /// default arguments.
+ llvm::APInt GetInt(const TSTiterator &Iter, Expr *ArgExpr) {
+ // Default, value-depenedent expressions require fetching
+ // from the desugared TemplateArgument
+ if (Iter.isEnd() && ArgExpr->isValueDependent())
+ switch (Iter.getDesugar().getKind()) {
+ case TemplateArgument::Integral:
+ return Iter.getDesugar().getAsIntegral();
+ case TemplateArgument::Expression:
+ ArgExpr = Iter.getDesugar().getAsExpr();
+ return ArgExpr->EvaluateKnownConstInt(Context);
+ default:
+ assert(0 && "Unexpected template argument kind");
+ }
+ return ArgExpr->EvaluateKnownConstInt(Context);
+ }
+
+ /// GetValueDecl - Retrieves the template integer argument, including
+ /// default expression argument.
+ ValueDecl *GetValueDecl(const TSTiterator &Iter, Expr *ArgExpr) {
+ // Default, value-depenedent expressions require fetching
+ // from the desugared TemplateArgument
+ if (Iter.isEnd() && ArgExpr->isValueDependent())
+ switch (Iter.getDesugar().getKind()) {
+ case TemplateArgument::Declaration:
+ return Iter.getDesugar().getAsDecl();
+ case TemplateArgument::Expression:
+ ArgExpr = Iter.getDesugar().getAsExpr();
+ return cast<DeclRefExpr>(ArgExpr)->getDecl();
+ default:
+ assert(0 && "Unexpected template argument kind");
+ }
+ return cast<DeclRefExpr>(ArgExpr)->getDecl();
+ }
+
/// GetTemplateDecl - Retrieves the template template arguments, including
/// default arguments.
void GetTemplateDecl(const TSTiterator &Iter,