aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-05-19 21:02:16 +0000
committerJason Merrill <jason@redhat.com>2010-05-19 21:02:16 +0000
commite7338039908b1bc3e4093619a9a83581260d69f8 (patch)
tree1f4e82ff0763474f40d38c31b992865c037a7f04
parentd2c421bbb6c551bf315acd24ebee897213212603 (diff)
* typeck.c (merge_types): Preserve memfn quals.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@159598 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog2
-rw-r--r--gcc/cp/typeck.c27
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/g++.dg/parse/fn-typedef2.C7
4 files changed, 27 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 26eaafc386d..6dd97bb23eb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,7 @@
2010-05-19 Jason Merrill <jason@redhat.com>
+ * typeck.c (merge_types): Preserve memfn quals.
+
* decl.c (grokdeclarator): Don't check quals on fn type.
* typeck.c (cp_apply_type_quals_to_decl): Likewise.
* tree.c (cp_build_qualified_type_real): Simplify qualifier checking.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 44d7ab10b21..a46b218700d 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -810,6 +810,7 @@ merge_types (tree t1, tree t2)
tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
tree p1 = TYPE_ARG_TYPES (t1);
tree p2 = TYPE_ARG_TYPES (t2);
+ tree parms;
tree rval, raises;
/* Save space: see if the result is identical to one of the args. */
@@ -821,21 +822,25 @@ merge_types (tree t1, tree t2)
/* Simple way if one arg fails to specify argument types. */
if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
{
- rval = build_function_type (valtype, p2);
- if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))
- rval = build_exception_variant (rval, raises);
- return cp_build_type_attribute_variant (rval, attributes);
+ parms = p2;
+ raises = TYPE_RAISES_EXCEPTIONS (t2);
}
- raises = TYPE_RAISES_EXCEPTIONS (t1);
- if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
+ else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
{
- rval = build_function_type (valtype, p1);
- if (raises)
- rval = build_exception_variant (rval, raises);
- return cp_build_type_attribute_variant (rval, attributes);
+ parms = p1;
+ raises = TYPE_RAISES_EXCEPTIONS (t1);
+ }
+ else
+ {
+ parms = commonparms (p1, p2);
+ /* In cases where we're merging a real declaration with a
+ built-in declaration, t1 is the real one. */
+ raises = TYPE_RAISES_EXCEPTIONS (t1);
}
- rval = build_function_type (valtype, commonparms (p1, p2));
+ rval = build_function_type (valtype, parms);
+ gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2));
+ rval = apply_memfn_quals (rval, type_memfn_quals (t1));
t1 = build_exception_variant (rval, raises);
break;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b6146f68cef..3d12129edd8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,7 @@
2010-05-19 Jason Merrill <jason@redhat.com>
+ * g++.dg/parse/fn-typedef2.C: New.
+
* g++.dg/other/cv_func.C: Don't expect errors about cv-qualified
function type.
diff --git a/gcc/testsuite/g++.dg/parse/fn-typedef2.C b/gcc/testsuite/g++.dg/parse/fn-typedef2.C
new file mode 100644
index 00000000000..c9c7f060d01
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/fn-typedef2.C
@@ -0,0 +1,7 @@
+// Test that merge_types preserves fn cv-quals.
+
+typedef void ft() const;
+typedef void V;
+typedef V ft() const;
+
+ft f; // { dg-error "qualified" }