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]

C++ PATCH: Remove -fguiding-decls



With reluctance, I commited this patch, which removes support for
-fguiding-decls.  (The concept of "guiding declarations" was present
in the ARM, but removed in the ANSI/ISO standard.)

The problem is that the current approach to implementing support for
this feature is inappropriate for use with the new ABI.  The current
approach was to use a different mangling scheme for code compiled with
-fguiding-decls.  So, using this feature already required rebuilding
libgcc, and all other code, with -fguiding-decls.  Under the new ABI,
I don't think GCC should produce incorrectly mangled names, with any
set of options; the risk of confusion when linking with other
compilers, etc., is great.

We also tried to blend guiding-declaration semantics with the new
semantics, and guess which set of semantics the user preferred.

Instead, I think this feature could be implemented in a better way.
Given:

  template <class T> void f(T);	
  void f(int);

We should (with -fguiding-decls) treat `void f(int)' exactly as:

   template void f<int>(int);

except that we should also introduce a dummy template declaration of
`void f(int)' that is used to guide overload resolution.  Any
definition of `void f(int) {}' should be illegal.

(These semantics, by the way, are what the EDG front-end provides with
its --guiding_decls compatibility option.)

In the future, if there is demand, we can reimplement this feature
according to this program.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2000-05-31  Mark Mitchell  <mark@codesourcery.com>

	* invoke.texi: Remove documentation for -fguiding-decls.

Index: invoke.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/invoke.texi,v
retrieving revision 1.192
diff -c -p -r1.192 invoke.texi
*** invoke.texi	2000/05/30 14:37:22	1.192
--- invoke.texi	2000/05/31 19:13:34
*************** in the following sections.
*** 105,111 ****
  @smallexample
  -fno-access-control -fcheck-new -fconserve-space
  -fdollars-in-identifiers -fno-elide-constructors -fexternal-templates
! -ffor-scope -fno-for-scope -fno-gnu-keywords -fguiding-decls -fhonor-std
  -fhuge-objects -fno-implicit-templates -finit-priority
  -fno-implement-inlines -fname-mangling-version-@var{n}
  -fno-default-inline -fno-operator-names -fno-optional-diags -fpermissive
--- 105,111 ----
  @smallexample
  -fno-access-control -fcheck-new -fconserve-space
  -fdollars-in-identifiers -fno-elide-constructors -fexternal-templates
! -ffor-scope -fno-for-scope -fno-gnu-keywords -fhonor-std
  -fhuge-objects -fno-implicit-templates -finit-priority
  -fno-implement-inlines -fname-mangling-version-@var{n}
  -fno-default-inline -fno-operator-names -fno-optional-diags -fpermissive
*************** Do not recognize @code{typeof} as a keyw
*** 1103,1122 ****
  word as an identifier. You can use the keyword @code{__typeof__} instead.  
  @samp{-ansi} implies @samp{-fno-gnu-keywords}.
  
- @item -fguiding-decls
- Treat a function declaration with the same type as a potential function
- template instantiation as though it declares that instantiation, not a
- normal function.  If a definition is given for the function later in the
- translation unit (or another translation unit if the target supports
- weak symbols), that definition will be used; otherwise the template will
- be instantiated.  This behavior reflects the C++ language prior to
- September 1996, when guiding declarations were removed.
- 
- This option implies @samp{-fname-mangling-version-0}, and will not work
- with other name mangling versions.  Like all options that change the
- ABI, all C++ code, @emph{including libgcc.a} must be built with the same
- setting of this option.
- 
  @item -fhonor-std
  Treat the @code{namespace std} as a namespace, instead of ignoring
  it. For compatibility with earlier versions of g++, the compiler will,
--- 1103,1108 ----
*************** could be interpreted as a particular spe
*** 1328,1337 ****
  function. Because this non-conforming behavior is no longer the default
  behavior for g++, @samp{-Wnon-template-friend} allows the compiler to
  check existing code for potential trouble spots, and is on by default.
! This new compiler behavior can also be turned off with the flag
! @samp{-fguiding-decls}, which activates the older, non-specification
! compiler code, or with @samp{-Wno-non-template-friend} which keeps the
! conformant compiler code but disables the helpful warning.
  
  @item -Wold-style-cast (C++ only)
  Warn if an old-style (C-style) cast is used within a C++ program.  The
--- 1314,1322 ----
  function. Because this non-conforming behavior is no longer the default
  behavior for g++, @samp{-Wnon-template-friend} allows the compiler to
  check existing code for potential trouble spots, and is on by default.
! This new compiler behavior can be turned off with
! @samp{-Wno-non-template-friend} which keeps the conformant compiler code
! but disables the helpful warning.
  
  @item -Wold-style-cast (C++ only)
  Warn if an old-style (C-style) cast is used within a C++ program.  The

2000-05-31  Mark Mitchell  <mark@codesourcery.com>

	Remove guiding declaration support.
	* cp/cp-tree.h (flag_dump_translation_unit): Make it const.
	(flag_guiding_decls): Remove.
	* call.c (build_user_type_conversion_1): Remove support for
	guiding decls.
	(build_new_function_call): Likewise.
	(build_new_op): Likewise.
	(build_new_method_call): Likewise.
	* decl.c (start_function): Likewise.
	* friend.c (is_friend): Likewise.
	(do_friend): Likewise.
	* decl2.c ((flag_dump_translation_unit): Make it const.
	(flag_guiding_decls): Remove.
	(unsupported_options): New variable
	(compare_options): New function.
	(lang_decode_option): Use them.

Index: testsuite/g++.old-deja/g++.brendan/template9.C
===================================================================
RCS file: template9.C
diff -N template9.C
*** /sourceware/cvs-tmp/cvs9GipUK	Wed May 31 12:12:16 2000
--- /dev/null	Tue May  5 13:32:27 1998
***************
*** 1,20 ****
- // GROUPS passed templates
- // Test that the compiler will emit the definition of min given just
- // the declaration.  At one point in the past, it did not.
- // Special g++ Options: -fguiding-decls
- #include <iostream.h>
- 
- template <class T> inline T min(T a, T b) { return (a < b) ? a : b;};
- 
- double min(double,double);	// this should expand the template
- 
- main () {
-     int a = 1, b = 2;
-     double aa = 2.0, bb = 1.2;
-     cout << min(a,b) << ", " << min(aa,bb) << "\n";
-     if (min (a, aa) == a)
-       cout << "PASS" << endl;
-     else
-       cout << "FAIL" << endl;
- }
- 
--- 0 ----
Index: testsuite/g++.old-deja/g++.jason/overload10.C
===================================================================
RCS file: overload10.C
diff -N overload10.C
*** /sourceware/cvs-tmp/cvs8FpK1R	Wed May 31 12:12:16 2000
--- /dev/null	Tue May  5 13:32:27 1998
***************
*** 1,22 ****
- // PRMS Id: 4257 (second bug)
- // Bug: g++ fails to recognize multiple previous instantiations of a function
- // template.
- // Build don't link:
- // Special g++ Options: -fguiding-decls
- 
- template <class T>
- class A {
-   int i;
- 
-   friend int foo (A<T>&);
- };
- 
- template <class T> int foo (A<T>& a) { return a.i; }
- 
- A<int> a;
- A<char> dummy;
- 
- void bar ()
- {
-   foo (a);			// gets bogus error - two foo(A<int>&)'s
- }
--- 0 ----
Index: testsuite/g++.old-deja/g++.jason/template13.C
===================================================================
RCS file: template13.C
diff -N template13.C
*** /sourceware/cvs-tmp/cvsZMqts1	Wed May 31 12:12:17 2000
--- /dev/null	Tue May  5 13:32:27 1998
***************
*** 1,10 ****
- // Bug: g++ fails to actually instantiate templates to the specifications of
- // guiding decls.
- // Special g++ Options: -g -ansi -pedantic-errors -fguiding-decls
- 
- template <class T> inline T min (T a, T b) { return a<b?a:b; }
- double min (double, double);
- 
- int main () {
-   return (int) min (0, 1.0);
- }
--- 0 ----
Index: testsuite/g++.old-deja/g++.jason/template38.C
===================================================================
RCS file: template38.C
diff -N template38.C
*** /sourceware/cvs-tmp/cvsRE7lh3	Wed May 31 12:12:17 2000
--- /dev/null	Tue May  5 13:32:27 1998
***************
*** 1,18 ****
- // Special g++ Options: -fguiding-decls
- 
- struct A {
-   friend int operator== (const A&, const A&);
-   A (int) { }
- };
- 
- template <class T> int
- operator== (const T&, const T&)
- {
-   return 0;
- }
- 
- main ()
- {
-   A a (1);
-   return a == 1;
- }
--- 0 ----
Index: testsuite/g++.old-deja/g++.law/template2.C
===================================================================
RCS file: template2.C
diff -N template2.C
*** /sourceware/cvs-tmp/cvsh4qqm8	Wed May 31 12:12:17 2000
--- /dev/null	Tue May  5 13:32:27 1998
***************
*** 1,17 ****
- // GROUPS passed templates
- // Special g++ Options: -fguiding-decls
- extern "C" int printf (const char *, ...);
- 
- template<class T> T max(T a, T b) { return a > b ? a : b; }
- 
- int max(int, int);
- 
- main()
- {
-   int j;
- 
-   j = max(1,2);
-   j = max (1, 'c');
-   printf ("PASS\n");
- }
- 
--- 0 ----
Index: cp/NEWS
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/NEWS,v
retrieving revision 1.23
diff -c -p -r1.23 NEWS
*** NEWS	2000/02/27 21:19:35	1.23
--- NEWS	2000/05/31 19:11:56
***************
*** 1,5 ****
--- 1,7 ----
  *** Changes since GCC 2.95:
  
+ * Support for guiding declarations has been removed.
+ 
  * G++ now supports importing member functions from base classes with a
    using-declaration.
  
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.219
diff -c -p -r1.219 call.c
*** call.c	2000/05/31 06:53:03	1.219
--- call.c	2000/05/31 19:11:59
*************** build_user_type_conversion_1 (totype, ex
*** 2470,2483 ****
    for (p = &(cand->second_conv); TREE_CODE (*p) != IDENTITY_CONV; )
      p = &(TREE_OPERAND (*p, 0));
  
-   /* Pedantically, normal function declarations are never considered
-      to refer to template instantiations, so we only do this with
-      -fguiding-decls.  */ 
-   if (flag_guiding_decls && templates && ! cand->template 
-       && !DECL_INITIAL (cand->fn) 
-       && TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE)
-     add_maybe_template (cand->fn, templates);
- 
    *p = build
      (USER_CONV,
       (DECL_CONSTRUCTOR_P (cand->fn)
--- 2470,2475 ----
*************** build_new_function_call (fn, args)
*** 2593,2605 ****
  	  return error_mark_node;
  	}
  
-       /* Pedantically, normal function declarations are never considered
- 	 to refer to template instantiations, so we only do this with
- 	 -fguiding-decls.  */
-       if (flag_guiding_decls && templates && ! cand->template 
- 	  && ! DECL_INITIAL (cand->fn))
- 	add_maybe_template (cand->fn, templates);
- 
        return build_over_call (cand, args, LOOKUP_NORMAL);
      }
  
--- 2585,2590 ----
*************** build_new_op (code, flags, arg1, arg2, a
*** 3388,3401 ****
  			 : candidates->fn);
  	}
  
-       /* Pedantically, normal function declarations are never considered
- 	 to refer to template instantiations, so we only do this with
- 	 -fguiding-decls.  */ 
-       if (flag_guiding_decls && templates && ! cand->template 
- 	  && ! DECL_INITIAL (cand->fn)
- 	  && TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE)
- 	add_maybe_template (cand->fn, templates);
- 
        return build_over_call
  	(cand,
  	 TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
--- 3373,3378 ----
*************** build_new_method_call (instance, name, a
*** 4460,4472 ****
        && ((instance == current_class_ref && (dtor_label || ctor_label))
  	  || resolves_to_fixed_type_p (instance, 0)))
      flags |= LOOKUP_NONVIRTUAL;
- 
-   /* Pedantically, normal function declarations are never considered
-      to refer to template instantiations, so we only do this with
-      -fguiding-decls.  */ 
-   if (flag_guiding_decls && templates && ! cand->template 
-       && ! DECL_INITIAL (cand->fn))
-     add_maybe_template (cand->fn, templates);
  
    return build_over_call
      (cand,
--- 4437,4442 ----
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.466
diff -c -p -r1.466 cp-tree.h
*** cp-tree.h	2000/05/30 15:44:19	1.466
--- cp-tree.h	2000/05/31 19:12:03
*************** extern int flag_const_strings;
*** 1066,1072 ****
  /* If non-NULL, dump the tree structure for the entire translation
     unit to this file.  */
  
! extern char *flag_dump_translation_unit;
  
  /* Nonzero means warn about deprecated conversion from string constant to
     `char *'.  */
