Jason,
somme of our customers have 'interesting' C++ coding rules, they'd like to have the compiler enforced. They want to disable:

1) namespace definitions
2) template declarations
3) multiple inheritance
4) virtual inheritance

But they want to use the STL. This patch implements 4 new flags, intended to be use in the -fno-FOO form. They're only active outside of system header files.

1) -fno-namespaces disables namespace definitions, but not using directives or qualified names.

2) -fno-templates disables primary template declarations, but not template instantiations or specializations (partial or otherwise).

3) -fno-multiple-inheritance disables direct multiple inheritance, but not indirect multiple inheritance

4) -fno-virtual-inheritance disables direct virtual inheritance, but not indirect virtual inheritance.

Thus you can't use any of these features directly, but one can use the STL and have it behave as intended.

WDYT?

nathan
2015-09-15  Nathan Sidwell  <nat...@codesourcery.com>

	c-family/
	* c.opt (fmultiple-inheritance, fvirtual-inheritance, ftemplates,
	fnamespaces): New C++ options.

	cp/
	* decl.c (xref_basetypes): Check virtual and/or multiple
	inheritance not disabled.
	* parser.c (cp_parser_namespace_definition): Check namespaces
	not disabled.
	* pt.c (push_template_decl_real): Check templates not disabled.

	* doc/invoke.texi  (-fmultiple-inheritance, -fvirtual-inheritance,
	-ftemplates, -namespaces): Document.

	testsuite/
	* g++.dg/diagostic/disable.C: New.

Index: c-family/c.opt
===================================================================
--- c-family/c.opt	(revision 227761)
+++ c-family/c.opt	(working copy)
@@ -1257,9 +1257,17 @@ C ObjC C++ ObjC++ Ignore Warn(switch %qs
 fmudflapir
 C ObjC C++ ObjC++ Ignore Warn(switch %qs is no longer supported)
 
+fmultiple-inheritance
+C++ ObjC++ Var(flag_multiple_inheritance) Init(1)
+Enable multiple inheritance
+
 fname-mangling-version-
 C++ ObjC++ Joined Ignore Warn(switch %qs is no longer supported)
 
+fnamespaces
+C++ ObjC++ Var(flag_namespaces) Init(1)
+Enable namespaces
+
 fnew-abi
 C++ ObjC++ Ignore Warn(switch %qs is no longer supported)
 
@@ -1446,6 +1454,10 @@ ftabstop=
 C ObjC C++ ObjC++ Joined RejectNegative UInteger
 -ftabstop=<number>	Distance between tab stops for column reporting
 
+ftemplates
+C++ ObjC++ Var(flag_templates) Init(1)
+Enable templates
+
 ftemplate-backtrace-limit=
 C++ ObjC++ Joined RejectNegative UInteger Var(template_backtrace_limit) Init(10)
 Set the maximum number of template instantiation notes for a single warning or error
@@ -1480,6 +1492,10 @@ fuse-cxa-get-exception-ptr
 C++ ObjC++ Var(flag_use_cxa_get_exception_ptr) Init(2)
 Use __cxa_get_exception_ptr in exception handling
 
+fvirtual-inheritance
+C++ ObjC++ Var(flag_virtual_inheritance) Init(1)
+Enable virtual inheritance
+
 fvisibility-inlines-hidden
 C++ ObjC++
 Marks all inlined functions and methods as having hidden visibility
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 227761)
+++ cp/decl.c	(working copy)
@@ -12814,6 +12814,9 @@ xref_basetypes (tree ref, tree base_list
 	  error ("Java class %qT cannot have multiple bases", ref);
           return false;
         }
+      else if (!flag_multiple_inheritance
+	       && !in_system_header_at (input_location))
+	error ("%qT defined with multiple bases", ref);
     }
 
   if (max_vbases)
@@ -12825,6 +12828,9 @@ xref_basetypes (tree ref, tree base_list
 	  error ("Java class %qT cannot have virtual bases", ref);
           return false;
         }
