This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/40750 (missing call with function typedef)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 20 Jan 2010 16:26:54 -0500
- Subject: C++ PATCH for c++/40750 (missing call with function typedef)
The problem was that we were propagating the 'const' from the typedef to
be an attribute on the function, so the compiler thought we could
discard the call.
Tested x86_64-pc-linux-gnu. I'm applying this to trunk because it's a
very safe fix for a silent wrong-code bug.
commit 5a55a1e6fa32bd47b418698f0d35d58807a61468
Author: Jason Merrill <jason@redhat.com>
Date: Wed Jan 20 14:19:10 2010 -0500
PR c++/40750
* decl.c (grokdeclarator): Clear type_quals for a member function
declared using a typedef. Don't complain about adding cv-quals
to a function typedef in C++0x mode.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 9624771..920d75b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8149,7 +8149,7 @@ grokdeclarator (const cp_declarator *declarator,
/* This was an error in C++98 (cv-qualifiers cannot be added to
a function type), but DR 295 makes the code well-formed by
dropping the extra qualifiers. */
- if (pedantic)
+ if (pedantic && cxx_dialect == cxx98)
{
tree bad_type = build_qualified_type (type, type_quals);
pedwarn (input_location, OPT_pedantic,
@@ -9046,6 +9046,7 @@ grokdeclarator (const cp_declarator *declarator,
/* The qualifiers on the function type become the qualifiers on
the non-static member function. */
memfn_quals |= cp_type_quals (type);
+ type_quals = TYPE_UNQUALIFIED;
}
}
diff --git a/gcc/testsuite/g++.dg/other/cv_func.C b/gcc/testsuite/g++.dg/other/cv_func.C
index 4f10382..788c173 100644
--- a/gcc/testsuite/g++.dg/other/cv_func.C
+++ b/gcc/testsuite/g++.dg/other/cv_func.C
@@ -4,7 +4,6 @@ typedef int FIC(int) const;
typedef int FI(int);
FIC f; // { dg-error "qualified" }
-// { dg-error "ignoring" "ignoring" { target *-*-* } 6 }
struct S {
FIC f; // OK
@@ -15,7 +14,7 @@ struct S {
};
FIC S::*pm = &S::f;
const FI S::*pm2 = &S::f; // { dg-error "qualifier" }
-// { dg-error "cannot convert" "cannot convert" { target *-*-* } 17 }
+// { dg-error "cannot convert" "cannot convert" { target *-*-* } 16 }
const FIC S::*pm3 = &S::f; // { dg-error "qualifier" }
int S::f(int) const
diff --git a/gcc/testsuite/g++.dg/parse/fn-typedef1.C b/gcc/testsuite/g++.dg/parse/fn-typedef1.C
new file mode 100644
index 0000000..6cc8625
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/fn-typedef1.C
@@ -0,0 +1,18 @@
+// PR c++/40750
+
+extern "C" void abort ();
+
+typedef void Fn() const;
+
+struct Foo {
+ Fn fn;
+};
+
+bool called = false;
+void Foo::fn() const { called = true; }
+
+int main() {
+ Foo f; f.fn();
+ if (!called)
+ abort();
+}