Revert r348741 "[Sema] Further improvements to to static_assert diagnostics."
Seems to break build bots. llvm-svn: 348742
This commit is contained in:
parent
057f7695de
commit
d872041f8f
|
@ -2861,7 +2861,11 @@ public:
|
||||||
|
|
||||||
/// Find the failed Boolean condition within a given Boolean
|
/// Find the failed Boolean condition within a given Boolean
|
||||||
/// constant expression, and describe it with a string.
|
/// constant expression, and describe it with a string.
|
||||||
std::pair<Expr *, std::string> findFailedBooleanCondition(Expr *Cond);
|
///
|
||||||
|
/// \param AllowTopLevelCond Whether to allow the result to be the
|
||||||
|
/// complete top-level condition.
|
||||||
|
std::pair<Expr *, std::string>
|
||||||
|
findFailedBooleanCondition(Expr *Cond, bool AllowTopLevelCond);
|
||||||
|
|
||||||
/// Emit diagnostics for the diagnose_if attributes on Function, ignoring any
|
/// Emit diagnostics for the diagnose_if attributes on Function, ignoring any
|
||||||
/// non-ArgDependent DiagnoseIfAttrs.
|
/// non-ArgDependent DiagnoseIfAttrs.
|
||||||
|
|
|
@ -13878,7 +13878,8 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
|
||||||
Expr *InnerCond = nullptr;
|
Expr *InnerCond = nullptr;
|
||||||
std::string InnerCondDescription;
|
std::string InnerCondDescription;
|
||||||
std::tie(InnerCond, InnerCondDescription) =
|
std::tie(InnerCond, InnerCondDescription) =
|
||||||
findFailedBooleanCondition(Converted.get());
|
findFailedBooleanCondition(Converted.get(),
|
||||||
|
/*AllowTopLevelCond=*/false);
|
||||||
if (InnerCond) {
|
if (InnerCond) {
|
||||||
Diag(StaticAssertLoc, diag::err_static_assert_requirement_failed)
|
Diag(StaticAssertLoc, diag::err_static_assert_requirement_failed)
|
||||||
<< InnerCondDescription << !AssertMessage
|
<< InnerCondDescription << !AssertMessage
|
||||||
|
|
|
@ -3052,18 +3052,12 @@ static Expr *lookThroughRangesV3Condition(Preprocessor &PP, Expr *Cond) {
|
||||||
return Cond;
|
return Cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
// Print a diagnostic for the failing static_assert expression. Defaults to
|
||||||
|
// pretty-printing the expression.
|
||||||
// A PrinterHelper that prints more helpful diagnostics for some sub-expressions
|
static void prettyPrintFailedBooleanCondition(llvm::raw_string_ostream &OS,
|
||||||
// within failing boolean expression, such as substituting template parameters
|
const Expr *FailedCond,
|
||||||
// for actual types.
|
const PrintingPolicy &Policy) {
|
||||||
class FailedBooleanConditionPrinterHelper : public PrinterHelper {
|
const auto *DR = dyn_cast<DeclRefExpr>(FailedCond);
|
||||||
public:
|
|
||||||
explicit FailedBooleanConditionPrinterHelper(const PrintingPolicy &Policy)
|
|
||||||
: Policy(Policy) {}
|
|
||||||
|
|
||||||
bool handledStmt(Stmt *E, raw_ostream &OS) override {
|
|
||||||
const auto *DR = dyn_cast<DeclRefExpr>(E);
|
|
||||||
if (DR && DR->getQualifier()) {
|
if (DR && DR->getQualifier()) {
|
||||||
// If this is a qualified name, expand the template arguments in nested
|
// If this is a qualified name, expand the template arguments in nested
|
||||||
// qualifiers.
|
// qualifiers.
|
||||||
|
@ -3075,19 +3069,13 @@ public:
|
||||||
// This is a template variable, print the expanded template arguments.
|
// This is a template variable, print the expanded template arguments.
|
||||||
printTemplateArgumentList(OS, IV->getTemplateArgs().asArray(), Policy);
|
printTemplateArgumentList(OS, IV->getTemplateArgs().asArray(), Policy);
|
||||||
}
|
}
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
return false;
|
FailedCond->printPretty(OS, nullptr, Policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
const PrintingPolicy &Policy;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end anonymous namespace
|
|
||||||
|
|
||||||
std::pair<Expr *, std::string>
|
std::pair<Expr *, std::string>
|
||||||
Sema::findFailedBooleanCondition(Expr *Cond) {
|
Sema::findFailedBooleanCondition(Expr *Cond, bool AllowTopLevelCond) {
|
||||||
Cond = lookThroughRangesV3Condition(PP, Cond);
|
Cond = lookThroughRangesV3Condition(PP, Cond);
|
||||||
|
|
||||||
// Separate out all of the terms in a conjunction.
|
// Separate out all of the terms in a conjunction.
|
||||||
|
@ -3099,6 +3087,11 @@ Sema::findFailedBooleanCondition(Expr *Cond) {
|
||||||
for (Expr *Term : Terms) {
|
for (Expr *Term : Terms) {
|
||||||
Expr *TermAsWritten = Term->IgnoreParenImpCasts();
|
Expr *TermAsWritten = Term->IgnoreParenImpCasts();
|
||||||
|
|
||||||
|
// Literals are uninteresting.
|
||||||
|
if (isa<CXXBoolLiteralExpr>(TermAsWritten) ||
|
||||||
|
isa<IntegerLiteral>(TermAsWritten))
|
||||||
|
continue;
|
||||||
|
|
||||||
// The initialization of the parameter from the argument is
|
// The initialization of the parameter from the argument is
|
||||||
// a constant-evaluated context.
|
// a constant-evaluated context.
|
||||||
EnterExpressionEvaluationContext ConstantEvaluated(
|
EnterExpressionEvaluationContext ConstantEvaluated(
|
||||||
|
@ -3111,18 +3104,18 @@ Sema::findFailedBooleanCondition(Expr *Cond) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!FailedCond)
|
|
||||||
FailedCond = Cond->IgnoreParenImpCasts();
|
|
||||||
|
|
||||||
// Literals are uninteresting.
|
if (!FailedCond) {
|
||||||
if (isa<CXXBoolLiteralExpr>(FailedCond) || isa<IntegerLiteral>(FailedCond))
|
if (!AllowTopLevelCond)
|
||||||
return { nullptr, "" };
|
return { nullptr, "" };
|
||||||
|
|
||||||
|
FailedCond = Cond->IgnoreParenImpCasts();
|
||||||
|
}
|
||||||
|
|
||||||
std::string Description;
|
std::string Description;
|
||||||
{
|
{
|
||||||
llvm::raw_string_ostream Out(Description);
|
llvm::raw_string_ostream Out(Description);
|
||||||
FailedBooleanConditionPrinterHelper Helper(getPrintingPolicy());
|
prettyPrintFailedBooleanCondition(Out, FailedCond, getPrintingPolicy());
|
||||||
FailedCond->printPretty(Out, &Helper, getPrintingPolicy());
|
|
||||||
}
|
}
|
||||||
return { FailedCond, Description };
|
return { FailedCond, Description };
|
||||||
}
|
}
|
||||||
|
@ -3206,7 +3199,9 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
|
||||||
Expr *FailedCond;
|
Expr *FailedCond;
|
||||||
std::string FailedDescription;
|
std::string FailedDescription;
|
||||||
std::tie(FailedCond, FailedDescription) =
|
std::tie(FailedCond, FailedDescription) =
|
||||||
findFailedBooleanCondition(TemplateArgs[0].getSourceExpression());
|
findFailedBooleanCondition(
|
||||||
|
TemplateArgs[0].getSourceExpression(),
|
||||||
|
/*AllowTopLevelCond=*/true);
|
||||||
|
|
||||||
// Remove the old SFINAE diagnostic.
|
// Remove the old SFINAE diagnostic.
|
||||||
PartialDiagnosticAt OldDiag =
|
PartialDiagnosticAt OldDiag =
|
||||||
|
@ -9654,7 +9649,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
||||||
Expr *FailedCond;
|
Expr *FailedCond;
|
||||||
std::string FailedDescription;
|
std::string FailedDescription;
|
||||||
std::tie(FailedCond, FailedDescription) =
|
std::tie(FailedCond, FailedDescription) =
|
||||||
findFailedBooleanCondition(Cond);
|
findFailedBooleanCondition(Cond, /*AllowTopLevelCond=*/true);
|
||||||
|
|
||||||
Diag(FailedCond->getExprLoc(),
|
Diag(FailedCond->getExprLoc(),
|
||||||
diag::err_typename_nested_not_found_requirement)
|
diag::err_typename_nested_not_found_requirement)
|
||||||
|
|
|
@ -14,7 +14,7 @@ template<int N> struct T {
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// expected-error@12 {{static_assert failed due to requirement '1 == 2' "N is not 2!"}}
|
// expected-error@12 {{static_assert failed "N is not 2!"}}
|
||||||
T<1> t1; // expected-note {{in instantiation of template class 'T<1>' requested here}}
|
T<1> t1; // expected-note {{in instantiation of template class 'T<1>' requested here}}
|
||||||
T<2> t2;
|
T<2> t2;
|
||||||
|
|
||||||
|
|
|
@ -38,5 +38,5 @@ struct A {
|
||||||
|
|
||||||
typedef UNION(unsigned, struct A) U1;
|
typedef UNION(unsigned, struct A) U1;
|
||||||
UNION(char[2], short) u2 = { .one = { 'a', 'b' } };
|
UNION(char[2], short) u2 = { .one = { 'a', 'b' } };
|
||||||
typedef UNION(char, short) U3; // expected-error {{static_assert failed due to requirement 'sizeof(char) == sizeof(short)' "type size mismatch"}}
|
typedef UNION(char, short) U3; // expected-error {{static_assert failed "type size mismatch"}}
|
||||||
typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}}
|
typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}}
|
||||||
|
|
|
@ -45,12 +45,3 @@ void foo4() {
|
||||||
};
|
};
|
||||||
template void foo4<float>();
|
template void foo4<float>();
|
||||||
// expected-note@-1{{in instantiation of function template specialization 'foo4<float>' requested here}}
|
// expected-note@-1{{in instantiation of function template specialization 'foo4<float>' requested here}}
|
||||||
|
|
||||||
|
|
||||||
template <typename U, typename V>
|
|
||||||
void foo5() {
|
|
||||||
static_assert(!!(global_inline_var<U, V>));
|
|
||||||
// expected-error@-1{{static_assert failed due to requirement '!!(global_inline_var<int, float>)'}}
|
|
||||||
}
|
|
||||||
template void foo5<int, float>();
|
|
||||||
// expected-note@-1{{in instantiation of function template specialization 'foo5<int, float>' requested here}}
|
|
||||||
|
|
|
@ -15,14 +15,14 @@ class C {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int N> struct T {
|
template<int N> struct T {
|
||||||
static_assert(N == 2, "N is not 2!"); // expected-error {{static_assert failed due to requirement '1 == 2' "N is not 2!"}}
|
static_assert(N == 2, "N is not 2!"); // expected-error {{static_assert failed "N is not 2!"}}
|
||||||
};
|
};
|
||||||
|
|
||||||
T<1> t1; // expected-note {{in instantiation of template class 'T<1>' requested here}}
|
T<1> t1; // expected-note {{in instantiation of template class 'T<1>' requested here}}
|
||||||
T<2> t2;
|
T<2> t2;
|
||||||
|
|
||||||
template<typename T> struct S {
|
template<typename T> struct S {
|
||||||
static_assert(sizeof(T) > sizeof(char), "Type not big enough!"); // expected-error {{static_assert failed due to requirement 'sizeof(char) > sizeof(char)' "Type not big enough!"}}
|
static_assert(sizeof(T) > sizeof(char), "Type not big enough!"); // expected-error {{static_assert failed "Type not big enough!"}}
|
||||||
};
|
};
|
||||||
|
|
||||||
S<char> s1; // expected-note {{in instantiation of template class 'S<char>' requested here}}
|
S<char> s1; // expected-note {{in instantiation of template class 'S<char>' requested here}}
|
||||||
|
@ -111,14 +111,6 @@ static_assert(std::is_same<ExampleTypes::T, ExampleTypes::U>::value, "message");
|
||||||
// expected-error@-1{{static_assert failed due to requirement 'std::is_same<int, float>::value' "message"}}
|
// expected-error@-1{{static_assert failed due to requirement 'std::is_same<int, float>::value' "message"}}
|
||||||
static_assert(std::is_const<ExampleTypes::T>::value, "message");
|
static_assert(std::is_const<ExampleTypes::T>::value, "message");
|
||||||
// expected-error@-1{{static_assert failed due to requirement 'std::is_const<int>::value' "message"}}
|
// expected-error@-1{{static_assert failed due to requirement 'std::is_const<int>::value' "message"}}
|
||||||
static_assert(!std::is_const<const ExampleTypes::T>::value, "message");
|
|
||||||
// expected-error@-1{{static_assert failed due to requirement '!std::is_const<const int>::value' "message"}}
|
|
||||||
static_assert(!(std::is_const<const ExampleTypes::T>::value), "message");
|
|
||||||
// expected-error@-1{{static_assert failed due to requirement '!(std::is_const<const int>::value)' "message"}}
|
|
||||||
static_assert(std::is_const<const ExampleTypes::T>::value == false, "message");
|
|
||||||
// expected-error@-1{{static_assert failed due to requirement 'std::is_const<const int>::value == false' "message"}}
|
|
||||||
static_assert(!(std::is_const<const ExampleTypes::T>::value == true), "message");
|
|
||||||
// expected-error@-1{{static_assert failed due to requirement '!(std::is_const<const int>::value == true)' "message"}}
|
|
||||||
|
|
||||||
struct BI_tag {};
|
struct BI_tag {};
|
||||||
struct RAI_tag : BI_tag {};
|
struct RAI_tag : BI_tag {};
|
||||||
|
|
Loading…
Reference in New Issue