+      else if (!flag_virtual_inheritance
+	       && !in_system_header_at (input_location))
+	error ("%qT defined with virtual base", ref);
     }
 
   for (igo_prev = binfo; base_list; base_list = TREE_CHAIN (base_list))
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 227761)
+++ cp/parser.c	(working copy)
@@ -16798,6 +16798,9 @@ cp_parser_namespace_definition (cp_parse
 
   has_visibility = handle_namespace_attrs (current_namespace, attribs);
 
+  if (!flag_namespaces && !in_system_header_at (input_location))
+    error  ("namepace %qD entered", current_namespace);
+
   /* Parse the body of the namespace.  */
   cp_parser_namespace_body (parser);
 
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 227761)
+++ cp/pt.c	(working copy)
@@ -5088,6 +5088,9 @@ push_template_decl_real (tree decl, bool
 
   if (is_primary)
     {
+      if (!flag_templates && !in_system_header_at (input_location))
+	error ("template %qD declared", decl);
+
       if (DECL_CLASS_SCOPE_P (decl))
 	member_template_p = true;
       if (TREE_CODE (decl) == TYPE_DECL
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 227761)
+++ doc/invoke.texi	(working copy)
@@ -183,19 +183,19 @@ in the following sections.
 -ffor-scope  -fno-for-scope  -fno-gnu-keywords @gol
 -fno-implicit-templates @gol
 -fno-implicit-inline-templates @gol
--fno-implement-inlines  -fms-extensions @gol
--fno-nonansi-builtins  -fnothrow-opt  -fno-operator-names @gol
+-fno-implement-inlines  -fms-extensions -fno-multiple-inheritance &gol
+-fno-namespaces -fno-nonansi-builtins  -fnothrow-opt  -fno-operator-names @gol
 -fno-optional-diags  -fpermissive @gol
 -fno-pretty-templates @gol
 -frepo  -fno-rtti -fsized-deallocation @gol
 -fstats  -ftemplate-backtrace-limit=@var{n} @gol
--ftemplate-depth=@var{n} @gol
+-ftemplate-depth=@var{n} -fno-templates @gol
 -fno-threadsafe-statics  -fuse-cxa-atexit @gol
 -fno-weak  -nostdinc++ @gol
 -fvisibility-inlines-hidden @gol
 -fvtable-verify=@r{[}std@r{|}preinit@r{|}none@r{]} @gol
 -fvtv-counts -fvtv-debug @gol
--fvisibility-ms-compat @gol
+-fno-virtual-inheritance -fvisibility-ms-compat @gol
 -fext-numeric-literals @gol
 -Wabi=@var{n}  -Wabi-tag  -Wconversion-null  -Wctor-dtor-privacy @gol
 -Wdelete-non-virtual-dtor -Wliteral-suffix -Wnarrowing @gol
@@ -2292,6 +2292,14 @@ errors if these functions are not inline
 Disable Wpedantic warnings about constructs used in MFC, such as implicit
 int and getting a pointer to member function via non-standard syntax.
 
+@item -fno-multiple-inheritance
+@opindex fno-multiple-inheritance
+Do not permit multiple inheritance, except in system header files.
+
+@item -fno-namespaces
+@opindex fno-namespacess
+Do not permit namespace definitions, except in system header files.
+
 @item -fno-nonansi-builtins
 @opindex fno-nonansi-builtins
 Disable built-in declarations of functions that are not mandated by
@@ -2399,6 +2407,10 @@ conforming programs must not rely on a m
 (changed to 1024 in C++11).  The default value is 900, as the compiler
 can run out of stack space before hitting 1024 in some situations.
 
+@item -fno-templates
+@opindex fno-templates
+Do not permit primary template declarations, except in system header files.
+
 @item -fno-threadsafe-statics
 @opindex fno-threadsafe-statics
 Do not emit the extra code to use the routines specified in the C++
@@ -2420,6 +2432,10 @@ Don't use the @code{__cxa_get_exception_
 causes @code{std::uncaught_exception} to be incorrect, but is necessary
 if the runtime routine is not available.
 
+@item -fno-virtual-inheritance
+@opindex fno-virtual-inheritance
+Do not permit virtual inheritance, except in system header files.
+
 @item -fvisibility-inlines-hidden
 @opindex fvisibility-inlines-hidden
 This switch declares that the user does not attempt to compare
Index: testsuite/g++.dg/diagnostic/disable.C
===================================================================
--- testsuite/g++.dg/diagnostic/disable.C	(revision 0)
+++ testsuite/g++.dg/diagnostic/disable.C	(working copy)
@@ -0,0 +1,23 @@
+// { dg-options "-fno-templates -fno-multiple-inheritance -fno-virtual-inheritance -fno-namespaces" }
+
+#include <iostream>
+#include <algorithm>
+
+namespace foo { } // { dg-error "namepace" }
+
+template <typename X> X Foo (); // { dg-error "template" }
+
+struct B1 {};
+struct B2 {};
+struct V {};
+
+struct D :  B1, B2 {}; //  { dg-error "multiple" }
+
+struct E : virtual V {};  // { dg-error "virtual" }
+
+void Baz (int a, int b)
+{
+  std::swap (a, b);
+}
+
+

Reply via email to