--- 1066,1072 ----
  /* If non-NULL, dump the tree structure for the entire translation
     unit to this file.  */
  
! extern const char *flag_dump_translation_unit;
  
  /* Nonzero means warn about deprecated conversion from string constant to
     `char *'.  */
*************** extern int flag_default_inline;
*** 1177,1185 ****
  /* The name-mangling scheme to use.  Versions of gcc before 2.8 use
     version 0.  */
  extern int name_mangling_version;
- 
- /* Nonzero means that guiding declarations are allowed.  */
- extern int flag_guiding_decls;
  
  /* Nonzero if wchar_t should be `unsigned short' instead of whatever it
     would normally be, for use with WINE.  */
--- 1177,1182 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.618
diff -c -p -r1.618 decl.c
*** decl.c	2000/05/31 16:39:18	1.618
--- decl.c	2000/05/31 19:12:12
*************** start_function (declspecs, declarator, a
*** 13664,13671 ****
    if (!processing_template_decl && !(flags & SF_PRE_PARSED))
      {
        /* A specialization is not used to guide overload resolution.  */
!       if ((flag_guiding_decls
! 	   || !DECL_TEMPLATE_SPECIALIZATION (decl1))
  	  && ! DECL_FUNCTION_MEMBER_P (decl1))
  	decl1 = pushdecl (decl1);
        else
--- 13664,13670 ----
    if (!processing_template_decl && !(flags & SF_PRE_PARSED))
      {
        /* A specialization is not used to guide overload resolution.  */
!       if (!DECL_TEMPLATE_SPECIALIZATION (decl1)
  	  && ! DECL_FUNCTION_MEMBER_P (decl1))
  	decl1 = pushdecl (decl1);
        else
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.357
diff -c -p -r1.357 decl2.c
*** decl2.c	2000/05/28 21:22:12	1.357
--- decl2.c	2000/05/31 19:12:15
*************** static tree prune_vars_needing_no_initia
*** 95,100 ****
--- 95,101 ----
  static void write_out_vars PARAMS ((tree));
  static void import_export_class	PARAMS ((tree));
  static tree key_method PARAMS ((tree));
+ static int compare_options PARAMS ((const PTR, const PTR));
  
  extern int current_class_depth;
  
*************** int flag_const_strings = 1;
*** 247,253 ****
  /* If non-NULL, dump the tree structure for the entire translation
     unit to this file.  */
  
! char *flag_dump_translation_unit = 0;
  
  /* Nonzero means warn about deprecated conversion from string constant to
     `char *'.  */
--- 248,254 ----
  /* If non-NULL, dump the tree structure for the entire translation
     unit to this file.  */
  
! const char *flag_dump_translation_unit = 0;
  
  /* Nonzero means warn about deprecated conversion from string constant to
     `char *'.  */
*************** int max_tinst_depth = 17;
*** 471,479 ****
     arguments.  */
  int name_mangling_version = 2;
  
- /* Nonzero means that guiding declarations are allowed.  */
- int flag_guiding_decls;
- 
  /* Nonzero if wchar_t should be `unsigned short' instead of whatever it
     would normally be, for use with WINE.  */
  int flag_short_wchar;
--- 472,477 ----
*************** lang_f_options[] =
*** 561,566 ****
--- 559,586 ----
    {"xref", &flag_gnu_xref, 1}
  };
  
+ /* The list of `-f' options that we no longer support.  The `-f'
+    prefix is not given in this table.  The `-fno-' variants are not
+    listed here.  This table must be kept in alphabetical order.  */
+ static const char *unsupported_options[] = {
+   "all-virtual",
+   "enum-int-equiv",
+   "guiding-decls"
+   "nonnull-objects",
+   "this-is-variable",
+ };
+ 
+ /* Compare two option strings, pointed two by P1 and P2, for use with
+    bsearch.  */
+ 
+ static int
+ compare_options (p1, p2)
+      const PTR p1;
+      const PTR p2;
+ {
+   return strcmp (*((char **) p1), *((char **) p2));
+ }
+ 
  /* Decode the string P as a language-specific option.
     Return the number of strings consumed for a valid option.
     Otherwise return 0.  Should not complain if it does not
*************** lang_decode_option (argc, argv)
*** 576,582 ****
       char **argv;
  {
    int strings_processed;
!   char *p = argv[0];
  #if USE_CPPLIB
    strings_processed = cpp_handle_option (&parse_in, argc, argv);
  #else
--- 596,602 ----
       char **argv;
  {
    int strings_processed;
!   const char *p = argv[0];
  #if USE_CPPLIB
    strings_processed = cpp_handle_option (&parse_in, argc, argv);
  #else
*************** lang_decode_option (argc, argv)
*** 591,609 ****
  	 P's value is the option sans `-f'.
  	 Search for it in the table of options.  */
        const char *option_value = NULL;
        size_t j;
  
        p += 2;
        /* Try special -f options.  */
  
        if (!strcmp (p, "handle-exceptions")
  	  || !strcmp (p, "no-handle-exceptions"))
  	warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)");
-       else if (!strcmp (p, "all-virtual")
- 	       || !strcmp (p, "enum-int-equiv")
- 	       || !strcmp (p, "no-nonnull-objects")
- 	       || !strcmp (p, "this-is-variable"))
- 	warning ("-f%s is no longer supported", p);
        else if (! strcmp (p, "alt-external-templates"))
  	{
  	  flag_external_templates = 1;
--- 611,646 ----
  	 P's value is the option sans `-f'.
  	 Search for it in the table of options.  */
        const char *option_value = NULL;
+       const char *positive_option;
        size_t j;
  
        p += 2;
        /* Try special -f options.  */
  
+       /* See if this is one of the options no longer supported.  We
+ 	 used to support these options, so we continue to accept them,
+ 	 with a warning.  */
+       if (strncmp (p, "no-", strlen ("no-")) == 0)
+ 	positive_option = p + strlen ("no-");
+       else
+ 	positive_option = p;
+ 
+       /* If the option is present, issue a warning.  Indicate to our
+ 	 caller that the option was processed successfully.  */
+       if (bsearch (&positive_option, 
+ 		   unsupported_options, 
+ 		   sizeof (unsupported_options[0]),
+ 		   (sizeof (unsupported_options) 
+ 		    / sizeof (unsupported_options[0])),
+ 		   compare_options))
+ 	{
+ 	  warning ("-f%s is no longer supported", p);
+ 	  return 1;
+ 	}
+ 
        if (!strcmp (p, "handle-exceptions")
  	  || !strcmp (p, "no-handle-exceptions"))
  	warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)");
        else if (! strcmp (p, "alt-external-templates"))
  	{
  	  flag_external_templates = 1;
*************** lang_decode_option (argc, argv)
*** 617,629 ****
  	  flag_use_repository = 1;
  	  flag_implicit_templates = 0;
  	}
-       else if (!strcmp (p, "guiding-decls"))
- 	{
- 	  flag_guiding_decls = 1;
- 	  name_mangling_version = 0;
- 	}
-       else if (!strcmp (p, "no-guiding-decls"))
- 	flag_guiding_decls = 0;
        else if (!strcmp (p, "external-templates"))
          {
            flag_external_templates = 1;
--- 654,659 ----
Index: cp/friend.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/friend.c,v
retrieving revision 1.58
diff -c -p -r1.58 friend.c
*** friend.c	2000/03/25 16:38:49	1.58
--- friend.c	2000/05/31 19:12:15
*************** is_friend (type, supplicant)
*** 63,81 ****
  		  if (supplicant == TREE_VALUE (friends))
  		    return 1;
  
! 		  /* With -fguiding-decls we are more lenient about
! 		     friendship.  This is bogus in general since two
! 		     specializations of a template with non-type
! 		     template parameters may have the same type, but
! 		     be different.  
! 
! 		     Temporarily, we are also more lenient to deal
! 		     with nested friend functions, for which there can
! 		     be more than one FUNCTION_DECL, despite being the
! 		     same function.  When that's fixed, the
! 		     FUNCTION_MEMBER_P bit can go.  */
! 		  if ((flag_guiding_decls 
! 		       || DECL_FUNCTION_MEMBER_P (supplicant))
  		      && same_type_p (TREE_TYPE (supplicant),
  				      TREE_TYPE (TREE_VALUE (friends))))
  		    return 1;
--- 63,74 ----
  		  if (supplicant == TREE_VALUE (friends))
  		    return 1;
  
! 		  /* Temporarily, we are more lenient to deal with
! 		     nested friend functions, for which there can be
! 		     more than one FUNCTION_DECL, despite being the
! 		     same function.  When that's fixed, this bit can
! 		     go.  */
! 		  if (DECL_FUNCTION_MEMBER_P (supplicant)
  		      && same_type_p (TREE_TYPE (supplicant),
  				      TREE_TYPE (TREE_VALUE (friends))))
  		    return 1;
*************** do_friend (ctype, declarator, decl, parm
*** 402,408 ****
  	    decl = push_template_decl_real (decl, /*is_friend=*/1); 
  
  	  if (warn_nontemplate_friend
! 	      && ! funcdef_flag && ! flag_guiding_decls && ! is_friend_template
  	      && current_template_parms && uses_template_parms (decl))
  	    {
  	      static int explained;
--- 395,401 ----
  	    decl = push_template_decl_real (decl, /*is_friend=*/1); 
  
  	  if (warn_nontemplate_friend
! 	      && ! funcdef_flag && ! is_friend_template
  	      && current_template_parms && uses_template_parms (decl))
  	    {
  	      static int explained;

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