Index: clang/lib/AST/Interp/ByteCodeExprGen.h
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.h
+++ clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -69,6 +69,8 @@
   bool VisitIntegerLiteral(const IntegerLiteral *E);
   bool VisitParenExpr(const ParenExpr *E);
   bool VisitBinaryOperator(const BinaryOperator *E);
+  bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E);
+  bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -113,6 +113,7 @@
   case CK_NonAtomicToAtomic:
   case CK_NoOp:
   case CK_UserDefinedConversion:
+  case CK_NullToPointer:
     return this->Visit(SubExpr);
 
   case CK_ToVoid:
@@ -564,6 +565,24 @@
   return this->bail(VD);
 }
 
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitCXXBoolLiteralExpr(
+    const CXXBoolLiteralExpr *E) {
+  if (DiscardResult)
+    return true;
+
+  return this->emitConstBool(E->getValue(), E);
+}
+
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitCXXNullPtrLiteralExpr(
+    const CXXNullPtrLiteralExpr *E) {
+  if (DiscardResult)
+    return true;
+
+  return this->emitNullPtr(E);
+}
+
 template <class Emitter>
 void ByteCodeExprGen<Emitter>::emitCleanup() {
   for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
Index: clang/lib/AST/Interp/Disasm.cpp
===================================================================
--- clang/lib/AST/Interp/Disasm.cpp
+++ clang/lib/AST/Interp/Disasm.cpp
@@ -23,13 +23,13 @@
 
 template <typename T>
 inline std::enable_if_t<!std::is_pointer<T>::value, T> ReadArg(Program &P,
-                                                               CodePtr OpPC) {
+                                                               CodePtr &OpPC) {
   return OpPC.read<T>();
 }
 
 template <typename T>
 inline std::enable_if_t<std::is_pointer<T>::value, T> ReadArg(Program &P,
-                                                              CodePtr OpPC) {
+                                                              CodePtr &OpPC) {
   uint32_t ID = OpPC.read<uint32_t>();
   return reinterpret_cast<T>(P.getNativePointer(ID));
 }
Index: clang/lib/AST/Interp/Function.h
===================================================================
--- clang/lib/AST/Interp/Function.h
+++ clang/lib/AST/Interp/Function.h
@@ -66,13 +66,17 @@
   unsigned getArgSize() const { return ArgSize; }
 
   /// Returns a pointer to the start of the code.
-  CodePtr getCodeBegin() const;
+  CodePtr getCodeBegin() const { return Code.data(); }
   /// Returns a pointer to the end of the code.
-  CodePtr getCodeEnd() const;
+  CodePtr getCodeEnd() const { return Code.data() + Code.size(); }
 
   /// Returns the original FunctionDecl.
   const FunctionDecl *getDecl() const { return F; }
 
+  /// Returns the name of the function decl this code
+  /// was generated for.
+  const std::string getName() const { return F->getNameInfo().getAsString(); }
+
   /// Returns the location.
   SourceLocation getLoc() const { return Loc; }
 
Index: clang/lib/AST/Interp/Function.cpp
===================================================================
--- clang/lib/AST/Interp/Function.cpp
+++ clang/lib/AST/Interp/Function.cpp
@@ -21,10 +21,6 @@
     : P(P), Loc(F->getBeginLoc()), F(F), ArgSize(ArgSize),
       ParamTypes(std::move(ParamTypes)), Params(std::move(Params)) {}
 
-CodePtr Function::getCodeBegin() const { return Code.data(); }
-
-CodePtr Function::getCodeEnd() const { return Code.data() + Code.size(); }
-
 Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const {
   auto It = Params.find(Offset);
   assert(It != Params.end() && "Invalid parameter offset");
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -956,13 +956,13 @@
 
 template <typename T>
 inline std::enable_if_t<!std::is_pointer<T>::value, T> ReadArg(InterpState &S,
-                                                               CodePtr OpPC) {
+                                                               CodePtr &OpPC) {
   return OpPC.read<T>();
 }
 
 template <typename T>
 inline std::enable_if_t<std::is_pointer<T>::value, T> ReadArg(InterpState &S,
-                                                              CodePtr OpPC) {
+                                                              CodePtr &OpPC) {
   uint32_t ID = OpPC.read<uint32_t>();
   return reinterpret_cast<T>(S.P.getNativePointer(ID));
 }
Index: clang/lib/AST/Interp/Interp.cpp
===================================================================
--- clang/lib/AST/Interp/Interp.cpp
+++ clang/lib/AST/Interp/Interp.cpp
@@ -399,8 +399,13 @@
   return false;
 }
 bool Interpret(InterpState &S, APValue &Result) {
+  assert(!S.Current->isRoot());
   CodePtr PC = S.Current->getPC();
 
+  // Empty program.
+  if (!PC)
+    return true;
+
   for (;;) {
     auto Op = PC.read<Opcode>();
     CodePtr OpPC = PC;
Index: clang/lib/AST/Interp/Source.h
===================================================================
--- clang/lib/AST/Interp/Source.h
+++ clang/lib/AST/Interp/Source.h
@@ -22,7 +22,7 @@
 class Function;
 
 /// Pointer into the code segment.
-class CodePtr {
+class CodePtr final {
 public:
   CodePtr() : Ptr(nullptr) {}
 
@@ -43,6 +43,8 @@
 
   bool operator!=(const CodePtr &RHS) const { return Ptr != RHS.Ptr; }
 
+  operator bool() const { return Ptr; }
+
   /// Reads data and advances the pointer.
   template <typename T> std::enable_if_t<!std::is_pointer<T>::value, T> read() {
     using namespace llvm::support;
@@ -63,7 +65,7 @@
 };
 
 /// Describes the statement/declaration an opcode was generated from.
-class SourceInfo {
+class SourceInfo final {
 public:
   SourceInfo() {}
   SourceInfo(const Stmt *E) : Source(E) {}
Index: clang/test/AST/Interp/literals.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/Interp/literals.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++11 -verify %s
+
+static_assert(true, "");
+static_assert(false, ""); // expected-error{{failed}}
+static_assert(nullptr == nullptr, "");
+static_assert(1 == 1, "");
+static_assert(1 == 3, ""); // expected-error{{failed}}
+
+constexpr int number = 10;
+static_assert(number == 10, "");
+static_assert(number != 10, ""); // expected-error{{failed}}
+
+constexpr bool getTrue() { return true; }
+constexpr bool getFalse() { return false; }
+constexpr void* getNull() { return nullptr; }