diff mbox

C++0x, warnings for uses of override/final in non-c++0x mode, add __final for non-c++0x mode

Message ID 87bown353n.wl%ville@ville-laptop
State New
Headers show

Commit Message

Ville Voutilainen July 21, 2011, 5:39 p.m. UTC
At Thu, 21 Jul 2011 18:34:35 +0300,
Ville Voutilainen wrote:
> On 21 July 2011 18:23, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
> > +struct F : E {}; { dg-error "cannot derive from ‘final’ base" }
> Urgh, botched. Will send a new patch after I finish the test run. Note

This one seems to work...

Comments

Jason Merrill July 22, 2011, 7:43 p.m. UTC | #1
On 07/21/2011 01:39 PM, Ville Voutilainen wrote:
> This one seems to work...

Looks good.  ChangeLogs?

Jason
Ville Voutilainen July 22, 2011, 8:06 p.m. UTC | #2
On 22 July 2011 22:43, Jason Merrill <jason@redhat.com> wrote:
> On 07/21/2011 01:39 PM, Ville Voutilainen wrote:
>> This one seems to work...
> Looks good.  ChangeLogs?
> Jason

In the first patch-mail that had the borken test-patch. Repasted:

2011-07-21 Ville Voutilainen <ville.voutilainen@gmail.com>
<ville.voutilainen@symbio.com>
          Warn about the use of final/override in non-c++0x mode, and
add __final for non-c++0x mode.
          * cp-tree.h (cpp0x_warn_str): Add CPP0X_OVERRIDE_CONTROLS.
          * error.c (maybe_warn_cpp0x): Adjust.
          * parser.c (cp_parser_virt_specifier_seq_opt): Use it. Add
'__final' as a non-c++0x alternative for 'final'.
          * override1.C: This test should use c++0x mode.
          * override3.C: New. Test the diagnostics in c++98 mode.
diff mbox

Patch

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c590585..fb17178 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -393,7 +393,9 @@  typedef enum cpp0x_warn_str
   /* defaulted and deleted functions */
   CPP0X_DEFAULTED_DELETED,
   /* inline namespaces */
-  CPP0X_INLINE_NAMESPACES
+  CPP0X_INLINE_NAMESPACES,
+  /* override controls, override/final */
+  CPP0X_OVERRIDE_CONTROLS
 } cpp0x_warn_str;
   
 /* The various kinds of operation used by composite_pointer_type. */
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 2d7c0f1..d435bbe 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -3227,6 +3227,11 @@  maybe_warn_cpp0x (cpp0x_warn_str str)
 		 "inline namespaces "
 		 "only available with -std=c++0x or -std=gnu++0x");
 	break;	
+      case CPP0X_OVERRIDE_CONTROLS:
+	pedwarn (input_location, 0,
+		 "override controls (override/final) "
+		 "only available with -std=c++0x or -std=gnu++0x");
+        break;
       default:
 	gcc_unreachable();
       }
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 2851801..dc54dc2 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -15596,9 +15596,19 @@  cp_parser_virt_specifier_seq_opt (cp_parser* parser)
       if (token->type != CPP_NAME)
         break;
       if (!strcmp (IDENTIFIER_POINTER(token->u.value), "override"))
-	virt_specifier = VIRT_SPEC_OVERRIDE;
+        {
+          maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS);
+          virt_specifier = VIRT_SPEC_OVERRIDE;
+        }
       else if (!strcmp (IDENTIFIER_POINTER(token->u.value), "final"))
-	virt_specifier = VIRT_SPEC_FINAL;
+        {
+          maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS);
+          virt_specifier = VIRT_SPEC_FINAL;
+        }
+      else if (!strcmp (IDENTIFIER_POINTER(token->u.value), "__final"))
+        {
+          virt_specifier = VIRT_SPEC_FINAL;
+        }
       else
 	break;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/override1.C b/gcc/testsuite/g++.dg/cpp0x/override1.C
index 83e0479..ba580b5 100644
--- a/gcc/testsuite/g++.dg/cpp0x/override1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/override1.C
@@ -1,4 +1,5 @@ 
 // { dg-do compile }
+// { dg-options "--std=c++0x" }
 struct B
 {
   virtual void f() final {}
diff --git a/gcc/testsuite/g++.dg/cpp0x/override3.C b/gcc/testsuite/g++.dg/cpp0x/override3.C
new file mode 100644
index 0000000..2d22cbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/override3.C
@@ -0,0 +1,24 @@ 
+// { dg-do compile }
+// { dg-options "--std=c++98" }
+
+struct B final {}; // { dg-warning "override controls" }
+
+struct D : B {}; // { dg-error "cannot derive from 'final' base" }
+
+struct E __final {};
+
+struct F : E {}; // { dg-error "cannot derive from 'final' base" }
+
+struct G
+{
+  virtual void f();
+};
+
+struct H : G
+{
+  void f() override; // { dg-warning "override controls" }
+};
+
+int main()
+{
+}