r313315 - Diagnostic specific failed condition in a static_assert.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 16 17:28:21 PDT 2017
This is a bug in the libc++ tests. It's OK for them to check that the
static_assert message is produced, but not that they're prefixed with the
exact string "static_assert failed:".
On 16 September 2017 at 05:54, NAKAMURA Takumi via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> This triggered failure in libcxx tests.
> http://bb.pgr.jp/builders/bootstrap-clang-libcxx-lld-i686-linux/builds/97
>
>
> On Fri, Sep 15, 2017 at 8:40 AM Douglas Gregor via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>> Author: dgregor
>> Date: Thu Sep 14 16:38:42 2017
>> New Revision: 313315
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=313315&view=rev
>> Log:
>> Diagnostic specific failed condition in a static_assert.
>>
>> When a static_assert fails, dig out a specific condition to diagnose,
>> using the same logic that we use to find the enable_if condition to
>> diagnose.
>>
>> Modified:
>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> cfe/trunk/include/clang/Sema/Sema.h
>> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>> cfe/trunk/lib/Sema/SemaTemplate.cpp
>> cfe/trunk/test/SemaCXX/static-assert.cpp
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/
>> DiagnosticSemaKinds.td?rev=313315&r1=313314&r2=313315&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 14
>> 16:38:42 2017
>> @@ -1219,6 +1219,8 @@ def warn_messaging_unqualified_id : Warn
>> def err_static_assert_expression_is_not_constant : Error<
>> "static_assert expression is not an integral constant expression">;
>> def err_static_assert_failed : Error<"static_assert failed%select{
>> %1|}0">;
>> +def err_static_assert_requirement_failed : Error<
>> + "static_assert failed due to requirement '%0'%select{ %2|}1">;
>> def ext_static_assert_no_message : ExtWarn<
>> "static_assert with no message is a C++17 extension">, InGroup<CXX17>;
>> def warn_cxx14_compat_static_assert_no_message : Warning<
>>
>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
>> clang/Sema/Sema.h?rev=313315&r1=313314&r2=313315&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Sep 14 16:38:42 2017
>> @@ -2783,6 +2783,14 @@ public:
>> EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *>
>> Args,
>> bool MissingImplicitThis = false);
>>
>> + /// Find the failed Boolean condition within a given Boolean
>> + /// constant expression, and describe it with a string.
>> + ///
>> + /// \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
>> /// non-ArgDependent DiagnoseIfAttrs.
>> ///
>>
>> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
>> SemaDeclCXX.cpp?rev=313315&r1=313314&r2=313315&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Sep 14 16:38:42 2017
>> @@ -13296,8 +13296,20 @@ Decl *Sema::BuildStaticAssertDeclaration
>> llvm::raw_svector_ostream Msg(MsgBuffer);
>> if (AssertMessage)
>> AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
>> - Diag(StaticAssertLoc, diag::err_static_assert_failed)
>> - << !AssertMessage << Msg.str() << AssertExpr->getSourceRange();
>> +
>> + Expr *InnerCond = nullptr;
>> + std::string InnerCondDescription;
>> + std::tie(InnerCond, InnerCondDescription) =
>> + findFailedBooleanCondition(Converted.get(),
>> + /*AllowTopLevelCond=*/false);
>> + if (InnerCond) {
>> + Diag(StaticAssertLoc, diag::err_static_assert_
>> requirement_failed)
>> + << InnerCondDescription << !AssertMessage
>> + << Msg.str() << InnerCond->getSourceRange();
>> + } else {
>> + Diag(StaticAssertLoc, diag::err_static_assert_failed)
>> + << !AssertMessage << Msg.str() << AssertExpr->getSourceRange();
>> + }
>> Failed = true;
>> }
>> }
>>
>> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
>> SemaTemplate.cpp?rev=313315&r1=313314&r2=313315&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Sep 14 16:38:42 2017
>> @@ -2863,11 +2863,9 @@ static Expr *lookThroughRangesV3Conditio
>> 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, Exp
>> // 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(Templ
>> 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(ElaboratedTypeKe
>> 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)
>>
>> Modified: cfe/trunk/test/SemaCXX/static-assert.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
>> SemaCXX/static-assert.cpp?rev=313315&r1=313314&r2=313315&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/test/SemaCXX/static-assert.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/static-assert.cpp Thu Sep 14 16:38:42 2017
>> @@ -51,3 +51,20 @@ StaticAssertProtected<X> sap2; // expect
>>
>> static_assert(true); // expected-warning {{C++17 extension}}
>> static_assert(false); // expected-error-re {{failed{{$}}}}
>> expected-warning {{extension}}
>> +
>> +
>> +// Diagnostics for static_assert with multiple conditions
>> +template<typename T> struct first_trait {
>> + static const bool value = false;
>> +};
>> +
>> +template<>
>> +struct first_trait<X> {
>> + static const bool value = true;
>> +};
>> +
>> +template<typename T> struct second_trait {
>> + static const bool value = false;
>> +};
>> +
>> +static_assert(first_trait<X>::value && second_trait<X>::value,
>> "message"); // expected-error{{static_assert failed due to requirement
>> 'second_trait<X>::value' "message"}}
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170916/e39508f0/attachment-0001.html>
More information about the cfe-commits
mailing list