This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]