diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index b7af33b3231771543be8728ac3ce78a95d67d830..4238314558b1aaba1afbe71957dd139800066249 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -11213,14 +11213,28 @@ grokfndecl (tree ctype,
      expression, that declaration shall be a definition..."  */
   if (friendp && !funcdef_flag)
     {
+      bool has_errored = false;
       for (tree t = FUNCTION_FIRST_USER_PARMTYPE (decl);
 	   t && t != void_list_node; t = TREE_CHAIN (t))
 	if (TREE_PURPOSE (t))
 	  {
-	    permerror (DECL_SOURCE_LOCATION (decl),
-		       "friend declaration of %qD specifies default "
-		       "arguments and isn%'t a definition", decl);
-	    break;
+	    diagnostic_t diag_kind = DK_PERMERROR;
+	    /* For templates, mark the default argument as erroneous and give a
+	       hard error.  */
+	    if (processing_template_decl)
+	      {
+		diag_kind = DK_ERROR;
+		TREE_PURPOSE (t) = error_mark_node;
+	      }
+	    if (!has_errored)
+	      {
+		has_errored = true;
+		emit_diagnostic (diag_kind,
+				 DECL_SOURCE_LOCATION (decl),
+				 /*diagnostic_option_id=*/0,
+				 "friend declaration of %qD specifies default "
+				 "arguments and isn%'t a definition", decl);
+	      }
 	  }
     }
 
diff --git a/gcc/testsuite/g++.dg/parse/defarg18.C b/gcc/testsuite/g++.dg/parse/defarg18.C
new file mode 100644
index 0000000000000000000000000000000000000000..62c8f15f2843b85f9ea035e3927c523a51798840
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/defarg18.C
@@ -0,0 +1,48 @@
+// PR c++/118319
+// { dg-do "compile" { target c++11 } }
+
+// Template case, that used to crash.
+
+template <int>
+struct S {
+  friend void foo1 (int a = []{}());  // { dg-error "specifies default|only declaration" }
+  friend void foo3 (int a,	      // { dg-error "specifies default|only declaration" }
+		    int b = []{}(),
+		    int c = []{}());
+};
+
+void foo1 (int a) {}
+void foo3 (int a, int b, int c) {}
+
+void hello (){
+  S<0> t;
+  foo1 ();
+  foo3 (1, 2);
+}
+
+
+// Template case, that already worked.
+
+template <int>
+struct T {
+  friend void bar (int a = []{}()); // { dg-error "specifies default|only declaration" }
+};
+
+void hallo (){
+  T<0> t;
+  bar (); // { dg-error "not declared" }
+}
+
+
+// Non template case, that already worked.
+
+struct NoTemplate {
+  friend void baz (int a = []{}()); // { dg-error "specifies default|could not convert" }
+};
+
+void baz (int a) {} // { dg-error "only declaration" }
+
+void ola (){
+  NoTemplate t;
+  baz (); // { dg-error "void value not ignored" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/defarg18a.C b/gcc/testsuite/g++.dg/parse/defarg18a.C
new file mode 100644
index 0000000000000000000000000000000000000000..9157a4d5158fef99ec74a6de7bc94bc68180a3d7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/defarg18a.C
@@ -0,0 +1,33 @@
+// PR c++/118319 - With -fpermissive
+// { dg-do "compile" { target c++11 } }
+// { dg-additional-options "-fpermissive" }
+
+// Template case, that used to crash.
+// Check that we error-out even with -fpermissive.
+
+template <int>
+struct S { // { dg-error "instantiating erroneous template" }
+  friend void foo1 (int a = []{}());  // { dg-warning "specifies default|only declaration" }
+};
+
+void foo1 (int a) {}
+
+void hello (){
+  S<0> t;
+  foo1 ();
+}
+
+
+// Non template case, that already worked.
+// Check that errors are demoted to warnings.
+
+struct NoTemplate {
+  friend void baz (int a = 1); // { dg-warning "specifies default" }
+};
+
+void baz (int a) {} // { dg-warning "only declaration" }
+
+void ola (){
+  NoTemplate t;
+  baz ();
+}