[ImplicitNulls] Add some clarifying comments; NFC
authorSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 13 Nov 2015 08:14:00 +0000 (08:14 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 13 Nov 2015 08:14:00 +0000 (08:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253020 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/ImplicitNullChecks.cpp

index dbfdbe9d6a66e59a1df922c35ab9ac03907e0f7e..39c1b9fb9a6677aeaddff871bd9413b098c5e6e3 100644 (file)
@@ -281,7 +281,7 @@ bool ImplicitNullChecks::analyzeBlockForNullChecks(
   //
   // we want to end up with
   //
-  //   Def = TrappingLoad (%RAX + <offset>), LblNull
+  //   Def = FaultingLoad (%RAX + <offset>), LblNull
   //   jmp LblNotNull ;; explicit or fallthrough
   //
   //  LblNotNull:
@@ -292,6 +292,30 @@ bool ImplicitNullChecks::analyzeBlockForNullChecks(
   //  LblNull:
   //   callq throw_NullPointerException
   //
+  //
+  // To see why this is legal, consider the two possibilities:
+  //
+  //  1. %RAX is null: since we constrain <offset> to be less than PageSize, the
+  //     load instruction dereferences the null page, causing a segmentation
+  //     fault.
+  //
+  //  2. %RAX is not null: in this case we know that the load cannot fault, as
+  //     otherwise the load would've faulted in the original program too and the
+  //     original program would've been undefined.
+  //
+  // This reasoning cannot be extended to justify hoisting through arbitrary
+  // control flow.  For instance, in the example below (in pseudo-C)
+  //
+  //    if (ptr == null) { throw_npe(); unreachable; }
+  //    if (some_cond) { return 42; }
+  //    v = ptr->field;  // LD
+  //    ...
+  //
+  // we cannot (without code duplication) use the load marked "LD" to null check
+  // ptr -- clause (2) above does not apply in this case.  In the above program
+  // the safety of ptr->field can be dependent on some_cond; and, for instance,
+  // ptr could be some non-null invalid reference that never gets loaded from
+  // because some_cond is always true.
 
   unsigned PointerReg = MBP.LHS.getReg();