Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c	(revision 203626)
+++ gcc/cp/class.c	(working copy)
@@ -956,6 +956,18 @@ modify_vtable_entry (tree t,
     }
 }
 
+// Returns the template associated with the member FN or
+// NULL if the declaration is neither a template nor temploid.
+static inline tree
+get_member_fn_template (tree fn)
+{
+  if (TREE_CODE (fn) == TEMPLATE_DECL)
+    return fn;
+  if (TREE_CODE (fn) == FUNCTION_DECL && DECL_TEMPLATE_INFO (fn))
+    return DECL_TI_TEMPLATE (fn);
+  return NULL_TREE;
+}
+
 // Returns true if NEWDECL and OLDDECL are member functions with with 
 // different constraints. If NEWDECL and OLDDECL are non-template members
 // or specializations of non-template members, the overloads are 
@@ -965,10 +977,8 @@ modify_vtable_entry (tree t,
 static inline bool
 are_constrained_member_overloads (tree newdecl, tree olddecl) 
 {
-  if (TREE_CODE (newdecl) == FUNCTION_DECL)
-    newdecl = DECL_TI_TEMPLATE (newdecl);
-  if (TREE_CODE (olddecl) == FUNCTION_DECL)
-    olddecl = DECL_TI_TEMPLATE (olddecl);
+  newdecl = get_member_fn_template (newdecl);
+  olddecl = get_member_fn_template (olddecl);
 
   // If neither is a template or temploid, then they cannot
   // be constrained declarations.
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 203704)
+++ gcc/cp/pt.c	(working copy)
@@ -2459,6 +2459,7 @@ check_explicit_specialization (tree decl
 {
   int have_def = flags & 2;
   int is_friend = flags & 4;
+  bool is_concept = flags & 8;
   int specialization = 0;
   int explicit_instantiation = 0;
   int member_specialization = 0;
@@ -2534,6 +2535,11 @@ check_explicit_specialization (tree decl
 
       /* Fall through.  */
     case tsk_expl_spec:
+      if (is_concept)
+        error ("explicit specialization declared %<concept%>");
+      // if (DECL_DECLARED_CONCEPT_P (decl))
+      //   error ("explicit specialization of concept %qD", decl);
+
       SET_DECL_TEMPLATE_SPECIALIZATION (decl);
       if (ctype)
 	member_specialization = 1;
@@ -2844,6 +2850,13 @@ check_explicit_specialization (tree decl
               tree tmpl_func = DECL_TEMPLATE_RESULT (gen_tmpl);
               gcc_assert (TREE_CODE (tmpl_func) == FUNCTION_DECL);
 
+              // A concept cannot be specialized.
+              if (DECL_DECLARED_CONCEPT_P (tmpl_func))
+                {
+                  error ("explicit specialization of concept %qD", gen_tmpl);
+                  return error_mark_node;
+                }
+
               /* This specialization has the same linkage and visibility as
                  the function template it specializes.  */
               TREE_PUBLIC (decl) = TREE_PUBLIC (tmpl_func);
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 203626)
+++ gcc/cp/decl.c	(working copy)
@@ -7430,6 +7430,9 @@ grokfndecl (tree ctype,
   int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
   tree t;
 
+  // Was the concept specifier present?
+  bool concept_p = inlinep & 4;
+
   if (rqual)
     type = build_ref_qualified_type (type, rqual);
   if (raises)
@@ -7766,7 +7769,8 @@ grokfndecl (tree ctype,
   decl = check_explicit_specialization (orig_declarator, decl,
 					template_count,
 					2 * funcdef_flag +
-					4 * (friendp != 0));
+					4 * (friendp != 0) +
+                                        8 * concept_p);
   if (decl == error_mark_node)
     return NULL_TREE;
 
