From f9ceed32dc9196ddcd2551526637369910a8407b Mon Sep 17 00:00:00 2001
From: Michael Matz <matz@suse.de>
Date: Fri, 19 Mar 2010 16:37:27 +0000
Subject: [PATCH] re PR c++/43116 (ICE when using attributes in a function
 alias declaration)

	PR c++/43116
	* attribs.c (decl_attributes): When rebuilding a function pointer
	type use the same qualifiers as the original pointer type.

testsuite/
	* g++.dg/other/pr43116.C: New testcase.

From-SVN: r157578
---
 gcc/ChangeLog                        | 6 ++++++
 gcc/attribs.c                        | 4 ++++
 gcc/testsuite/ChangeLog              | 5 +++++
 gcc/testsuite/g++.dg/other/pr43116.C | 9 +++++++++
 4 files changed, 24 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/other/pr43116.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index faed150ce016..c255935a0933 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-03-19  Michael Matz  <matz@suse.de>
+
+	PR c++/43116
+	* attribs.c (decl_attributes): When rebuilding a function pointer
+	type use the same qualifiers as the original pointer type.
+
 2010-03-19  Martin Jambor  <mjambor@suse.cz>
 
 	* doc/gimple.texi (Logical Operators): Describe is_gimple_ip_invariant
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 9f2f50bdfd93..9d76a0c30db0 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -286,6 +286,7 @@ decl_attributes (tree *node, tree attributes, int flags)
       tree *anode = node;
       const struct attribute_spec *spec = lookup_attribute_spec (name);
       bool no_add_attrs = 0;
+      int fn_ptr_quals = 0;
       tree fn_ptr_tmp = NULL_TREE;
 
       if (spec == NULL)
@@ -353,6 +354,7 @@ decl_attributes (tree *node, tree attributes, int flags)
 		 This would all be simpler if attributes were part of the
 		 declarator, grumble grumble.  */
 	      fn_ptr_tmp = TREE_TYPE (*anode);
+	      fn_ptr_quals = TYPE_QUALS (*anode);
 	      anode = &fn_ptr_tmp;
 	      flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
 	    }
@@ -449,6 +451,8 @@ decl_attributes (tree *node, tree attributes, int flags)
 	  /* Rebuild the function pointer type and put it in the
 	     appropriate place.  */
 	  fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
+	  if (fn_ptr_quals)
+	    fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals);
 	  if (DECL_P (*node))
 	    TREE_TYPE (*node) = fn_ptr_tmp;
 	  else
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 39705477a34d..758456ecc234 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-03-19  Michael Matz  <matz@suse.de>
+
+	PR c++/43116
+	* g++.dg/other/pr43116.C: New testcase.
+
 2010-03-19  Michael Matz  <matz@suse.de>
 
 	PR target/43305
diff --git a/gcc/testsuite/g++.dg/other/pr43116.C b/gcc/testsuite/g++.dg/other/pr43116.C
new file mode 100644
index 000000000000..f0d9d01e4a86
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/pr43116.C
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+extern "C" int rpl_open (const char *filename, int flags, ...) __attribute__
+((__nonnull__ (1)));
+
+namespace gnulib
+{
+    int (*const open) (const char *filename, int flags, ...) __attribute__
+	((__nonnull__ (1))) = rpl_open;
+}
-- 
GitLab