[PATCH] D108212: Emit offsetof values as notes when a static_assert fails

Alexander Richardson via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 17 08:32:30 PDT 2021


arichardson created this revision.
arichardson added reviewers: courbet, Quuxplusone, aaron.ballman.
arichardson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Trying to debug a static_assert(offset(foo, field) == ...) failure can be
rather awkward since there is no easy way to print the value at compile
time without another compiler diagnostic involving an array size.
This builds upon the sizeof()/alignof() printing and extends it to handle
OffsetOfExpr.

Depends on D108211 <https://reviews.llvm.org/D108211>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D108212

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


Index: clang/test/SemaCXX/static-assert.cpp
===================================================================
--- clang/test/SemaCXX/static-assert.cpp
+++ clang/test/SemaCXX/static-assert.cpp
@@ -216,3 +216,10 @@
 // expected-error at -1{{static_assert failed due to requirement 'alignof(IntAndPointer) == sizeof(IntAndPointer)' "message"}}
 // expected-note at -2{{with 'alignof(IntAndPointer)' equal to 8}}
 // expected-note at -3{{with 'sizeof(IntAndPointer)' equal to 16}}
+#define offsetof(s, f) __builtin_offsetof(s, f)
+static_assert(__builtin_offsetof(IntAndPointer, p) == -1, "message");
+// expected-error at -1{{static_assert failed due to requirement '__builtin_offsetof(IntAndPointer, p) == -1' "message"}}
+// expected-note at -2{{with '__builtin_offsetof(IntAndPointer, p)' equal to 8}}
+static_assert(offsetof(IntAndPointer, i) == -1, "message");
+// expected-error at -1{{static_assert failed due to requirement '__builtin_offsetof(IntAndPointer, i) == -1' "message"}}
+// expected-note at -2{{with '__builtin_offsetof(IntAndPointer, i)' equal to 0}}
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -3577,10 +3577,10 @@
   explicit FailedBooleanConditionPrinterHelper(
       const PrintingPolicy &P, Sema &S,
       SmallVectorImpl<PartialDiagnosticAt> &Notes)
-      : Policy(P), S(S), Notes(Notes) {}
+      : Policy(P), SemaRef(S), Notes(Notes) {}
 
-  bool handledStmt(Stmt *E, raw_ostream &OS) override {
-    const auto *DR = dyn_cast<DeclRefExpr>(E);
+  bool handledStmt(Stmt *S, raw_ostream &OS) override {
+    const auto *DR = dyn_cast<DeclRefExpr>(S);
     if (DR && DR->getQualifier()) {
       // If this is a qualified name, expand the template arguments in nested
       // qualifiers.
@@ -3595,18 +3595,20 @@
             IV->getSpecializedTemplate()->getTemplateParameters());
       }
       return true;
-    } else if (auto *UE = dyn_cast<UnaryExprOrTypeTraitExpr>(E)) {
+    } else if (isa<UnaryExprOrTypeTraitExpr>(S) || isa<OffsetOfExpr>(S)) {
+      Expr *E = cast<Expr>(S);
       Expr::EvalResult Result;
-      if (UE->EvaluateAsConstantExpr(Result, S.Context) && Result.Val.isInt()) {
+      if (E->EvaluateAsConstantExpr(Result, SemaRef.Context) &&
+          Result.Val.isInt()) {
         std::string ExprStr;
         llvm::raw_string_ostream ExprStream(ExprStr);
-        UE->printPretty(ExprStream, nullptr, Policy);
+        E->printPretty(ExprStream, nullptr, Policy);
         ExprStream.flush();
         Notes.push_back(PartialDiagnosticAt(
-            UE->getExprLoc(),
-            S.PDiag(diag::note_static_assert_requirement_context)
+            E->getExprLoc(),
+            SemaRef.PDiag(diag::note_static_assert_requirement_context)
                 << ExprStr << toString(Result.Val.getInt(), 10)
-                << UE->getSourceRange()));
+                << E->getSourceRange()));
       }
     }
     return false;
@@ -3614,7 +3616,7 @@
 
 private:
   const PrintingPolicy Policy;
-  Sema &S;
+  Sema &SemaRef;
   SmallVectorImpl<PartialDiagnosticAt> &Notes;
 };
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D108212.366909.patch
Type: text/x-patch
Size: 3151 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210817/51da2af9/attachment.bin>


More information about the cfe-commits mailing list