Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp	(revision 206450)
+++ lib/Sema/SemaDeclCXX.cpp	(working copy)
@@ -1175,10 +1175,13 @@
   } else {
     if (ReturnStmts.empty()) {
       // C++1y doesn't require constexpr functions to contain a 'return'
-      // statement. We still do, unless the return type is void, because
+      // statement. We still do, unless the return type might be void, because
       // otherwise if there's no return statement, the function cannot
       // be used in a core constant expression.
-      bool OK = getLangOpts().CPlusPlus1y && Dcl->getReturnType()->isVoidType();
+      bool OK = Dcl->getReturnType()->isVoidType() || 
+                Dcl->getReturnType()->isDependentType();
+      OK = OK && getLangOpts().CPlusPlus1y;
+
       Diag(Dcl->getLocation(),
            OK ? diag::warn_cxx11_compat_constexpr_body_no_return
               : diag::err_constexpr_body_no_return);
Index: test/SemaCXX/cxx1y-deduced-return-type.cpp
===================================================================
--- test/SemaCXX/cxx1y-deduced-return-type.cpp	(revision 206450)
+++ test/SemaCXX/cxx1y-deduced-return-type.cpp	(working copy)
@@ -261,6 +261,8 @@
 
 namespace Constexpr {
   constexpr auto f1(int n) { return n; }
+  template<typename T> struct X { constexpr auto f() {} }; // PR18746
+  template<typename T> struct Y { constexpr T f() {} }; // ok
   struct NonLiteral { ~NonLiteral(); } nl; // expected-note {{user-provided destructor}}
   constexpr auto f2(int n) { return nl; } // expected-error {{return type 'Constexpr::NonLiteral' is not a literal type}}
 }
