[PATCH] D33568: Fix crash when evaluating constant expressions involving nullptr

Tim Northover via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu May 25 14:44:51 PDT 2017


t.p.northover created this revision.
Herald added a subscriber: mcrosier.

For the simple casts in the test, we were crashing because the ZeroInitialization function created an LValue with an unexpected SubobjectDesignator: it was valid but didn't actually refer to a valid MostDerivedType.

Since PointerExprEvaluator actually creates an LValue based notionally on what you'd get if you dereferenced the pointer (I think), the MostDerivedType should be set by stripping the pointer from the type as in this patch.

The theoretically simpler solution of providing an invalid SubobjectDesignator (as happens for an int to pointer cast) is incorrect because nullptr has more possible uses in constexprs than other casts of integers.

Does my reasoning look sound? I've been all over that file before I finally thought I knew what was going on and I'm still not entirely confident.


https://reviews.llvm.org/D33568

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/SemaCXX/null-cast.cpp


Index: clang/test/SemaCXX/null-cast.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/null-cast.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A {};
+struct B : virtual A {};
+
+void foo() {
+  (void)static_cast<A&>(*(B *)0); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}}
+}
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -5496,6 +5496,8 @@
   bool ZeroInitialization(const Expr *E) {
     auto Offset = Info.Ctx.getTargetNullPointerValue(E->getType());
     Result.set((Expr*)nullptr, 0, false, true, Offset);
+    Result.getLValueDesignator() =
+        SubobjectDesignator(E->getType()->getPointeeType());
     return true;
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33568.100302.patch
Type: text/x-patch
Size: 901 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170525/523dae07/attachment-0001.bin>


More information about the cfe-commits mailing list