<div dir="ltr">Fixed in r313499.<div><br></div><div>/Eric</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Sep 17, 2017 at 2:04 PM, Eric Fiselier <span dir="ltr"><<a href="mailto:eric@efcs.ca" target="_blank">eric@efcs.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><div dir="ltr">I'll correct them.<div><br></div><div>/Eric</div></div></span><div class="gmail_extra"><br><div class="gmail_quote"><span class="">On Sat, Sep 16, 2017 at 6:28 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br></span><div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">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:".</div><div class="m_-351395522174857025HOEnZb"><div class="m_-351395522174857025h5"><div class="gmail_extra"><br><div class="gmail_quote">On 16 September 2017 at 05:54, NAKAMURA Takumi via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">This triggered failure in libcxx tests.<div><a href="http://bb.pgr.jp/builders/bootstrap-clang-libcxx-lld-i686-linux/builds/97" target="_blank">http://bb.pgr.jp/builders/boot<wbr>strap-clang-libcxx-lld-i686-li<wbr>nux/builds/97</a><div><div class="m_-351395522174857025m_-1073438357633302932h5"><br><br><div class="gmail_quote"><div dir="ltr">On Fri, Sep 15, 2017 at 8:40 AM Douglas Gregor via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dgregor<br>
Date: Thu Sep 14 16:38:42 2017<br>
New Revision: 313315<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=313315&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=313315&view=rev</a><br>
Log:<br>
Diagnostic specific failed condition in a static_assert.<br>
<br>
When a static_assert fails, dig out a specific condition to diagnose,<br>
using the same logic that we use to find the enable_if condition to<br>
diagnose.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Sema/S<wbr>ema.h<br>
    cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp<br>
    cfe/trunk/test/SemaCXX/static-<wbr>assert.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=313315&r1=313314&r2=313315&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Basic/DiagnosticSemaKinds.td?r<wbr>ev=313315&r1=313314&r2=313315&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td Thu Sep 14 16:38:42 2017<br>
@@ -1219,6 +1219,8 @@ def warn_messaging_unqualified_id : Warn<br>
 def err_static_assert_expression_i<wbr>s_not_constant : Error<<br>
   "static_assert expression is not an integral constant expression">;<br>
 def err_static_assert_failed : Error<"static_assert failed%select{ %1|}0">;<br>
+def err_static_assert_requirement_<wbr>failed : Error<<br>
+  "static_assert failed due to requirement '%0'%select{ %2|}1">;<br>
 def ext_static_assert_no_message : ExtWarn<<br>
   "static_assert with no message is a C++17 extension">, InGroup<CXX17>;<br>
 def warn_cxx14_compat_static_asser<wbr>t_no_message : Warning<<br>
<br>
Modified: cfe/trunk/include/clang/Sema/S<wbr>ema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=313315&r1=313314&r2=313315&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Sema/Sema.h?rev=313315&r1=3133<wbr>14&r2=313315&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/S<wbr>ema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/S<wbr>ema.h Thu Sep 14 16:38:42 2017<br>
@@ -2783,6 +2783,14 @@ public:<br>
   EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,<br>
                               bool MissingImplicitThis = false);<br>
<br>
+  /// Find the failed Boolean condition within a given Boolean<br>
+  /// constant expression, and describe it with a string.<br>
+  ///<br>
+  /// \param AllowTopLevelCond Whether to allow the result to be the<br>
+  /// complete top-level condition.<br>
+  std::pair<Expr *, std::string><br>
+  findFailedBooleanCondition(Exp<wbr>r *Cond, bool AllowTopLevelCond);<br>
+<br>
   /// Emit diagnostics for the diagnose_if attributes on Function, ignoring any<br>
   /// non-ArgDependent DiagnoseIfAttrs.<br>
   ///<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=313315&r1=313314&r2=313315&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaD<wbr>eclCXX.cpp?rev=313315&r1=31331<wbr>4&r2=313315&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp Thu Sep 14 16:38:42 2017<br>
@@ -13296,8 +13296,20 @@ Decl *Sema::BuildStaticAssertDeclar<wbr>ation<br>
       llvm::raw_svector_ostream Msg(MsgBuffer);<br>
       if (AssertMessage)<br>
         AssertMessage->printPretty(Ms<wbr>g, nullptr, getPrintingPolicy());<br>
-      Diag(StaticAssertLoc, diag::err_static_assert_failed<wbr>)<br>
-        << !AssertMessage << Msg.str() << AssertExpr->getSourceRange();<br>
+<br>
+      Expr *InnerCond = nullptr;<br>
+      std::string InnerCondDescription;<br>
+      std::tie(InnerCond, InnerCondDescription) =<br>
+        findFailedBooleanCondition(Con<wbr>verted.get(),<br>
+                                   /*AllowTopLevelCond=*/false);<br>
+      if (InnerCond) {<br>
+        Diag(StaticAssertLoc, diag::err_static_assert_requir<wbr>ement_failed)<br>
+          << InnerCondDescription << !AssertMessage<br>
+          << Msg.str() << InnerCond->getSourceRange();<br>
+      } else {<br>
+        Diag(StaticAssertLoc, diag::err_static_assert_failed<wbr>)<br>
+          << !AssertMessage << Msg.str() << AssertExpr->getSourceRange();<br>
+      }<br>
       Failed = true;<br>
     }<br>
   }<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=313315&r1=313314&r2=313315&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaT<wbr>emplate.cpp?rev=313315&r1=3133<wbr>14&r2=313315&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp Thu Sep 14 16:38:42 2017<br>
@@ -2863,11 +2863,9 @@ static Expr *lookThroughRangesV3Conditio<br>
   return Cond;<br>
 }<br>
