summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp37
1 files changed, 23 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 1fcc79403f8..050e18944a7 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2863,11 +2863,9 @@ static Expr *lookThroughRangesV3Condition(Preprocessor &PP, Expr *Cond) {
return Cond;
}
-/// Find the failed subexpression within enable_if, and describe it
-/// with a string.
-static std::pair<Expr *, std::string>
-findFailedEnableIfCondition(Sema &S, Expr *Cond) {
- Cond = lookThroughRangesV3Condition(S.PP, Cond);
+std::pair<Expr *, std::string>
+Sema::findFailedBooleanCondition(Expr *Cond, bool AllowTopLevelCond) {
+ Cond = lookThroughRangesV3Condition(PP, Cond);
// Separate out all of the terms in a conjunction.
SmallVector<Expr *, 4> Terms;
@@ -2876,27 +2874,37 @@ findFailedEnableIfCondition(Sema &S, Expr *Cond) {
// Determine which term failed.
Expr *FailedCond = nullptr;
for (Expr *Term : Terms) {
+ Expr *TermAsWritten = Term->IgnoreParenImpCasts();
+
+ // Literals are uninteresting.
+ if (isa<CXXBoolLiteralExpr>(TermAsWritten) ||
+ isa<IntegerLiteral>(TermAsWritten))
+ continue;
+
// The initialization of the parameter from the argument is
// a constant-evaluated context.
EnterExpressionEvaluationContext ConstantEvaluated(
- S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+ *this, Sema::ExpressionEvaluationContext::ConstantEvaluated);
bool Succeeded;
- if (Term->EvaluateAsBooleanCondition(Succeeded, S.Context) &&
+ if (Term->EvaluateAsBooleanCondition(Succeeded, Context) &&
!Succeeded) {
- FailedCond = Term->IgnoreParenImpCasts();
+ FailedCond = TermAsWritten;
break;
}
}
- if (!FailedCond)
+ if (!FailedCond) {
+ if (!AllowTopLevelCond)
+ return { nullptr, "" };
+
FailedCond = Cond->IgnoreParenImpCasts();
+ }
std::string Description;
{
llvm::raw_string_ostream Out(Description);
- FailedCond->printPretty(Out, nullptr,
- PrintingPolicy(S.Context.getLangOpts()));
+ FailedCond->printPretty(Out, nullptr, getPrintingPolicy());
}
return { FailedCond, Description };
}
@@ -2980,8 +2988,9 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
Expr *FailedCond;
std::string FailedDescription;
std::tie(FailedCond, FailedDescription) =
- findFailedEnableIfCondition(
- *this, TemplateArgs[0].getSourceExpression());
+ findFailedBooleanCondition(
+ TemplateArgs[0].getSourceExpression(),
+ /*AllowTopLevelCond=*/true);
// Remove the old SFINAE diagnostic.
PartialDiagnosticAt OldDiag =
@@ -9513,7 +9522,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
Expr *FailedCond;
std::string FailedDescription;
std::tie(FailedCond, FailedDescription) =
- findFailedEnableIfCondition(*this, Cond);
+ findFailedBooleanCondition(Cond, /*AllowTopLevelCond=*/true);
Diag(FailedCond->getExprLoc(),
diag::err_typename_nested_not_found_requirement)
OpenPOWER on IntegriCloud