[PATCH] D54903: [WIP][Sema] Improve static_assert diagnostics.

Clement Courbet via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 26 08:31:45 PST 2018


courbet created this revision.
Herald added a subscriber: cfe-commits.

`static_assert(std::is_same<U, V>::value, "message")` now prints the
value of U and V.


Repository:
  rC Clang

https://reviews.llvm.org/D54903

Files:
  lib/Sema/SemaTemplate.cpp
  test/SemaCXX/static-assert.cpp


Index: test/SemaCXX/static-assert.cpp
===================================================================
--- test/SemaCXX/static-assert.cpp
+++ test/SemaCXX/static-assert.cpp
@@ -68,3 +68,27 @@
 };
 
 static_assert(first_trait<X>::value && second_trait<X>::value, "message"); // expected-error{{static_assert failed due to requirement 'second_trait<X>::value' "message"}}
+
+namespace std {
+
+template <typename T, typename U>
+struct is_same {
+  static const bool value = false;
+};
+
+template <typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+} // namespace std
+
+struct ExampleTypes {
+  using T = int;
+  using U = float;
+};
+
+template <typename T, typename U>
+class StaticAssertIsSame {
+  static_assert(std::is_same<ExampleTypes::T, ExampleTypes::U>::value, "message"); // expected-error{{static_assert failed due to requirement 'int and float are the same type' "message"}}
+};
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -3052,6 +3052,48 @@
   return Cond;
 }
 
+// Pretty prints std::is_same<U, V> as 'U and V are the same types'.
+static void
+prettyPrintFailedIsSameCondition(llvm::raw_string_ostream &OS,
+                                 const RecordDecl *Decl,
+                                 const PrintingPolicy &PrintPolicy) {
+  const auto *const TmplDecl = dyn_cast<ClassTemplateSpecializationDecl>(Decl);
+  assert(TmplDecl &&
+         "std::is_same should be a ClassTemplateSpecializationDecl");
+  const auto &Args = TmplDecl->getTemplateArgs();
+  assert(Args.size() == 2 && "std::is_same should have 2 template parameters");
+  Args.get(0).getAsType().print(OS, PrintPolicy);
+  OS << " and ";
+  Args.get(1).getAsType().print(OS, PrintPolicy);
+  OS << " are the same type";
+}
+
+// Print a diagnostic for the failing static_assert expression. Defaults to
+// pretty-printing the expression.
+static void
+prettyPrintFailedBooleanCondition(llvm::raw_string_ostream &OS,
+                                  const Expr *const FailedCond,
+                                  const PrintingPolicy &PrintPolicy) {
+  if (const auto *const DR = dyn_cast<DeclRefExpr>(FailedCond)) {
+    const auto *const Var = dyn_cast<VarDecl>(DR->getDecl());
+    if (Var && Var->isStaticDataMember() && Var->getName() == "value") {
+      const NestedNameSpecifier *const Qualifier = Var->getQualifier();
+      // This might be an std type trait.
+      const auto *const Record = Qualifier->getAsRecordDecl();
+      const auto *const Parent = Qualifier->getPrefix();
+      if (Parent && Parent->getPrefix() &&
+          Parent->getPrefix()->getKind() == NestedNameSpecifier::Global &&
+          Parent->getAsNamespace() &&
+          Parent->getAsNamespace()->getName() == "std" &&
+          Record->getName() == "is_same") {
+        prettyPrintFailedIsSameCondition(OS, Record, PrintPolicy);
+        return;
+      }
+    }
+  }
+  FailedCond->printPretty(OS, nullptr, PrintPolicy);
+}
+
 std::pair<Expr *, std::string>
 Sema::findFailedBooleanCondition(Expr *Cond, bool AllowTopLevelCond) {
   Cond = lookThroughRangesV3Condition(PP, Cond);
@@ -3093,7 +3135,7 @@
   std::string Description;
   {
     llvm::raw_string_ostream Out(Description);
-    FailedCond->printPretty(Out, nullptr, getPrintingPolicy());
+    prettyPrintFailedBooleanCondition(Out, FailedCond, getPrintingPolicy());
   }
   return { FailedCond, Description };
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54903.175274.patch
Type: text/x-patch
Size: 3510 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20181126/d86df4d2/attachment.bin>


More information about the cfe-commits mailing list