<br>
-/// Find the failed subexpression within enable_if, and describe it<br>
-/// with a string.<br>
-static std::pair<Expr *, std::string><br>
-findFailedEnableIfCondition(S<wbr>ema &S, Expr *Cond) {<br>
-  Cond = lookThroughRangesV3Condition(S<wbr>.PP, Cond);<br>
+std::pair<Expr *, std::string><br>
+Sema::findFailedBooleanCondit<wbr>ion(Expr *Cond, bool AllowTopLevelCond) {<br>
+  Cond = lookThroughRangesV3Condition(P<wbr>P, Cond);<br>
<br>
   // Separate out all of the terms in a conjunction.<br>
   SmallVector<Expr *, 4> Terms;<br>
@@ -2876,27 +2874,37 @@ findFailedEnableIfCondition(Se<wbr>ma &S, Exp<br>
   // Determine which term failed.<br>
   Expr *FailedCond = nullptr;<br>
   for (Expr *Term : Terms) {<br>
+    Expr *TermAsWritten = Term->IgnoreParenImpCasts();<br>
+<br>
+    // Literals are uninteresting.<br>
+    if (isa<CXXBoolLiteralExpr>(TermA<wbr>sWritten) ||<br>
+        isa<IntegerLiteral>(TermAsWrit<wbr>ten))<br>
+      continue;<br>
+<br>
     // The initialization of the parameter from the argument is<br>
     // a constant-evaluated context.<br>
     EnterExpressionEvaluationCont<wbr>ext ConstantEvaluated(<br>
-      S, Sema::ExpressionEvaluationCont<wbr>ext::ConstantEvaluated);<br>
+      *this, Sema::ExpressionEvaluationCont<wbr>ext::ConstantEvaluated);<br>
<br>
     bool Succeeded;<br>
-    if (Term->EvaluateAsBooleanCondit<wbr>ion(Succeeded, S.Context) &&<br>
+    if (Term->EvaluateAsBooleanCondit<wbr>ion(Succeeded, Context) &&<br>
         !Succeeded) {<br>
-      FailedCond = Term->IgnoreParenImpCasts();<br>
+      FailedCond = TermAsWritten;<br>
       break;<br>
     }<br>
   }<br>
<br>
-  if (!FailedCond)<br>
+  if (!FailedCond) {<br>
+    if (!AllowTopLevelCond)<br>
+      return { nullptr, "" };<br>
+<br>
     FailedCond = Cond->IgnoreParenImpCasts();<br>
+  }<br>
<br>
   std::string Description;<br>
   {<br>
     llvm::raw_string_ostream Out(Description);<br>
-    FailedCond->printPretty(Out, nullptr,<br>
-                            PrintingPolicy(S.Context.getLa<wbr>ngOpts()));<br>
+    FailedCond->printPretty(Out, nullptr, getPrintingPolicy());<br>
   }<br>
   return { FailedCond, Description };<br>
 }<br>
@@ -2980,8 +2988,9 @@ QualType Sema::CheckTemplateIdType(Temp<wbr>l<br>
             Expr *FailedCond;<br>
             std::string FailedDescription;<br>
             std::tie(FailedCond, FailedDescription) =<br>
-              findFailedEnableIfCondition(<br>
-                *this, TemplateArgs[0].getSourceExpre<wbr>ssion());<br>
+              findFailedBooleanCondition(<br>
+                TemplateArgs[0].getSourceExpre<wbr>ssion(),<br>
+                /*AllowTopLevelCond=*/true);<br>
<br>
             // Remove the old SFINAE diagnostic.<br>
             PartialDiagnosticAt OldDiag =<br>
@@ -9513,7 +9522,7 @@ Sema::CheckTypenameType(Elabor<wbr>atedTypeKe<br>
         Expr *FailedCond;<br>
         std::string FailedDescription;<br>
         std::tie(FailedCond, FailedDescription) =<br>
-          findFailedEnableIfCondition(*t<wbr>his, Cond);<br>
+          findFailedBooleanCondition(Con<wbr>d, /*AllowTopLevelCond=*/true);<br>
<br>
         Diag(FailedCond->getExprLoc()<wbr>,<br>
              diag::err_typename_nested_not_<wbr>found_requirement)<br>
<br>
Modified: cfe/trunk/test/SemaCXX/static-<wbr>assert.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/static-assert.cpp?rev=313315&r1=313314&r2=313315&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/SemaCXX/s<wbr>tatic-assert.cpp?rev=313315&r1<wbr>=313314&r2=313315&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/static-<wbr>assert.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/static-<wbr>assert.cpp Thu Sep 14 16:38:42 2017<br>
@@ -51,3 +51,20 @@ StaticAssertProtected<X> sap2; // expect<br>
<br>
 static_assert(true); // expected-warning {{C++17 extension}}<br>
 static_assert(false); // expected-error-re {{failed{{$}}}} expected-warning {{extension}}<br>
+<br>
+<br>
+// Diagnostics for static_assert with multiple conditions<br>
+template<typename T> struct first_trait {<br>
+  static const bool value = false;<br>
+};<br>
+<br>
+template<><br>
+struct first_trait<X> {<br>
+  static const bool value = true;<br>
+};<br>
+<br>
+template<typename T> struct second_trait {<br>
+  static const bool value = false;<br>
+};<br>
+<br>
+static_assert(first_trait<X>:<wbr>:value && second_trait<X>::value, "message"); // expected-error{{static_assert failed due to requirement 'second_trait<X>::value' "message"}}<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div></div></div></div>
<br>______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div>
</div></div></blockquote></div></div></div><br></div>
</blockquote></div><br></div>