r313315 - Diagnostic specific failed condition in a static_assert.
NAKAMURA Takumi via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 16 05:54:28 PDT 2017
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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170916/b3f79667/attachment.html>
More information about the cfe-commits
mailing list