OSDN Git Service

2012-01-09 Harald Anlauf <anlauf@gmx.de>
[pf3gnuchains/gcc-fork.git] / libgfortran / runtime / compile_options.c
1 /* Handling of compile-time options that influence the library.
2    Copyright (C) 2005, 2007, 2009, 2010, 2011, 2012
3    Free Software Foundation, Inc.
4
5 This file is part of the GNU Fortran runtime library (libgfortran).
6
7 Libgfortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 <http://www.gnu.org/licenses/>.  */
25
26 #include "libgfortran.h"
27 #include <signal.h>
28
29
30 /* Useful compile-time options will be stored in here.  */
31 compile_options_t compile_options;
32
33
34 volatile sig_atomic_t fatal_error_in_progress = 0;
35
36
37 /* Helper function for backtrace_handler to write information about the
38    received signal to stderr before actually giving the backtrace.  */
39 static void
40 show_signal (int signum)
41 {
42   const char * name = NULL, * desc = NULL;
43
44   switch (signum)
45     {
46 #if defined(SIGSEGV)
47       case SIGSEGV:
48         name = "SIGSEGV";
49         desc = "Segmentation fault";
50         break;
51 #endif
52
53 #if defined(SIGBUS)
54       case SIGBUS:
55         name = "SIGBUS";
56         desc = "Bus error";
57         break;
58 #endif
59
60 #if defined(SIGILL)
61       case SIGILL:
62         name = "SIGILL";
63         desc = "Illegal instruction";
64         break;
65 #endif
66
67 #if defined(SIGFPE)
68       case SIGFPE:
69         name = "SIGFPE";
70         desc = "Floating-point exception";
71         break;
72 #endif
73     }
74
75   if (name)
76     st_printf ("\nProgram received signal %d (%s): %s.\n", signum, name, desc);
77   else
78     st_printf ("\nProgram received signal %d.\n", signum);
79 }
80
81
82 /* A signal handler to allow us to output a backtrace.  */
83 void
84 backtrace_handler (int signum)
85 {
86   /* Since this handler is established for more than one kind of signal, 
87      it might still get invoked recursively by delivery of some other kind
88      of signal.  Use a static variable to keep track of that. */
89   if (fatal_error_in_progress)
90     raise (signum);
91   fatal_error_in_progress = 1;
92
93   show_signal (signum);
94   show_backtrace();
95
96   /* Now reraise the signal.  We reactivate the signal's
97      default handling, which is to terminate the process.
98      We could just call exit or abort,
99      but reraising the signal sets the return status
100      from the process correctly. */
101   signal (signum, SIG_DFL);
102   raise (signum);
103 }
104
105
106 /* Helper function for set_options because we need to access the
107    global variable options which is not seen in set_options.  */
108 static void
109 maybe_find_addr2line (void)
110 {
111   if (options.backtrace == -1)
112     find_addr2line ();
113 }
114
115 /* Set the usual compile-time options.  */
116 extern void set_options (int , int []);
117 export_proto(set_options);
118
119 void
120 set_options (int num, int options[])
121 {
122   if (num >= 1)
123     compile_options.warn_std = options[0];
124   if (num >= 2)
125     compile_options.allow_std = options[1];
126   if (num >= 3)
127     compile_options.pedantic = options[2];
128   /* options[3] is the removed -fdump-core option. It's place in the
129      options array is retained due to ABI compatibility. Remove when
130      bumping the library ABI.  */
131   if (num >= 5)
132     compile_options.backtrace = options[4];
133   if (num >= 6)
134     compile_options.sign_zero = options[5];
135   if (num >= 7)
136     compile_options.bounds_check = options[6];
137   if (num >= 8)
138     compile_options.range_check = options[7];
139
140   /* If backtrace is required, we set signal handlers on the POSIX
141      2001 signals with core action.  */
142   if (compile_options.backtrace)
143     {
144 #if defined(SIGQUIT)
145       signal (SIGQUIT, backtrace_handler);
146 #endif
147
148       /* The following 4 signals are defined by C89.  */
149       signal (SIGILL, backtrace_handler);
150       signal (SIGABRT, backtrace_handler);
151       signal (SIGFPE, backtrace_handler);
152       signal (SIGSEGV, backtrace_handler);
153
154 #if defined(SIGBUS)
155       signal (SIGBUS, backtrace_handler);
156 #endif
157
158 #if defined(SIGSYS)
159       signal (SIGSYS, backtrace_handler);
160 #endif
161
162 #if defined(SIGTRAP)
163       signal (SIGTRAP, backtrace_handler);
164 #endif
165
166 #if defined(SIGXCPU)
167       signal (SIGXCPU, backtrace_handler);
168 #endif
169
170 #if defined(SIGXFSZ)
171       signal (SIGXFSZ, backtrace_handler);
172 #endif
173
174       maybe_find_addr2line ();
175     }
176 }
177
178
179 /* Default values for the compile-time options.  Keep in sync with
180    gcc/fortran/options.c (gfc_init_options).  */
181 void
182 init_compile_options (void)
183 {
184   compile_options.warn_std = GFC_STD_F95_DEL | GFC_STD_LEGACY;
185   compile_options.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
186     | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77
187     | GFC_STD_F2008_OBS | GFC_STD_GNU | GFC_STD_LEGACY;
188   compile_options.pedantic = 0;
189   compile_options.backtrace = 0;
190   compile_options.sign_zero = 1;
191   compile_options.range_check = 1;
192 }
193
194 /* Function called by the front-end to tell us the
195    default for unformatted data conversion.  */
196
197 extern void set_convert (int);
198 export_proto (set_convert);
199
200 void
201 set_convert (int conv)
202 {
203   compile_options.convert = conv;
204 }
205
206 extern void set_record_marker (int);
207 export_proto (set_record_marker);
208
209
210 void
211 set_record_marker (int val)
212 {
213
214   switch(val)
215     {
216     case 4:
217       compile_options.record_marker = sizeof (GFC_INTEGER_4);
218       break;
219
220     case 8:
221       compile_options.record_marker = sizeof (GFC_INTEGER_8);
222       break;
223
224     default:
225       runtime_error ("Invalid value for record marker");
226       break;
227     }
228 }
229
230 extern void set_max_subrecord_length (int);
231 export_proto (set_max_subrecord_length);
232
233 void set_max_subrecord_length(int val)
234 {
235   if (val > GFC_MAX_SUBRECORD_LENGTH || val < 1)
236     {
237       runtime_error ("Invalid value for maximum subrecord length");
238       return;
239     }
240
241   compile_options.max_subrecord_length = val;
242 }