From a714e5c5d34f921252d147a23ff3bc0642413824 Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Sat, 17 Feb 2001 19:00:29 -0500
Subject: [PATCH] decl2.c (build_artificial_parm): Set TREE_READONLY.

        * decl2.c (build_artificial_parm): Set TREE_READONLY.

        * decl.c (bad_specifiers): Allow throw specs on things with
        pointer-to-function or -member-function type.
        * init.c (build_default_init): Don't use a CONSTRUCTOR to initialize
        a pmf.

From-SVN: r39810
---
 gcc/cp/ChangeLog                          |  9 +++++++++
 gcc/cp/decl.c                             |  3 ++-
 gcc/cp/decl2.c                            |  3 +++
 gcc/cp/init.c                             |  2 +-
 gcc/testsuite/g++.old-deja/g++.eh/spec7.C | 19 +++++++++++++++++++
 5 files changed, 34 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.old-deja/g++.eh/spec7.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1c557bd0d11..efced16555b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2001-02-17  Jason Merrill  <jason@redhat.com>
+
+	* decl2.c (build_artificial_parm): Set TREE_READONLY.
+
+	* decl.c (bad_specifiers): Allow throw specs on things with 
+	pointer-to-function or -member-function type.
+	* init.c (build_default_init): Don't use a CONSTRUCTOR to initialize
+	a pmf.
+
 2001-02-17  Mark Mitchell  <mark@codesourcery.com>
 
 	* call.c (check_dtor_name): Handle template names correctly.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 7cf983b679b..4e727ad94b9 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8638,7 +8638,8 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
 	      object, type);
   if (friendp)
     cp_error_at ("`%D' declared as a friend", object);
-  if (raises)
+  if (raises && !TYPE_PTRFN_P (TREE_TYPE (object))
+      && !TYPE_PTRMEMFUNC_P (TREE_TYPE (object)))
     cp_error_at ("`%D' declared with an exception specification", object);
 }
 
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 9f79148534e..20aa6a82d72 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -917,6 +917,9 @@ build_artificial_parm (name, type)
 
   parm = build_decl (PARM_DECL, name, type);
   DECL_ARTIFICIAL (parm) = 1;
+  /* All our artificial parms are implicitly `const'; they cannot be
+     assigned to.  */
+  TREE_READONLY (parm) = 1;
   DECL_ARG_TYPE (parm) = type;
   return parm;
 }
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 6386f67f8c3..fb6beab8850 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -218,7 +218,7 @@ build_default_init (type)
        anything with a CONSTRUCTOR for arrays here, as that would imply
        copy-initialization.  */
     return NULL_TREE;
-  else if (AGGREGATE_TYPE_P (type))
+  else if (AGGREGATE_TYPE_P (type) && !TYPE_PTRMEMFUNC_P (type))
     {
       /* This is a default initialization of an aggregate, but not one of
 	 non-POD class type.  We cleverly notice that the initialization
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/spec7.C b/gcc/testsuite/g++.old-deja/g++.eh/spec7.C
new file mode 100644
index 00000000000..1945b84aec7
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.eh/spec7.C
@@ -0,0 +1,19 @@
+// Test that we allow simple throw specs on pointers.
+
+void f() throw () { }
+void (*pf)() throw () = f;
+
+struct A
+{
+  void g() throw () { }
+  static void (A::*pmf)() throw ();
+};
+
+void (A::* A::pmf)() = &A::g;
+
+int main()
+{
+  pf ();
+  A a;
+  (a.*A::pmf)();
+}
-- 
2.30.2