diff mbox

gcc/toplev.{c,h} + PR fortran/{40569,40568} compiler_options() + fixes

Message ID 4CA1A497.7040405@net-b.de
State New
Headers show

Commit Message

Tobias Burnus Sept. 28, 2010, 8:17 a.m. UTC
The  gcc/toplev.{c,h} part of the patch needs middle-end review, the 
rest is in the Fortran FE.

The patch exports the "save_decoded_options" in gcc/toplev.{c,h} and 
uses it in gcc/fortran/options.c to construct a string with the compiler 
flags.

Additionally changed:
- Add documentation
- Include compiler name in compiler_version ("value that identies the 
name and version [...] of the processor")
- Mark the functions as inquiry functions


The patch was build and loosely tested. It is currently bootstrapping 
and will then be regtested on x86-64-linux. OK for the trunk?


Example:
    use iso_fortran_env
    print '(5a)', 'This file was compiled by "', &
                  compiler_version(), '" using the the options "', &
                  compiler_options(),'"'
    end

That gives:

$ gfortran -march=native -m32 hjf34.f90 && ./a.out
This file was compiled by "GCC version 4.6.0 20100928 (experimental) 
[trunk revision 164668]" using the the options "-march=k8-sse3 -msahf 
--param l1-cache-size=64 --param l1-cache-line-size=64 --param 
l2-cache-size=1024 -mtune=k8 -m32"

$ gfortran -Dignored hjf34.f90 && ./a.out
This file was compiled by "GCC version 4.6.0 20100928 (experimental) 
[trunk revision 164668]" using the the options "-mtune=generic 
-march=x86-64"

$ gfortran -Dwith=cpp -cpp hjf34.f90 && ./a.out
This file was compiled by "GCC version 4.6.0 20100928 (experimental) 
[trunk revision 164668]" using the the options "-cpp -D with=cpp 
-mtune=generic -march=x86-64"


Tobias

PS: Still to do: -Wall fixes (bogus warning regarding functions already 
typed), inquiry fixes in expr.c's check_inquiry.

Comments

Daniel Kraft Sept. 28, 2010, 6:10 p.m. UTC | #1
Hi Tobias,

Tobias Burnus wrote:
> The patch was build and loosely tested. It is currently bootstrapping 
> and will then be regtested on x86-64-linux. OK for the trunk?

ok for the Fortran part, considering:

-  add_sym_0 ("compiler_options", GFC_ISYM_COMPILER_OPTIONS, CLASS_IMPURE,
+  add_sym_0 ("compiler_options", GFC_ISYM_COMPILER_OPTIONS, CLASS_INQUIRY,
  	     ACTUAL_NO, BT_CHARACTER, 1, GFC_STD_F2008,
  	     NULL, gfc_simplify_compiler_options, NULL);
    make_from_module();

-  add_sym_0 ("compiler_version", GFC_ISYM_COMPILER_VERSION, CLASS_IMPURE,
+  add_sym_0 ("compiler_version", GFC_ISYM_COMPILER_VERSION, CLASS_INQUIRY,

When you first submitted the patch with CLASS_IMPURE, I wondered about 
this (as those do not seem "impure") but thought it was due to being 
that way in the standard -- but now I guess this was just in accident 
and the standard lists them as inquiry?

+  for (j = 1; j < save_decoded_options_count; j++)
+    {
+      switch (save_decoded_options[j].opt_index)
+        {
+        case OPT_o:
+        case OPT_d:
+        case OPT_dumpbase:
+        case OPT_dumpdir:
+        case OPT_auxbase:
+        case OPT_quiet:
+        case OPT_version:
+        case OPT_fintrinsic_modules_path:
+          /* Ignore these.  */
+          continue;
+        }
+
+      /* Ignore file names. */
+      if (save_decoded_options[j].orig_option_with_args_text[0] == '-')
+	len += 1 + strlen (save_decoded_options[j].orig_option_with_args_text);
+    }

What about adding the if as default clause to the switch instead of the 
continue branching?  This seems to clarify the code-flow better -- but 
just take this is as a suggestion, and feel free to do whatever you like 
better.

But since this is also done in the following loop, it would make code 
also more consistent.

  gfc_expr *
  gfc_simplify_compiler_version (void)
  {
+  char *buffer;
+  size_t len;
+
+  len = strlen ("GCC version ") + strlen (version_string) + 1;
+  buffer = (char*) alloca (len);
+  snprintf (buffer, len, "GCC version %s", version_string);
    return gfc_get_character_expr (gfc_default_character_kind,
-                                &gfc_current_locus, version_string,
-                                strlen (version_string));
+                                &gfc_current_locus, buffer, len);
  }

Possibly stupid question:  Isn't alloca supposed to allocate memory on 
the stack that is free'ed automatically on scope exit?  If so, doesn't 
this create a dangling pointer referenced from the expression?

BTW, in gfc_get_option_string, you used gfc_getmem instead of alloca for 
seemingly "the same" purpose.

Yours,
Daniel

> 
> 
> Example:
>    use iso_fortran_env
>    print '(5a)', 'This file was compiled by "', &
>                  compiler_version(), '" using the the options "', &
>                  compiler_options(),'"'
>    end
> 
> That gives:
> 
> $ gfortran -march=native -m32 hjf34.f90 && ./a.out
> This file was compiled by "GCC version 4.6.0 20100928 (experimental) 
> [trunk revision 164668]" using the the options "-march=k8-sse3 -msahf 
> --param l1-cache-size=64 --param l1-cache-line-size=64 --param 
> l2-cache-size=1024 -mtune=k8 -m32"
> 
> $ gfortran -Dignored hjf34.f90 && ./a.out
> This file was compiled by "GCC version 4.6.0 20100928 (experimental) 
> [trunk revision 164668]" using the the options "-mtune=generic 
> -march=x86-64"
> 
> $ gfortran -Dwith=cpp -cpp hjf34.f90 && ./a.out
> This file was compiled by "GCC version 4.6.0 20100928 (experimental) 
> [trunk revision 164668]" using the the options "-cpp -D with=cpp 
> -mtune=generic -march=x86-64"
> 
> 
> Tobias
> 
> PS: Still to do: -Wall fixes (bogus warning regarding functions already 
> typed), inquiry fixes in expr.c's check_inquiry.
>
Tobias Burnus Sept. 28, 2010, 7:52 p.m. UTC | #2
Daniel Kraft wrote:
> Tobias Burnus wrote:
>> The patch was build and loosely tested. It is currently bootstrapping 
>> and will then be regtested on x86-64-linux. OK for the trunk?
>
> ok for the Fortran part

Thanks for the review! Ian had already approved the toplev.* part; I 
followed his suggestion of adding a comment before gfc_get_option_string.

Comitted as Rev. 164698.


> -  add_sym_0 ("compiler_options", GFC_ISYM_COMPILER_OPTIONS, 
> CLASS_IMPURE,
> +  add_sym_0 ("compiler_options", GFC_ISYM_COMPILER_OPTIONS, 
> CLASS_INQUIRY,
>
> When you first submitted the patch with CLASS_IMPURE, I wondered about 
> this -- but now I guess this was just in accident and the standard 
> lists them as inquiry?

Yes that was on one hand a copy and paste mistake and also another 
misconception of mine. The standard lists them as inquiry functions in 
the module section as "specication inquiry" thus they are full 
"inquiry" citizens.

> What about adding the if as default clause to the switch instead of 
> the continue branching?
Done.

>  gfc_simplify_compiler_version (void)
>  {
> +  buffer = (char*) alloca (len);
>    return gfc_get_character_expr (gfc_default_character_kind,
> + &gfc_current_locus, buffer, len);
>
> Possibly stupid question:  Isn't alloca supposed to allocate memory on 
> the stack that is free'ed automatically on scope exit?  If so, doesn't 
> this create a dangling pointer referenced from the expression?

For gfc_get_option_string I cannot use alloca as I return the string - 
thus it is explicitly freed in gfc_simplify_options. For the version 
string, it only needs to survive until gfc_get_character_expr - which 
then copies the string using gfc_char_to_widechar.

Tobias
diff mbox

Patch

gcc/
2010-09-28  Tobias Burnus  <burnus@net-b.de>

        PR fortran/40569
        PR fortran/40568
	* toplev.h (save_decoded_options, save_decoded_options_count):
	New global variables.
	* toplev.c (save_decoded_options, save_decoded_options_count):
	export variables.

gcc/fortran/
2010-09-28  Tobias Burnus  <burnus@net-b.de>

        PR fortran/40569
        PR fortran/40568
	* intrinsic.c (add_functions): Make compiler_version and
	compiler_options CLASS_INQUIRY.
	* gfortran.h (gfc_get_option_string): New prototype.
	* intrinsic.texi (COMPILER_VERSION, COMPILER_OPTIONS):
	Add documentation.
	(C_SIZEOF): Mark as inquiry function of ISO_C_BINDING.
	(ISO_FORTRAN_ENV): Refer to COMPILER_VERSION and COMPILER_OPTIONS.
	(ISO_C_BINDING): Refer to C_SIZEOF.
	* options.c (gfc_get_option_string): New function.
	* simplify.c (gfc_simplify_compiler_options): Use it.
	(gfc_simplify_compiler_version): Include compiler name.

Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 164676)
+++ gcc/toplev.c	(working copy)
@@ -127,8 +127,8 @@  static bool no_backend;
 #define MAX_LINE 75
 
 /* Decoded options, and number of such options.  */
-static struct cl_decoded_option *save_decoded_options;
-static unsigned int save_decoded_options_count;
+struct cl_decoded_option *save_decoded_options;
+unsigned int save_decoded_options_count;
 
 /* Name of top-level original source file (what was input to cpp).
    This comes from the #-command at the beginning of the actual input.
Index: gcc/toplev.h
===================================================================
--- gcc/toplev.h	(revision 164676)
+++ gcc/toplev.h	(working copy)
@@ -29,6 +29,11 @@  along with GCC; see the file COPYING3.
 #define skip_leading_substring(whole,  part) \
    (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
 
+/* Decoded options, and number of such options.  */
+extern struct cl_decoded_option *save_decoded_options;
+extern unsigned int save_decoded_options_count;
+
+
 extern int toplev_main (int, char **);
 extern void strip_off_ending (char *, int);
 extern void rest_of_decl_compilation (tree, int, int);
Index: gcc/fortran/intrinsic.c
===================================================================
--- gcc/fortran/intrinsic.c	(revision 164676)
+++ gcc/fortran/intrinsic.c	(working copy)
@@ -2644,12 +2644,12 @@  add_functions (void)
   make_from_module();
 
   /* COMPILER_OPTIONS and COMPILER_VERSION are part of ISO_FORTRAN_ENV.  */  
-  add_sym_0 ("compiler_options", GFC_ISYM_COMPILER_OPTIONS, CLASS_IMPURE,
+  add_sym_0 ("compiler_options", GFC_ISYM_COMPILER_OPTIONS, CLASS_INQUIRY,
 	     ACTUAL_NO, BT_CHARACTER, 1, GFC_STD_F2008,
 	     NULL, gfc_simplify_compiler_options, NULL);
   make_from_module();
 
-  add_sym_0 ("compiler_version", GFC_ISYM_COMPILER_VERSION, CLASS_IMPURE,
+  add_sym_0 ("compiler_version", GFC_ISYM_COMPILER_VERSION, CLASS_INQUIRY,
 	     ACTUAL_NO, BT_CHARACTER, 1, GFC_STD_F2008,
 	     NULL, gfc_simplify_compiler_version, NULL);
   make_from_module();
Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h	(revision 164676)
+++ gcc/fortran/gfortran.h	(working copy)
@@ -2403,6 +2403,7 @@  void gfc_init_options (unsigned int,
 bool gfc_handle_option (size_t, const char *, int, int,
 			const struct cl_option_handlers *);
 bool gfc_post_options (const char **);
+char *gfc_get_option_string (void);
 
 /* f95-lang.c */
 void gfc_maybe_initialize_eh (void);
Index: gcc/fortran/intrinsic.texi
===================================================================
--- gcc/fortran/intrinsic.texi	(revision 164676)
+++ gcc/fortran/intrinsic.texi	(working copy)
@@ -86,6 +86,8 @@  Some basic guidelines for editing this d
 * @code{CMPLX}:         CMPLX,     Complex conversion function
 * @code{COMMAND_ARGUMENT_COUNT}: COMMAND_ARGUMENT_COUNT, Get number of command line arguments
 * @code{COMPLEX}:       COMPLEX,   Complex conversion function
+* @code{COMPILER_VERSION}: COMPILER_VERSION, Compiler version string
+* @code{COMPILER_OPTIONS}: COMPILER_OPTIONS, Options passed to the compiler
 * @code{CONJG}:         CONJG,     Complex conjugate function
 * @code{COS}:           COS,       Cosine function
 * @code{COSH}:          COSH,      Hyperbolic cosine function
@@ -2363,7 +2365,7 @@  expression @code{X} occupies.
 Fortran 2008
 
 @item @emph{Class}:
-Intrinsic function
+Inquiry function of the module @code{ISO_C_BINDING}
 
 @item @emph{Syntax}:
 @code{N = C_SIZEOF(X)}
@@ -2375,7 +2377,7 @@  Intrinsic function
 
 @item @emph{Return value}:
 The return value is of type integer and of the system-dependent kind
-@var{C_SIZE_T} (from the @var{ISO_C_BINDING} module). Its value is the
+@code{C_SIZE_T} (from the @code{ISO_C_BINDING} module). Its value is the
 number of bytes occupied by the argument.  If the argument has the
 @code{POINTER} attribute, the number of bytes of the storage area pointed
 to is returned.  If the argument is of a derived type with @code{POINTER}
@@ -2719,6 +2721,92 @@  end program test_command_argument_count
 
 
 
+@node COMPILER_OPTIONS
+@section @code{COMPILER_OPTIONS} --- Options passed to the compiler
+@fnindex COMPILER_OPTIONS
+@cindex flags inquiry function
+@cindex options inquiry function
+@cindex compiler flags inquiry function
+
+@table @asis
+@item @emph{Description}:
+@code{COMPILER_OPTIONS()} returns a string with the options used for
+compiling.
+
+@item @emph{Standard}:
+Fortran 2008
+
+@item @emph{Class}:
+Inquiry function of the module @code{ISO_FORTRAN_ENV}
+
+@item @emph{Syntax}:
+@code{STR = COMPILER_OPTIONS()}
+
+@item @emph{Arguments}:
+None.
+
+@item @emph{Return value}:
+The return value is a default-kind string with system-dependent length.
+It contains the compiler flags used to compile the file, which called
+the @code{COMPILER_OPTIONS} intrinsic.
+
+@item @emph{Example}:
+@smallexample
+   use iso_fortran_env
+   print '(4a)', 'This file was compiled by ', &
+                 compiler_version(), ' using the the options ', &
+                 compiler_options()
+   end
+@end smallexample
+
+@item @emph{See also}:
+@ref{COMPILER_VERSION}, @ref{ISO_FORTRAN_ENV}
+@end table
+
+
+
+@node COMPILER_VERSION
+@section @code{COMPILER_VERSION} --- Compiler version string
+@fnindex COMPILER_VERSION
+@cindex compiler, name and version
+@cindex version of the compiler
+
+@table @asis
+@item @emph{Description}:
+@code{COMPILER_VERSION()} returns a string with the name and the
+version of the compiler.
+
+@item @emph{Standard}:
+Fortran 2008
+
+@item @emph{Class}:
+Inquiry function of the module @code{ISO_FORTRAN_ENV}
+
+@item @emph{Syntax}:
+@code{STR = COMPILER_VERSION()}
+
+@item @emph{Arguments}:
+None.
+
+@item @emph{Return value}:
+The return value is a default-kind string with system-dependent length.
+It contains the name of the compiler and its version number.
+
+@item @emph{Example}:
+@smallexample
+   use iso_fortran_env
+   print '(4a)', 'This file was compiled by ', &
+                 compiler_version(), ' using the the options ', &
+                 compiler_options()
+   end
+@end smallexample
+
+@item @emph{See also}:
+@ref{COMPILER_OPTIONS}, @ref{ISO_FORTRAN_ENV}
+@end table
+
+
+
 @node COMPLEX
 @section @code{COMPLEX} --- Complex conversion function
 @fnindex COMPLEX
@@ -12685,6 +12773,9 @@  Scalar default-integer constant used as
 denote that the lock variable is unlocked. (Fortran 2008 or later.)
 @end table
 
+The module also provides the following intrinsic procedures:
+@ref{COMPILER_OPTIONS} and @ref{COMPILER_VERSION}.
+
 
 
 @node ISO_C_BINDING
@@ -12704,6 +12795,7 @@  manual.
 @item @code{C_F_PROCPOINTER}
 @item @code{C_FUNLOC}
 @item @code{C_LOC}
+@item @code{C_SIZEOF}
 @end table
 @c TODO: Vertical spacing between C_FUNLOC and C_LOC wrong in PDF,
 @c don't really know why.
Index: gcc/fortran/options.c
===================================================================
--- gcc/fortran/options.c	(revision 164676)
+++ gcc/fortran/options.c	(working copy)
@@ -27,6 +27,7 @@  along with GCC; see the file COPYING3.
 #include "flags.h"
 #include "intl.h"
 #include "opts.h"
+#include "toplev.h"  /* For save_decoded_options.  */
 #include "options.h"
 #include "params.h"
 #include "tree-inline.h"
@@ -966,3 +967,75 @@  gfc_handle_option (size_t scode, const c
 
   return result;
 }
+
+
+char *
+gfc_get_option_string (void)
+{
+  unsigned j;
+  size_t len, pos;
+  char *result;
+
+  /* Determine required string length.  */
+
+  len = 0;
+  for (j = 1; j < save_decoded_options_count; j++)
+    {
+      switch (save_decoded_options[j].opt_index)
+        {
+        case OPT_o:
+        case OPT_d:
+        case OPT_dumpbase:
+        case OPT_dumpdir:
+        case OPT_auxbase:
+        case OPT_quiet:
+        case OPT_version:
+        case OPT_fintrinsic_modules_path:
+          /* Ignore these.  */
+          continue;
+        }
+
+      /* Ignore file names. */
+      if (save_decoded_options[j].orig_option_with_args_text[0] == '-')
+	len += 1 + strlen (save_decoded_options[j].orig_option_with_args_text);
+    }
+
+  result = (char *) gfc_getmem (len);
+
+  pos = 0; 
+  for (j = 1; j < save_decoded_options_count; j++)
+    {
+      switch (save_decoded_options[j].opt_index)
+        {
+        case OPT_o:
+        case OPT_d:
+        case OPT_dumpbase:
+        case OPT_dumpdir:
+        case OPT_auxbase:
+        case OPT_quiet:
+        case OPT_version:
+        case OPT_fintrinsic_modules_path:
+          /* Ignore these.  */
+	  continue;
+
+        case OPT_cpp_:
+	  /* Use "-cpp" rather than "-cpp=<temporary file>".  */
+	  len = 4;
+	  break;
+
+        default:
+	  /* Ignore file names. */
+	  if (save_decoded_options[j].orig_option_with_args_text[0] != '-')
+	    continue;
+
+	  len = strlen (save_decoded_options[j].orig_option_with_args_text);
+        }
+
+      memcpy (&result[pos], save_decoded_options[j].orig_option_with_args_text, len);
+      pos += len;
+      result[pos++] = ' ';
+    }
+
+  result[--pos] = '\0';
+  return result;
+}
Index: gcc/fortran/simplify.c
===================================================================
--- gcc/fortran/simplify.c	(revision 164676)
+++ gcc/fortran/simplify.c	(working copy)
@@ -6739,16 +6739,26 @@  gfc_convert_char_constant (gfc_expr *e,
 gfc_expr *
 gfc_simplify_compiler_options (void)
 {
-  /* FIXME: PR40569 - return the proper compiler arguments.  */
-  return gfc_get_character_expr (gfc_default_character_kind,
-                                &gfc_current_locus, "", 0);
+  char *str;
+  gfc_expr *result;
+
+  str = gfc_get_option_string ();
+  result = gfc_get_character_expr (gfc_default_character_kind,
+				   &gfc_current_locus, str, strlen (str));
+  gfc_free (str);
+  return result;
 }
 
 
 gfc_expr *
 gfc_simplify_compiler_version (void)
 {
+  char *buffer;
+  size_t len;
+
+  len = strlen ("GCC version ") + strlen (version_string) + 1;
+  buffer = (char*) alloca (len);
+  snprintf (buffer, len, "GCC version %s", version_string);
   return gfc_get_character_expr (gfc_default_character_kind,
-                                &gfc_current_locus, version_string,
-                                strlen (version_string));
+                                &gfc_current_locus, buffer, len);
 }