118334Speter/* Subroutines shared by all languages that are variants of C.
290082Sobrien   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3169699Skan   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
418334Speter
590082SobrienThis file is part of GCC.
618334Speter
790082SobrienGCC is free software; you can redistribute it and/or modify it under
890082Sobrienthe terms of the GNU General Public License as published by the Free
990082SobrienSoftware Foundation; either version 2, or (at your option) any later
1090082Sobrienversion.
1118334Speter
1290082SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390082SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490082SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590082Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890082Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
19169699SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169699Skan02110-1301, USA.  */
2118334Speter
2218334Speter#include "config.h"
2350449Sobrien#include "system.h"
24132728Skan#include "coretypes.h"
25132728Skan#include "tm.h"
26132728Skan#include "intl.h"
2718334Speter#include "tree.h"
2818334Speter#include "flags.h"
2950449Sobrien#include "output.h"
3052299Sobrien#include "c-pragma.h"
3152299Sobrien#include "rtl.h"
3290082Sobrien#include "ggc.h"
33132728Skan#include "varray.h"
3490082Sobrien#include "expr.h"
3590082Sobrien#include "c-common.h"
3690082Sobrien#include "diagnostic.h"
3790082Sobrien#include "tm_p.h"
3890082Sobrien#include "obstack.h"
3990082Sobrien#include "cpplib.h"
4090082Sobrien#include "target.h"
41117404Skan#include "langhooks.h"
42117404Skan#include "tree-inline.h"
43117404Skan#include "c-tree.h"
44132728Skan#include "toplev.h"
45169699Skan#include "tree-iterator.h"
46169699Skan#include "hashtab.h"
47169699Skan#include "tree-mudflap.h"
48169699Skan#include "opts.h"
49169699Skan#include "real.h"
50169699Skan#include "cgraph.h"
5118334Speter
52117404Skancpp_reader *parse_in;		/* Declared in c-pragma.h.  */
5390082Sobrien
5490082Sobrien/* We let tm.h override the types used here, to handle trivial differences
5590082Sobrien   such as the choice of unsigned int or long unsigned int for size_t.
5690082Sobrien   When machines start needing nontrivial differences in the size type,
5790082Sobrien   it would be best to do something here to figure out automatically
5890082Sobrien   from other information what type to use.  */
5990082Sobrien
6090082Sobrien#ifndef SIZE_TYPE
6190082Sobrien#define SIZE_TYPE "long unsigned int"
6250449Sobrien#endif
6350449Sobrien
64169699Skan#ifndef PID_TYPE
65169699Skan#define PID_TYPE "int"
66169699Skan#endif
67169699Skan
6890082Sobrien#ifndef WCHAR_TYPE
6990082Sobrien#define WCHAR_TYPE "int"
7050449Sobrien#endif
7190082Sobrien
72117404Skan/* WCHAR_TYPE gets overridden by -fshort-wchar.  */
73117404Skan#define MODIFIED_WCHAR_TYPE \
74117404Skan	(flag_short_wchar ? "short unsigned int" : WCHAR_TYPE)
75117404Skan
7690082Sobrien#ifndef PTRDIFF_TYPE
7790082Sobrien#define PTRDIFF_TYPE "long int"
7850449Sobrien#endif
7950449Sobrien
8090082Sobrien#ifndef WINT_TYPE
8190082Sobrien#define WINT_TYPE "unsigned int"
8290082Sobrien#endif
8318334Speter
8490082Sobrien#ifndef INTMAX_TYPE
8590082Sobrien#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)	\
8690082Sobrien		     ? "int"					\
8790082Sobrien		     : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE)	\
8890082Sobrien			? "long int"				\
8990082Sobrien			: "long long int"))
9090082Sobrien#endif
9190082Sobrien
9290082Sobrien#ifndef UINTMAX_TYPE
9390082Sobrien#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)	\
9490082Sobrien		     ? "unsigned int"				\
9590082Sobrien		     : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE)	\
9690082Sobrien			? "long unsigned int"			\
9790082Sobrien			: "long long unsigned int"))
9890082Sobrien#endif
9990082Sobrien
10090082Sobrien/* The following symbols are subsumed in the c_global_trees array, and
10190082Sobrien   listed here individually for documentation purposes.
10290082Sobrien
10390082Sobrien   INTEGER_TYPE and REAL_TYPE nodes for the standard data types.
10490082Sobrien
10590082Sobrien	tree short_integer_type_node;
10690082Sobrien	tree long_integer_type_node;
10790082Sobrien	tree long_long_integer_type_node;
10890082Sobrien
10990082Sobrien	tree short_unsigned_type_node;
11090082Sobrien	tree long_unsigned_type_node;
11190082Sobrien	tree long_long_unsigned_type_node;
11290082Sobrien
113132728Skan	tree truthvalue_type_node;
114132728Skan	tree truthvalue_false_node;
115132728Skan	tree truthvalue_true_node;
11690082Sobrien
11790082Sobrien	tree ptrdiff_type_node;
11890082Sobrien
11990082Sobrien	tree unsigned_char_type_node;
12090082Sobrien	tree signed_char_type_node;
12190082Sobrien	tree wchar_type_node;
12290082Sobrien	tree signed_wchar_type_node;
12390082Sobrien	tree unsigned_wchar_type_node;
12490082Sobrien
12590082Sobrien	tree float_type_node;
12690082Sobrien	tree double_type_node;
12790082Sobrien	tree long_double_type_node;
12890082Sobrien
12990082Sobrien	tree complex_integer_type_node;
13090082Sobrien	tree complex_float_type_node;
13190082Sobrien	tree complex_double_type_node;
13290082Sobrien	tree complex_long_double_type_node;
13390082Sobrien
134169699Skan	tree dfloat32_type_node;
135169699Skan	tree dfloat64_type_node;
136169699Skan	tree_dfloat128_type_node;
137169699Skan
13890082Sobrien	tree intQI_type_node;
13990082Sobrien	tree intHI_type_node;
14090082Sobrien	tree intSI_type_node;
14190082Sobrien	tree intDI_type_node;
14290082Sobrien	tree intTI_type_node;
14390082Sobrien
14490082Sobrien	tree unsigned_intQI_type_node;
14590082Sobrien	tree unsigned_intHI_type_node;
14690082Sobrien	tree unsigned_intSI_type_node;
14790082Sobrien	tree unsigned_intDI_type_node;
14890082Sobrien	tree unsigned_intTI_type_node;
14990082Sobrien
15090082Sobrien	tree widest_integer_literal_type_node;
15190082Sobrien	tree widest_unsigned_literal_type_node;
15290082Sobrien
15390082Sobrien   Nodes for types `void *' and `const void *'.
15490082Sobrien
15590082Sobrien	tree ptr_type_node, const_ptr_type_node;
15690082Sobrien
15790082Sobrien   Nodes for types `char *' and `const char *'.
15890082Sobrien
15990082Sobrien	tree string_type_node, const_string_type_node;
16090082Sobrien
16190082Sobrien   Type `char[SOMENUMBER]'.
16290082Sobrien   Used when an array of char is needed and the size is irrelevant.
16390082Sobrien
16490082Sobrien	tree char_array_type_node;
16590082Sobrien
16690082Sobrien   Type `int[SOMENUMBER]' or something like it.
16790082Sobrien   Used when an array of int needed and the size is irrelevant.
16890082Sobrien
16990082Sobrien	tree int_array_type_node;
17090082Sobrien
17190082Sobrien   Type `wchar_t[SOMENUMBER]' or something like it.
17290082Sobrien   Used when a wide string literal is created.
17390082Sobrien
17490082Sobrien	tree wchar_array_type_node;
17590082Sobrien
17690082Sobrien   Type `int ()' -- used for implicit declaration of functions.
17790082Sobrien
17890082Sobrien	tree default_function_type;
17990082Sobrien
18090082Sobrien   A VOID_TYPE node, packaged in a TREE_LIST.
18190082Sobrien
18290082Sobrien	tree void_list_node;
18390082Sobrien
18490082Sobrien  The lazily created VAR_DECLs for __FUNCTION__, __PRETTY_FUNCTION__,
18590082Sobrien  and __func__. (C doesn't generate __FUNCTION__ and__PRETTY_FUNCTION__
18690082Sobrien  VAR_DECLS, but C++ does.)
18790082Sobrien
18890082Sobrien	tree function_name_decl_node;
18990082Sobrien	tree pretty_function_name_decl_node;
19090082Sobrien	tree c99_function_name_decl_node;
19190082Sobrien
19290082Sobrien  Stack of nested function name VAR_DECLs.
193132728Skan
19490082Sobrien	tree saved_function_name_decls;
19590082Sobrien
19690082Sobrien*/
19790082Sobrien
19890082Sobrientree c_global_trees[CTI_MAX];
199132728Skan
200117404Skan/* Switches common to the C front ends.  */
201117404Skan
202117404Skan/* Nonzero if prepreprocessing only.  */
203132728Skan
204117404Skanint flag_preprocess_only;
205117404Skan
206132728Skan/* Nonzero means don't output line number information.  */
207132728Skan
208132728Skanchar flag_no_line_commands;
209132728Skan
210132728Skan/* Nonzero causes -E output not to be done, but directives such as
211132728Skan   #define that have side effects are still obeyed.  */
212132728Skan
213132728Skanchar flag_no_output;
214132728Skan
215132728Skan/* Nonzero means dump macros in some fashion.  */
216132728Skan
217132728Skanchar flag_dump_macros;
218132728Skan
219132728Skan/* Nonzero means pass #include lines through to the output.  */
220132728Skan
221132728Skanchar flag_dump_includes;
222132728Skan
223169699Skan/* Nonzero means process PCH files while preprocessing.  */
224169699Skan
225169699Skanbool flag_pch_preprocess;
226169699Skan
227132728Skan/* The file name to which we should write a precompiled header, or
228132728Skan   NULL if no header will be written in this compile.  */
229132728Skan
230132728Skanconst char *pch_file;
231132728Skan
232117404Skan/* Nonzero if an ISO standard was selected.  It rejects macros in the
233117404Skan   user's namespace.  */
234117404Skanint flag_iso;
235117404Skan
236117404Skan/* Nonzero if -undef was given.  It suppresses target built-in macros
237117404Skan   and assertions.  */
238117404Skanint flag_undef;
239117404Skan
24090082Sobrien/* Nonzero means don't recognize the non-ANSI builtin functions.  */
24190082Sobrien
24290082Sobrienint flag_no_builtin;
24390082Sobrien
24490082Sobrien/* Nonzero means don't recognize the non-ANSI builtin functions.
24590082Sobrien   -ansi sets this.  */
24690082Sobrien
24790082Sobrienint flag_no_nonansi_builtin;
24890082Sobrien
24990082Sobrien/* Nonzero means give `double' the same size as `float'.  */
25090082Sobrien
25190082Sobrienint flag_short_double;
25290082Sobrien
25390082Sobrien/* Nonzero means give `wchar_t' the same size as `short'.  */
25490082Sobrien
25590082Sobrienint flag_short_wchar;
25690082Sobrien
257260074Spfg/* Nonzero means allow implicit conversions between vectors with
258260074Spfg   differing numbers of subparts and/or differing element types.  */
259260074Spfgint flag_lax_vector_conversions;
260260074Spfg
261117404Skan/* Nonzero means allow Microsoft extensions without warnings or errors.  */
262117404Skanint flag_ms_extensions;
263117404Skan
264117404Skan/* Nonzero means don't recognize the keyword `asm'.  */
265117404Skan
266117404Skanint flag_no_asm;
267117404Skan
268117404Skan/* Nonzero means to treat bitfields as signed unless they say `unsigned'.  */
269117404Skan
270117404Skanint flag_signed_bitfields = 1;
271117404Skan
272132728Skan/* Warn about #pragma directives that are not recognized.  */
273117404Skan
274132728Skanint warn_unknown_pragmas; /* Tri state variable.  */
275117404Skan
276117404Skan/* Warn about format/argument anomalies in calls to formatted I/O functions
277117404Skan   (*printf, *scanf, strftime, strfmon, etc.).  */
278117404Skan
279117404Skanint warn_format;
280117404Skan
281169699Skan/* Warn about using __null (as NULL in C++) as sentinel.  For code compiled
282169699Skan   with GCC this doesn't matter as __null is guaranteed to have the right
283169699Skan   size.  */
284117404Skan
285169699Skanint warn_strict_null_sentinel;
286117404Skan
287132728Skan/* Zero means that faster, ...NonNil variants of objc_msgSend...
288132728Skan   calls will be used in ObjC; passing nil receivers to such calls
289132728Skan   will most likely result in crashes.  */
290132728Skanint flag_nil_receivers = 1;
291117404Skan
292132728Skan/* Nonzero means that code generation will be altered to support
293132728Skan   "zero-link" execution.  This currently affects ObjC only, but may
294132728Skan   affect other languages in the future.  */
295132728Skanint flag_zero_link = 0;
296132728Skan
297132728Skan/* Nonzero means emit an '__OBJC, __image_info' for the current translation
298132728Skan   unit.  It will inform the ObjC runtime that class definition(s) herein
299132728Skan   contained are to replace one(s) previously loaded.  */
300132728Skanint flag_replace_objc_classes = 0;
301169699Skan
302117404Skan/* C/ObjC language option variables.  */
303117404Skan
304117404Skan
305117404Skan/* Nonzero means allow type mismatches in conditional expressions;
306117404Skan   just make their values `void'.  */
307117404Skan
308117404Skanint flag_cond_mismatch;
309117404Skan
310117404Skan/* Nonzero means enable C89 Amendment 1 features.  */
311117404Skan
312117404Skanint flag_isoc94;
313117404Skan
314117404Skan/* Nonzero means use the ISO C99 dialect of C.  */
315117404Skan
316117404Skanint flag_isoc99;
317117404Skan
318132728Skan/* Nonzero means that we have builtin functions, and main is an int.  */
319117404Skan
320117404Skanint flag_hosted = 1;
321117404Skan
322117404Skan/* Warn if main is suspicious.  */
323117404Skan
324117404Skanint warn_main;
325117404Skan
32690082Sobrien
327117404Skan/* ObjC language option variables.  */
328117404Skan
329117404Skan
330117404Skan/* Open and close the file for outputting class declarations, if
331117404Skan   requested (ObjC).  */
332117404Skan
333117404Skanint flag_gen_declaration;
334117404Skan
335117404Skan/* Tells the compiler that this is a special run.  Do not perform any
336117404Skan   compiling, instead we are to test some platform dependent features
337117404Skan   and output a C header file with appropriate definitions.  */
338117404Skan
339117404Skanint print_struct_values;
340117404Skan
341169699Skan/* Tells the compiler what is the constant string class for Objc.  */
342117404Skan
343117404Skanconst char *constant_string_class_name;
344117404Skan
345117404Skan
346117404Skan/* C++ language option variables.  */
347117404Skan
348117404Skan
349117404Skan/* Nonzero means don't recognize any extension keywords.  */
350117404Skan
351117404Skanint flag_no_gnu_keywords;
352117404Skan
353117404Skan/* Nonzero means do emit exported implementations of functions even if
354117404Skan   they can be inlined.  */
355117404Skan
356117404Skanint flag_implement_inlines = 1;
357117404Skan
358117404Skan/* Nonzero means that implicit instantiations will be emitted if needed.  */
359117404Skan
360117404Skanint flag_implicit_templates = 1;
361117404Skan
362117404Skan/* Nonzero means that implicit instantiations of inline templates will be
363117404Skan   emitted if needed, even if instantiations of non-inline templates
364117404Skan   aren't.  */
365117404Skan
366117404Skanint flag_implicit_inline_templates = 1;
367117404Skan
368117404Skan/* Nonzero means generate separate instantiation control files and
369117404Skan   juggle them at link time.  */
370117404Skan
371117404Skanint flag_use_repository;
372117404Skan
373117404Skan/* Nonzero if we want to issue diagnostics that the standard says are not
374117404Skan   required.  */
375117404Skan
376117404Skanint flag_optional_diags = 1;
377117404Skan
378117404Skan/* Nonzero means we should attempt to elide constructors when possible.  */
379117404Skan
380117404Skanint flag_elide_constructors = 1;
381117404Skan
382117404Skan/* Nonzero means that member functions defined in class scope are
383117404Skan   inline by default.  */
384117404Skan
385117404Skanint flag_default_inline = 1;
386117404Skan
387117404Skan/* Controls whether compiler generates 'type descriptor' that give
388117404Skan   run-time type information.  */
389117404Skan
390117404Skanint flag_rtti = 1;
391117404Skan
392117404Skan/* Nonzero if we want to conserve space in the .o files.  We do this
393117404Skan   by putting uninitialized data and runtime initialized data into
394117404Skan   .common instead of .data at the expense of not flagging multiple
395117404Skan   definitions.  */
396117404Skan
397117404Skanint flag_conserve_space;
398117404Skan
399117404Skan/* Nonzero if we want to obey access control semantics.  */
400117404Skan
401117404Skanint flag_access_control = 1;
402117404Skan
403117404Skan/* Nonzero if we want to check the return value of new and avoid calling
404117404Skan   constructors if it is a null pointer.  */
405117404Skan
406117404Skanint flag_check_new;
407117404Skan
408117404Skan/* Nonzero if we want the new ISO rules for pushing a new scope for `for'
409117404Skan   initialization variables.
410117404Skan   0: Old rules, set by -fno-for-scope.
411117404Skan   2: New ISO rules, set by -ffor-scope.
412117404Skan   1: Try to implement new ISO rules, but with backup compatibility
413117404Skan   (and warnings).  This is the default, for now.  */
414117404Skan
415117404Skanint flag_new_for_scope = 1;
416117404Skan
417117404Skan/* Nonzero if we want to emit defined symbols with common-like linkage as
418117404Skan   weak symbols where possible, in order to conform to C++ semantics.
419117404Skan   Otherwise, emit them as local symbols.  */
420117404Skan
421117404Skanint flag_weak = 1;
422117404Skan
423132728Skan/* 0 means we want the preprocessor to not emit line directives for
424132728Skan   the current working directory.  1 means we want it to do it.  -1
425132728Skan   means we should decide depending on whether debugging information
426132728Skan   is being emitted or not.  */
427132728Skan
428132728Skanint flag_working_directory = -1;
429132728Skan
430117404Skan/* Nonzero to use __cxa_atexit, rather than atexit, to register
431169699Skan   destructors for local statics and global objects.  '2' means it has been
432169699Skan   set nonzero as a default, not by a command-line flag.  */
433117404Skan
434117404Skanint flag_use_cxa_atexit = DEFAULT_USE_CXA_ATEXIT;
435117404Skan
436169699Skan/* Nonzero to use __cxa_get_exception_ptr in C++ exception-handling
437169699Skan   code.  '2' means it has not been set explicitly on the command line.  */
438169699Skan
439169699Skanint flag_use_cxa_get_exception_ptr = 2;
440169699Skan
441117404Skan/* Nonzero means make the default pedwarns warnings instead of errors.
442117404Skan   The value of this flag is ignored if -pedantic is specified.  */
443117404Skan
444117404Skanint flag_permissive;
445117404Skan
446117404Skan/* Nonzero means to implement standard semantics for exception
447117404Skan   specifications, calling unexpected if an exception is thrown that
448117404Skan   doesn't match the specification.  Zero means to treat them as
449117404Skan   assertions and optimize accordingly, but not check them.  */
450117404Skan
451117404Skanint flag_enforce_eh_specs = 1;
452117404Skan
453169699Skan/* Nonzero means to generate thread-safe code for initializing local
454169699Skan   statics.  */
455117404Skan
456169699Skanint flag_threadsafe_statics = 1;
457117404Skan
458117404Skan/* Nonzero means warn about implicit declarations.  */
459117404Skan
460117404Skanint warn_implicit = 1;
461117404Skan
462117404Skan/* Maximum template instantiation depth.  This limit is rather
463117404Skan   arbitrary, but it exists to limit the time it takes to notice
464117404Skan   infinite template instantiations.  */
465117404Skan
466117404Skanint max_tinst_depth = 500;
467117404Skan
468117404Skan
469117404Skan
47090082Sobrien/* The elements of `ridpointers' are identifier nodes for the reserved
47190082Sobrien   type names and storage classes.  It is indexed by a RID_... value.  */
47290082Sobrientree *ridpointers;
47390082Sobrien
474132728Skantree (*make_fname_decl) (tree, int);
47590082Sobrien
47650449Sobrien/* Nonzero means the expression being parsed will never be evaluated.
47750449Sobrien   This is a count, since unevaluated expressions can nest.  */
47850449Sobrienint skip_evaluation;
47950449Sobrien
48090082Sobrien/* Information about how a function name is generated.  */
48190082Sobrienstruct fname_var_t
48290082Sobrien{
48390082Sobrien  tree *const decl;	/* pointer to the VAR_DECL.  */
48490082Sobrien  const unsigned rid;	/* RID number for the identifier.  */
48590082Sobrien  const int pretty;	/* How pretty is it? */
48690082Sobrien};
48718334Speter
48890082Sobrien/* The three ways of getting then name of the current function.  */
48950449Sobrien
49090082Sobrienconst struct fname_var_t fname_vars[] =
49190082Sobrien{
49290082Sobrien  /* C99 compliant __func__, must be first.  */
49390082Sobrien  {&c99_function_name_decl_node, RID_C99_FUNCTION_NAME, 0},
49490082Sobrien  /* GCC __FUNCTION__ compliant.  */
49590082Sobrien  {&function_name_decl_node, RID_FUNCTION_NAME, 0},
49690082Sobrien  /* GCC __PRETTY_FUNCTION__ compliant.  */
49790082Sobrien  {&pretty_function_name_decl_node, RID_PRETTY_FUNCTION_NAME, 1},
49890082Sobrien  {NULL, 0, 0},
49990082Sobrien};
50018334Speter
501132728Skanstatic int constant_fits_type_p (tree, tree);
502169699Skanstatic tree check_case_value (tree);
503169699Skanstatic bool check_case_bounds (tree, tree, tree *, tree *);
50490082Sobrien
505132728Skanstatic tree handle_packed_attribute (tree *, tree, tree, int, bool *);
506132728Skanstatic tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
507132728Skanstatic tree handle_common_attribute (tree *, tree, tree, int, bool *);
508132728Skanstatic tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
509132728Skanstatic tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
510132728Skanstatic tree handle_always_inline_attribute (tree *, tree, tree, int,
511132728Skan					    bool *);
512169699Skanstatic tree handle_gnu_inline_attribute (tree *, tree, tree, int,
513169699Skan					 bool *);
514169699Skanstatic tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
515132728Skanstatic tree handle_used_attribute (tree *, tree, tree, int, bool *);
516132728Skanstatic tree handle_unused_attribute (tree *, tree, tree, int, bool *);
517169699Skanstatic tree handle_externally_visible_attribute (tree *, tree, tree, int,
518169699Skan						 bool *);
519132728Skanstatic tree handle_const_attribute (tree *, tree, tree, int, bool *);
520132728Skanstatic tree handle_transparent_union_attribute (tree *, tree, tree,
521132728Skan						int, bool *);
522132728Skanstatic tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
523132728Skanstatic tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
524132728Skanstatic tree handle_mode_attribute (tree *, tree, tree, int, bool *);
525132728Skanstatic tree handle_section_attribute (tree *, tree, tree, int, bool *);
526132728Skanstatic tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
527132728Skanstatic tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
528132728Skanstatic tree handle_alias_attribute (tree *, tree, tree, int, bool *);
529169699Skanstatic tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
530132728Skanstatic tree handle_visibility_attribute (tree *, tree, tree, int,
531132728Skan					 bool *);
532132728Skanstatic tree handle_tls_model_attribute (tree *, tree, tree, int,
533132728Skan					bool *);
534132728Skanstatic tree handle_no_instrument_function_attribute (tree *, tree,
535132728Skan						     tree, int, bool *);
536132728Skanstatic tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
537169699Skanstatic tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
538132728Skanstatic tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
539132728Skan					     bool *);
540132728Skanstatic tree handle_pure_attribute (tree *, tree, tree, int, bool *);
541169699Skanstatic tree handle_novops_attribute (tree *, tree, tree, int, bool *);
542132728Skanstatic tree handle_deprecated_attribute (tree *, tree, tree, int,
543132728Skan					 bool *);
544260918Spfg/* APPLE LOCAL begin "unavailable" attribute (Radar 2809697) --ilr */
545260918Spfgstatic tree handle_unavailable_attribute (tree *, tree, tree, int,  bool *);
546260918Spfg/* APPLE LOCAL end "unavailable" attribute --ilr */
547132728Skanstatic tree handle_vector_size_attribute (tree *, tree, tree, int,
548132728Skan					  bool *);
549132728Skanstatic tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
550132728Skanstatic tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
551132728Skanstatic tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
552132728Skanstatic tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
553132728Skan						 bool *);
554169699Skanstatic tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
555261188Spfg/* APPLE LOCAL radar 5932809 - copyable byref blocks */
556261188Spfgstatic tree handle_blocks_attribute (tree *, tree, tree, int, bool *);
557117404Skan
558132728Skanstatic void check_function_nonnull (tree, tree);
559132728Skanstatic void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
560132728Skanstatic bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
561132728Skanstatic bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *);
562132728Skanstatic int resort_field_decl_cmp (const void *, const void *);
563117404Skan
564117404Skan/* Table of machine-independent attributes common to all C-like languages.  */
565117404Skanconst struct attribute_spec c_common_attribute_table[] =
566117404Skan{
567117404Skan  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
568117404Skan  { "packed",                 0, 0, false, false, false,
569132728Skan			      handle_packed_attribute },
570117404Skan  { "nocommon",               0, 0, true,  false, false,
571117404Skan			      handle_nocommon_attribute },
572117404Skan  { "common",                 0, 0, true,  false, false,
573117404Skan			      handle_common_attribute },
574117404Skan  /* FIXME: logically, noreturn attributes should be listed as
575117404Skan     "false, true, true" and apply to function types.  But implementing this
576117404Skan     would require all the places in the compiler that use TREE_THIS_VOLATILE
577117404Skan     on a decl to identify non-returning functions to be located and fixed
578117404Skan     to check the function type instead.  */
579117404Skan  { "noreturn",               0, 0, true,  false, false,
580117404Skan			      handle_noreturn_attribute },
581117404Skan  { "volatile",               0, 0, true,  false, false,
582117404Skan			      handle_noreturn_attribute },
583117404Skan  { "noinline",               0, 0, true,  false, false,
584117404Skan			      handle_noinline_attribute },
585117404Skan  { "always_inline",          0, 0, true,  false, false,
586117404Skan			      handle_always_inline_attribute },
587169699Skan  { "gnu_inline",             0, 0, true,  false, false,
588169699Skan			      handle_gnu_inline_attribute },
589169699Skan  { "flatten",                0, 0, true,  false, false,
590169699Skan			      handle_flatten_attribute },
591117404Skan  { "used",                   0, 0, true,  false, false,
592117404Skan			      handle_used_attribute },
593117404Skan  { "unused",                 0, 0, false, false, false,
594117404Skan			      handle_unused_attribute },
595169699Skan  { "externally_visible",     0, 0, true,  false, false,
596169699Skan			      handle_externally_visible_attribute },
597117404Skan  /* The same comments as for noreturn attributes apply to const ones.  */
598117404Skan  { "const",                  0, 0, true,  false, false,
599117404Skan			      handle_const_attribute },
600117404Skan  { "transparent_union",      0, 0, false, false, false,
601117404Skan			      handle_transparent_union_attribute },
602117404Skan  { "constructor",            0, 0, true,  false, false,
603117404Skan			      handle_constructor_attribute },
604117404Skan  { "destructor",             0, 0, true,  false, false,
605117404Skan			      handle_destructor_attribute },
606117404Skan  { "mode",                   1, 1, false,  true, false,
607117404Skan			      handle_mode_attribute },
608117404Skan  { "section",                1, 1, true,  false, false,
609117404Skan			      handle_section_attribute },
610117404Skan  { "aligned",                0, 1, false, false, false,
611117404Skan			      handle_aligned_attribute },
612261188Spfg  /* APPLE LOCAL weak types 5954418 */
613261188Spfg  { "weak",                   0, 0, false, false, false,
614117404Skan			      handle_weak_attribute },
615117404Skan  { "alias",                  1, 1, true,  false, false,
616117404Skan			      handle_alias_attribute },
617169699Skan  { "weakref",                0, 1, true,  false, false,
618169699Skan			      handle_weakref_attribute },
619117404Skan  { "no_instrument_function", 0, 0, true,  false, false,
620117404Skan			      handle_no_instrument_function_attribute },
621117404Skan  { "malloc",                 0, 0, true,  false, false,
622117404Skan			      handle_malloc_attribute },
623169699Skan  { "returns_twice",          0, 0, true,  false, false,
624169699Skan			      handle_returns_twice_attribute },
625117404Skan  { "no_stack_limit",         0, 0, true,  false, false,
626117404Skan			      handle_no_limit_stack_attribute },
627117404Skan  { "pure",                   0, 0, true,  false, false,
628117404Skan			      handle_pure_attribute },
629169699Skan  /* For internal use (marking of builtins) only.  The name contains space
630169699Skan     to prevent its usage in source code.  */
631169699Skan  { "no vops",                0, 0, true,  false, false,
632169699Skan			      handle_novops_attribute },
633117404Skan  { "deprecated",             0, 0, false, false, false,
634117404Skan			      handle_deprecated_attribute },
635260918Spfg  /* APPLE LOCAL begin "unavailable" attribute (Radar 2809697) --ilr */
636260918Spfg  { "unavailable",            0, 0, false, false, false,
637260918Spfg			      handle_unavailable_attribute },
638260918Spfg  /* APPLE LOCAL end "unavailable" attribute --ilr */
639117404Skan  { "vector_size",	      1, 1, false, true, false,
640117404Skan			      handle_vector_size_attribute },
641169699Skan  { "visibility",	      1, 1, false, false, false,
642117404Skan			      handle_visibility_attribute },
643117404Skan  { "tls_model",	      1, 1, true,  false, false,
644117404Skan			      handle_tls_model_attribute },
645117404Skan  { "nonnull",                0, -1, false, true, true,
646117404Skan			      handle_nonnull_attribute },
647117404Skan  { "nothrow",                0, 0, true,  false, false,
648117404Skan			      handle_nothrow_attribute },
649117404Skan  { "may_alias",	      0, 0, false, true, false, NULL },
650117404Skan  { "cleanup",		      1, 1, true, false, false,
651117404Skan			      handle_cleanup_attribute },
652132728Skan  { "warn_unused_result",     0, 0, false, true, true,
653132728Skan			      handle_warn_unused_result_attribute },
654169699Skan  { "sentinel",               0, 1, false, true, true,
655169699Skan			      handle_sentinel_attribute },
656261188Spfg  /* APPLE LOCAL radar 5932809 - copyable byref blocks */
657261188Spfg  { "blocks", 1, 1, true, false, false, handle_blocks_attribute },
658117404Skan  { NULL,                     0, 0, false, false, false, NULL }
659117404Skan};
660117404Skan
661117404Skan/* Give the specifications for the format attributes, used by C and all
662132728Skan   descendants.  */
663117404Skan
664117404Skanconst struct attribute_spec c_common_format_attribute_table[] =
665117404Skan{
666117404Skan  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
667117404Skan  { "format",                 3, 3, false, true,  true,
668117404Skan			      handle_format_attribute },
669117404Skan  { "format_arg",             1, 1, false, true,  true,
670117404Skan			      handle_format_arg_attribute },
671117404Skan  { NULL,                     0, 0, false, false, false, NULL }
672117404Skan};
673117404Skan
67490082Sobrien/* Push current bindings for the function name VAR_DECLS.  */
67590082Sobrien
67690082Sobrienvoid
677132728Skanstart_fname_decls (void)
67890082Sobrien{
67990082Sobrien  unsigned ix;
68090082Sobrien  tree saved = NULL_TREE;
681132728Skan
68290082Sobrien  for (ix = 0; fname_vars[ix].decl; ix++)
68318334Speter    {
68490082Sobrien      tree decl = *fname_vars[ix].decl;
68590082Sobrien
68690082Sobrien      if (decl)
68790082Sobrien	{
688169699Skan	  saved = tree_cons (decl, build_int_cst (NULL_TREE, ix), saved);
68990082Sobrien	  *fname_vars[ix].decl = NULL_TREE;
69090082Sobrien	}
69118334Speter    }
69290082Sobrien  if (saved || saved_function_name_decls)
69390082Sobrien    /* Normally they'll have been NULL, so only push if we've got a
69490082Sobrien       stack, or they are non-NULL.  */
69590082Sobrien    saved_function_name_decls = tree_cons (saved, NULL_TREE,
69690082Sobrien					   saved_function_name_decls);
69790082Sobrien}
69890082Sobrien
699169699Skan/* Finish up the current bindings, adding them into the current function's
700169699Skan   statement tree.  This must be done _before_ finish_stmt_tree is called.
701169699Skan   If there is no current function, we must be at file scope and no statements
702169699Skan   are involved. Pop the previous bindings.  */
70390082Sobrien
70490082Sobrienvoid
705132728Skanfinish_fname_decls (void)
70690082Sobrien{
70790082Sobrien  unsigned ix;
708169699Skan  tree stmts = NULL_TREE;
70990082Sobrien  tree stack = saved_function_name_decls;
71090082Sobrien
71190082Sobrien  for (; stack && TREE_VALUE (stack); stack = TREE_CHAIN (stack))
712169699Skan    append_to_statement_list (TREE_VALUE (stack), &stmts);
713132728Skan
714169699Skan  if (stmts)
71518334Speter    {
716169699Skan      tree *bodyp = &DECL_SAVED_TREE (current_function_decl);
717132728Skan
718169699Skan      if (TREE_CODE (*bodyp) == BIND_EXPR)
719169699Skan	bodyp = &BIND_EXPR_BODY (*bodyp);
720132728Skan
721169699Skan      append_to_statement_list_force (*bodyp, &stmts);
722169699Skan      *bodyp = stmts;
72318334Speter    }
724132728Skan
72590082Sobrien  for (ix = 0; fname_vars[ix].decl; ix++)
72690082Sobrien    *fname_vars[ix].decl = NULL_TREE;
727132728Skan
72890082Sobrien  if (stack)
72990082Sobrien    {
73090082Sobrien      /* We had saved values, restore them.  */
73190082Sobrien      tree saved;
73218334Speter
73390082Sobrien      for (saved = TREE_PURPOSE (stack); saved; saved = TREE_CHAIN (saved))
73490082Sobrien	{
73590082Sobrien	  tree decl = TREE_PURPOSE (saved);
73690082Sobrien	  unsigned ix = TREE_INT_CST_LOW (TREE_VALUE (saved));
737132728Skan
73890082Sobrien	  *fname_vars[ix].decl = decl;
73990082Sobrien	}
74090082Sobrien      stack = TREE_CHAIN (stack);
74190082Sobrien    }
74290082Sobrien  saved_function_name_decls = stack;
74318334Speter}
74418334Speter
745132728Skan/* Return the text name of the current function, suitably prettified
746169699Skan   by PRETTY_P.  Return string must be freed by caller.  */
74790082Sobrien
74890082Sobrienconst char *
749132728Skanfname_as_string (int pretty_p)
75018334Speter{
751132728Skan  const char *name = "top level";
752169699Skan  char *namep;
753132728Skan  int vrb = 2;
75418334Speter
755169699Skan  if (!pretty_p)
756132728Skan    {
757132728Skan      name = "";
758132728Skan      vrb = 0;
759132728Skan    }
76090082Sobrien
761132728Skan  if (current_function_decl)
762169699Skan    name = lang_hooks.decl_printable_name (current_function_decl, vrb);
763132728Skan
764169699Skan  if (c_lex_string_translate)
765169699Skan    {
766169699Skan      int len = strlen (name) + 3; /* Two for '"'s.  One for NULL.  */
767169699Skan      cpp_string cstr = { 0, 0 }, strname;
768169699Skan
769169699Skan      namep = XNEWVEC (char, len);
770169699Skan      snprintf (namep, len, "\"%s\"", name);
771169699Skan      strname.text = (unsigned char *) namep;
772169699Skan      strname.len = len - 1;
773169699Skan
774169699Skan      if (cpp_interpret_string (parse_in, &strname, 1, &cstr, false))
775169699Skan	{
776169699Skan	  XDELETEVEC (namep);
777169699Skan	  return (char *) cstr.text;
778169699Skan	}
779169699Skan    }
780169699Skan  else
781169699Skan    namep = xstrdup (name);
782169699Skan
783169699Skan  return namep;
78418334Speter}
78518334Speter
786169699Skan/* Expand DECL if it declares an entity not handled by the
787169699Skan   common code.  */
788169699Skan
789169699Skanint
790169699Skanc_expand_decl (tree decl)
791169699Skan{
792169699Skan  if (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl))
793169699Skan    {
794169699Skan      /* Let the back-end know about this variable.  */
795169699Skan      if (!anon_aggr_type_p (TREE_TYPE (decl)))
796169699Skan	emit_local_var (decl);
797169699Skan      else
798169699Skan	expand_anon_union_decl (decl, NULL_TREE,
799169699Skan				DECL_ANON_UNION_ELEMS (decl));
800169699Skan    }
801169699Skan  else
802169699Skan    return 0;
803169699Skan
804169699Skan  return 1;
805169699Skan}
806169699Skan
807169699Skan
80890082Sobrien/* Return the VAR_DECL for a const char array naming the current
80990082Sobrien   function. If the VAR_DECL has not yet been created, create it
81090082Sobrien   now. RID indicates how it should be formatted and IDENTIFIER_NODE
81190082Sobrien   ID is its name (unfortunately C and C++ hold the RID values of
81290082Sobrien   keywords in different places, so we can't derive RID from ID in
81390082Sobrien   this language independent code.  */
81490082Sobrien
81590082Sobrientree
816132728Skanfname_decl (unsigned int rid, tree id)
81790082Sobrien{
81890082Sobrien  unsigned ix;
81990082Sobrien  tree decl = NULL_TREE;
82090082Sobrien
82190082Sobrien  for (ix = 0; fname_vars[ix].decl; ix++)
82290082Sobrien    if (fname_vars[ix].rid == rid)
82390082Sobrien      break;
82490082Sobrien
82590082Sobrien  decl = *fname_vars[ix].decl;
82690082Sobrien  if (!decl)
82790082Sobrien    {
828117404Skan      /* If a tree is built here, it would normally have the lineno of
829117404Skan	 the current statement.  Later this tree will be moved to the
830117404Skan	 beginning of the function and this line number will be wrong.
831117404Skan	 To avoid this problem set the lineno to 0 here; that prevents
832117404Skan	 it from appearing in the RTL.  */
833169699Skan      tree stmts;
834169699Skan      location_t saved_location = input_location;
835169699Skan#ifdef USE_MAPPED_LOCATION
836169699Skan      input_location = UNKNOWN_LOCATION;
837169699Skan#else
838132728Skan      input_line = 0;
839169699Skan#endif
840132728Skan
841169699Skan      stmts = push_stmt_list ();
84290082Sobrien      decl = (*make_fname_decl) (id, fname_vars[ix].pretty);
843169699Skan      stmts = pop_stmt_list (stmts);
844169699Skan      if (!IS_EMPTY_STMT (stmts))
845169699Skan	saved_function_name_decls
846169699Skan	  = tree_cons (decl, stmts, saved_function_name_decls);
84790082Sobrien      *fname_vars[ix].decl = decl;
848169699Skan      input_location = saved_location;
84990082Sobrien    }
85090082Sobrien  if (!ix && !current_function_decl)
851169699Skan    pedwarn ("%qD is not defined outside of function scope", decl);
852132728Skan
85390082Sobrien  return decl;
85490082Sobrien}
85590082Sobrien
856117404Skan/* Given a STRING_CST, give it a suitable array-of-chars data type.  */
85718334Speter
85818334Spetertree
859132728Skanfix_string_type (tree value)
860117404Skan{
861117404Skan  const int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
862117404Skan  const int wide_flag = TREE_TYPE (value) == wchar_array_type_node;
863117404Skan  int length = TREE_STRING_LENGTH (value);
864117404Skan  int nchars;
865169699Skan  tree e_type, i_type, a_type;
866117404Skan
867117404Skan  /* Compute the number of elements, for the array type.  */
868117404Skan  nchars = wide_flag ? length / wchar_bytes : length;
869117404Skan
870169699Skan  /* C89 2.2.4.1, C99 5.2.4.1 (Translation limits).  The analogous
871169699Skan     limit in C++98 Annex B is very large (65536) and is not normative,
872169699Skan     so we do not diagnose it (warn_overlength_strings is forced off
873169699Skan     in c_common_post_options).  */
874169699Skan  if (warn_overlength_strings)
875117404Skan    {
876169699Skan      const int nchars_max = flag_isoc99 ? 4095 : 509;
877169699Skan      const int relevant_std = flag_isoc99 ? 99 : 90;
878169699Skan      if (nchars - 1 > nchars_max)
879169699Skan	/* Translators: The %d after 'ISO C' will be 90 or 99.  Do not
880169699Skan	   separate the %d from the 'C'.  'ISO' should not be
881169699Skan	   translated, but it may be moved after 'C%d' in languages
882169699Skan	   where modifiers follow nouns.  */
883169699Skan	pedwarn ("string length %qd is greater than the length %qd "
884169699Skan		 "ISO C%d compilers are required to support",
885169699Skan		 nchars - 1, nchars_max, relevant_std);
886117404Skan    }
887117404Skan
888169699Skan  /* Create the array type for the string constant.  The ISO C++
889169699Skan     standard says that a string literal has type `const char[N]' or
890169699Skan     `const wchar_t[N]'.  We use the same logic when invoked as a C
891169699Skan     front-end with -Wwrite-strings.
892169699Skan     ??? We should change the type of an expression depending on the
893169699Skan     state of a warning flag.  We should just be warning -- see how
894169699Skan     this is handled in the C++ front-end for the deprecated implicit
895169699Skan     conversion from string literals to `char*' or `wchar_t*'.
896169699Skan
897169699Skan     The C++ front end relies on TYPE_MAIN_VARIANT of a cv-qualified
898169699Skan     array type being the unqualified version of that type.
899169699Skan     Therefore, if we are constructing an array of const char, we must
900169699Skan     construct the matching unqualified array type first.  The C front
901169699Skan     end does not require this, but it does no harm, so we do it
902169699Skan     unconditionally.  */
903169699Skan  e_type = wide_flag ? wchar_type_node : char_type_node;
904169699Skan  i_type = build_index_type (build_int_cst (NULL_TREE, nchars - 1));
905169699Skan  a_type = build_array_type (e_type, i_type);
906169699Skan  if (c_dialect_cxx() || warn_write_strings)
907169699Skan    a_type = c_build_qualified_type (a_type, TYPE_QUAL_CONST);
908169699Skan
909169699Skan  TREE_TYPE (value) = a_type;
910117404Skan  TREE_CONSTANT (value) = 1;
911169699Skan  TREE_INVARIANT (value) = 1;
912169699Skan  TREE_READONLY (value) = 1;
913117404Skan  TREE_STATIC (value) = 1;
914117404Skan  return value;
915117404Skan}
91618334Speter
91790082Sobrien/* Print a warning if a constant expression had overflow in folding.
91890082Sobrien   Invoke this function on every expression that the language
91990082Sobrien   requires to be a constant expression.
92090082Sobrien   Note the ANSI C standard says it is erroneous for a
92190082Sobrien   constant expression to overflow.  */
92252299Sobrien
92390082Sobrienvoid
924132728Skanconstant_expression_warning (tree value)
92552299Sobrien{
92690082Sobrien  if ((TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
92796275Sobrien       || TREE_CODE (value) == VECTOR_CST
92890082Sobrien       || TREE_CODE (value) == COMPLEX_CST)
929169699Skan      && TREE_CONSTANT_OVERFLOW (value)
930169699Skan      && warn_overflow
931169699Skan      && pedantic)
93290082Sobrien    pedwarn ("overflow in constant expression");
93352299Sobrien}
93452299Sobrien
935259584Spfg/* Print a warning if an expression had overflow in folding and its
936259584Spfg   operands hadn't.
937259584Spfg
93890082Sobrien   Invoke this function on every expression that
93990082Sobrien   (1) appears in the source code, and
940259584Spfg   (2) is a constant expression that overflowed, and
94190082Sobrien   (3) is not already checked by convert_and_check;
942259584Spfg   however, do not invoke this function on operands of explicit casts
943259584Spfg   or when the expression is the result of an operator and any operand
944259584Spfg   already overflowed.  */
94552299Sobrien
94618334Spetervoid
947132728Skanoverflow_warning (tree value)
94818334Speter{
949259584Spfg  if (skip_evaluation) return;
950259584Spfg
951259584Spfg  switch (TREE_CODE (value))
95218334Speter    {
953259584Spfg    case INTEGER_CST:
954259584Spfg      warning (OPT_Woverflow, "integer overflow in expression");
955259584Spfg      break;
956259584Spfg
957259584Spfg    case REAL_CST:
958259584Spfg      warning (OPT_Woverflow, "floating point overflow in expression");
959259584Spfg      break;
960259584Spfg
961259584Spfg    case VECTOR_CST:
962259584Spfg      warning (OPT_Woverflow, "vector overflow in expression");
963259584Spfg      break;
964259584Spfg
965259584Spfg    case COMPLEX_CST:
966259584Spfg      if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST)
967259584Spfg	warning (OPT_Woverflow, "complex integer overflow in expression");
968259584Spfg      else if (TREE_CODE (TREE_REALPART (value)) == REAL_CST)
969259584Spfg	warning (OPT_Woverflow, "complex floating point overflow in expression");
970259584Spfg      break;
971259584Spfg
972259584Spfg    default:
973259584Spfg      break;
97418334Speter    }
97518334Speter}
97650449Sobrien
97790082Sobrien/* Print a warning if a large constant is truncated to unsigned,
97890082Sobrien   or if -Wconversion is used and a constant < 0 is converted to unsigned.
97990082Sobrien   Invoke this function on every expression that might be implicitly
98090082Sobrien   converted to an unsigned type.  */
98150449Sobrien
982169699Skanstatic void
983132728Skanunsigned_conversion_warning (tree result, tree operand)
98450449Sobrien{
985117404Skan  tree type = TREE_TYPE (result);
986117404Skan
98790082Sobrien  if (TREE_CODE (operand) == INTEGER_CST
988117404Skan      && TREE_CODE (type) == INTEGER_TYPE
989169699Skan      && TYPE_UNSIGNED (type)
99090082Sobrien      && skip_evaluation == 0
991117404Skan      && !int_fits_type_p (operand, type))
99250449Sobrien    {
993117404Skan      if (!int_fits_type_p (operand, c_common_signed_type (type)))
99490082Sobrien	/* This detects cases like converting -129 or 256 to unsigned char.  */
995169699Skan	warning (OPT_Woverflow,
996169699Skan		 "large integer implicitly truncated to unsigned type");
997169699Skan      else
998169699Skan	warning (OPT_Wconversion,
999169699Skan		 "negative integer implicitly converted to unsigned type");
100050449Sobrien    }
100190082Sobrien}
100250449Sobrien
1003169699Skan/* Print a warning about casts that might indicate violation
1004169699Skan   of strict aliasing rules if -Wstrict-aliasing is used and
1005169699Skan   strict aliasing mode is in effect. OTYPE is the original
1006169699Skan   TREE_TYPE of EXPR, and TYPE the type we're casting to. */
1007169699Skan
1008259405Spfgbool
1009169699Skanstrict_aliasing_warning (tree otype, tree type, tree expr)
1010169699Skan{
1011259405Spfg  if (!(flag_strict_aliasing && POINTER_TYPE_P (type)
1012259405Spfg        && POINTER_TYPE_P (otype) && !VOID_TYPE_P (TREE_TYPE (type))))
1013259405Spfg    return false;
1014259405Spfg
1015259405Spfg  if ((warn_strict_aliasing > 1) && TREE_CODE (expr) == ADDR_EXPR
1016169699Skan      && (DECL_P (TREE_OPERAND (expr, 0))
1017259405Spfg          || handled_component_p (TREE_OPERAND (expr, 0))))
1018169699Skan    {
1019169699Skan      /* Casting the address of an object to non void pointer. Warn
1020169699Skan         if the cast breaks type based aliasing.  */
1021259405Spfg      if (!COMPLETE_TYPE_P (TREE_TYPE (type)) && warn_strict_aliasing == 2)
1022259405Spfg	{
1023259405Spfg	  warning (OPT_Wstrict_aliasing, "type-punning to incomplete type "
1024259405Spfg		   "might break strict-aliasing rules");
1025259405Spfg	  return true;
1026259405Spfg	}
1027169699Skan      else
1028169699Skan        {
1029259405Spfg          /* warn_strict_aliasing >= 3.   This includes the default (3).
1030259405Spfg             Only warn if the cast is dereferenced immediately.  */
1031259405Spfg          HOST_WIDE_INT set1 =
1032259405Spfg	    get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
1033169699Skan          HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type));
1034169699Skan
1035169699Skan          if (!alias_sets_conflict_p (set1, set2))
1036259405Spfg	    {
1037259405Spfg	      warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
1038259405Spfg		       "pointer will break strict-aliasing rules");
1039259405Spfg	      return true;
1040259405Spfg	    }
1041259405Spfg          else if (warn_strict_aliasing == 2
1042259405Spfg		   && !alias_sets_might_conflict_p (set1, set2))
1043259405Spfg	    {
1044259405Spfg	      warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
1045259405Spfg		       "pointer might break strict-aliasing rules");
1046259405Spfg	      return true;
1047259405Spfg	    }
1048259405Spfg        }
1049259405Spfg    }
1050259405Spfg  else
1051259405Spfg    if ((warn_strict_aliasing == 1) && !VOID_TYPE_P (TREE_TYPE (otype)))
1052259405Spfg      {
1053259405Spfg        /* At this level, warn for any conversions, even if an address is
1054259405Spfg           not taken in the same statement.  This will likely produce many
1055259405Spfg           false positives, but could be useful to pinpoint problems that
1056259405Spfg           are not revealed at higher levels.  */
1057259405Spfg        HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (otype));
1058259405Spfg        HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type));
1059259405Spfg        if (!COMPLETE_TYPE_P(type)
1060259405Spfg            || !alias_sets_might_conflict_p (set1, set2))
1061259405Spfg	  {
1062169699Skan            warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
1063169699Skan                     "pointer might break strict-aliasing rules");
1064259405Spfg            return true;
1065259405Spfg          }
1066259405Spfg      }
1067259405Spfg
1068259405Spfg  return false;
1069169699Skan}
1070169699Skan
1071169699Skan
1072169699Skan/* Print a warning about if (); or if () .. else; constructs
1073169699Skan   via the special empty statement node that we create.  INNER_THEN
1074169699Skan   and INNER_ELSE are the statement lists of the if and the else
1075169699Skan   block.  */
1076169699Skan
1077169699Skanvoid
1078169699Skanempty_body_warning (tree inner_then, tree inner_else)
1079169699Skan{
1080169699Skan  if (extra_warnings)
1081169699Skan    {
1082169699Skan      if (TREE_CODE (inner_then) == STATEMENT_LIST
1083169699Skan	  && STATEMENT_LIST_TAIL (inner_then))
1084169699Skan	inner_then = STATEMENT_LIST_TAIL (inner_then)->stmt;
1085169699Skan
1086169699Skan      if (inner_else && TREE_CODE (inner_else) == STATEMENT_LIST
1087169699Skan	  && STATEMENT_LIST_TAIL (inner_else))
1088169699Skan	inner_else = STATEMENT_LIST_TAIL (inner_else)->stmt;
1089169699Skan
1090169699Skan      if (IS_EMPTY_STMT (inner_then) && !inner_else)
1091169699Skan	warning (OPT_Wextra, "%Hempty body in an if-statement",
1092169699Skan		 EXPR_LOCUS (inner_then));
1093169699Skan
1094169699Skan      if (inner_else && IS_EMPTY_STMT (inner_else))
1095169699Skan	warning (OPT_Wextra, "%Hempty body in an else-statement",
1096169699Skan		 EXPR_LOCUS (inner_else));
1097169699Skan   }
1098169699Skan}
1099169699Skan
1100169699Skan
110190082Sobrien/* Nonzero if constant C has a value that is permissible
110290082Sobrien   for type TYPE (an INTEGER_TYPE).  */
110350449Sobrien
110490082Sobrienstatic int
1105132728Skanconstant_fits_type_p (tree c, tree type)
110690082Sobrien{
110790082Sobrien  if (TREE_CODE (c) == INTEGER_CST)
110890082Sobrien    return int_fits_type_p (c, type);
110950449Sobrien
111090082Sobrien  c = convert (type, c);
111190082Sobrien  return !TREE_OVERFLOW (c);
1112132728Skan}
111350449Sobrien
1114260074Spfg
1115260074Spfg/* True if vector types T1 and T2 can be converted to each other
1116260074Spfg   without an explicit cast.  If EMIT_LAX_NOTE is true, and T1 and T2
1117260074Spfg   can only be converted with -flax-vector-conversions yet that is not
1118260074Spfg   in effect, emit a note telling the user about that option if such
1119260074Spfg   a note has not previously been emitted.  */
1120260074Spfgbool
1121260074Spfgvector_types_convertible_p (tree t1, tree t2, bool emit_lax_note)
1122161660Skan{
1123260074Spfg  static bool emitted_lax_note = false;
1124260074Spfg  bool convertible_lax;
1125260074Spfg
1126260074Spfg  if ((targetm.vector_opaque_p (t1) || targetm.vector_opaque_p (t2))
1127260074Spfg      && tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2)))
1128260074Spfg    return true;
1129260074Spfg
1130260074Spfg  convertible_lax =
1131260074Spfg    (tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))
1132260074Spfg     && (TREE_CODE (TREE_TYPE (t1)) != REAL_TYPE ||
1133260074Spfg	 TYPE_PRECISION (t1) == TYPE_PRECISION (t2))
1134260074Spfg     && (INTEGRAL_TYPE_P (TREE_TYPE (t1))
1135260074Spfg	 == INTEGRAL_TYPE_P (TREE_TYPE (t2))));
1136260074Spfg
1137260074Spfg  if (!convertible_lax || flag_lax_vector_conversions)
1138260074Spfg    return convertible_lax;
1139260074Spfg
1140260074Spfg  if (TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
1141260074Spfg      && comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))
1142260074Spfg    return true;
1143260074Spfg
1144260074Spfg  if (emit_lax_note && !emitted_lax_note)
1145260074Spfg    {
1146260074Spfg      emitted_lax_note = true;
1147260074Spfg      inform ("use -flax-vector-conversions to permit "
1148260074Spfg              "conversions between vectors with differing "
1149260074Spfg              "element types or numbers of subparts");
1150260074Spfg    }
1151260074Spfg
1152260074Spfg  return false;
1153161660Skan}
1154161660Skan
115590082Sobrien/* Convert EXPR to TYPE, warning about conversion problems with constants.
115690082Sobrien   Invoke this function on every expression that is converted implicitly,
115790082Sobrien   i.e. because of language rules and not because of an explicit cast.  */
115850449Sobrien
115950449Sobrientree
1160132728Skanconvert_and_check (tree type, tree expr)
116150449Sobrien{
116290082Sobrien  tree t = convert (type, expr);
116390082Sobrien  if (TREE_CODE (t) == INTEGER_CST)
116490082Sobrien    {
116590082Sobrien      if (TREE_OVERFLOW (t))
116690082Sobrien	{
116790082Sobrien	  TREE_OVERFLOW (t) = 0;
116850449Sobrien
116990082Sobrien	  /* Do not diagnose overflow in a constant expression merely
117090082Sobrien	     because a conversion overflowed.  */
1171169699Skan	  TREE_CONSTANT_OVERFLOW (t) = CONSTANT_CLASS_P (expr)
1172169699Skan                                       && TREE_CONSTANT_OVERFLOW (expr);
117350449Sobrien
117490082Sobrien	  /* No warning for converting 0x80000000 to int.  */
1175169699Skan	  if (!(TYPE_UNSIGNED (type) < TYPE_UNSIGNED (TREE_TYPE (expr))
117690082Sobrien		&& TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
117790082Sobrien		&& TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (expr))))
117890082Sobrien	    /* If EXPR fits in the unsigned version of TYPE,
117990082Sobrien	       don't warn unless pedantic.  */
118090082Sobrien	    if ((pedantic
1181169699Skan		 || TYPE_UNSIGNED (type)
1182169699Skan		 || !constant_fits_type_p (expr,
1183169699Skan					   c_common_unsigned_type (type)))
1184169699Skan		&& skip_evaluation == 0)
1185169699Skan	      warning (OPT_Woverflow,
1186169699Skan                       "overflow in implicit constant conversion");
118790082Sobrien	}
118890082Sobrien      else
118990082Sobrien	unsigned_conversion_warning (t, expr);
119050449Sobrien    }
119190082Sobrien  return t;
119250449Sobrien}
119318334Speter
119490082Sobrien/* A node in a list that describes references to variables (EXPR), which are
119590082Sobrien   either read accesses if WRITER is zero, or write accesses, in which case
119690082Sobrien   WRITER is the parent of EXPR.  */
119790082Sobrienstruct tlist
119890082Sobrien{
119990082Sobrien  struct tlist *next;
120090082Sobrien  tree expr, writer;
120118334Speter};
120218334Speter
120390082Sobrien/* Used to implement a cache the results of a call to verify_tree.  We only
120490082Sobrien   use this for SAVE_EXPRs.  */
120590082Sobrienstruct tlist_cache
120690082Sobrien{
120790082Sobrien  struct tlist_cache *next;
120890082Sobrien  struct tlist *cache_before_sp;
120990082Sobrien  struct tlist *cache_after_sp;
121090082Sobrien  tree expr;
121118334Speter};
121218334Speter
121390082Sobrien/* Obstack to use when allocating tlist structures, and corresponding
121490082Sobrien   firstobj.  */
121590082Sobrienstatic struct obstack tlist_obstack;
121690082Sobrienstatic char *tlist_firstobj = 0;
121750449Sobrien
121890082Sobrien/* Keep track of the identifiers we've warned about, so we can avoid duplicate
121990082Sobrien   warnings.  */
122090082Sobrienstatic struct tlist *warned_ids;
122190082Sobrien/* SAVE_EXPRs need special treatment.  We process them only once and then
122290082Sobrien   cache the results.  */
122390082Sobrienstatic struct tlist_cache *save_expr_cache;
122450449Sobrien
1225132728Skanstatic void add_tlist (struct tlist **, struct tlist *, tree, int);
1226132728Skanstatic void merge_tlist (struct tlist **, struct tlist *, int);
1227132728Skanstatic void verify_tree (tree, struct tlist **, struct tlist **, tree);
1228132728Skanstatic int warning_candidate_p (tree);
1229132728Skanstatic void warn_for_collisions (struct tlist *);
1230132728Skanstatic void warn_for_collisions_1 (tree, tree, struct tlist *, int);
1231132728Skanstatic struct tlist *new_tlist (struct tlist *, tree, tree);
123218334Speter
123390082Sobrien/* Create a new struct tlist and fill in its fields.  */
123490082Sobrienstatic struct tlist *
1235132728Skannew_tlist (struct tlist *next, tree t, tree writer)
123650449Sobrien{
123790082Sobrien  struct tlist *l;
1238169699Skan  l = XOBNEW (&tlist_obstack, struct tlist);
123990082Sobrien  l->next = next;
124090082Sobrien  l->expr = t;
124190082Sobrien  l->writer = writer;
124290082Sobrien  return l;
124318334Speter}
124418334Speter
124590082Sobrien/* Add duplicates of the nodes found in ADD to the list *TO.  If EXCLUDE_WRITER
124690082Sobrien   is nonnull, we ignore any node we find which has a writer equal to it.  */
124718334Speter
124850449Sobrienstatic void
1249132728Skanadd_tlist (struct tlist **to, struct tlist *add, tree exclude_writer, int copy)
125018334Speter{
125190082Sobrien  while (add)
125218334Speter    {
125390082Sobrien      struct tlist *next = add->next;
1254169699Skan      if (!copy)
125590082Sobrien	add->next = *to;
1256169699Skan      if (!exclude_writer || add->writer != exclude_writer)
125790082Sobrien	*to = copy ? new_tlist (*to, add->expr, add->writer) : add;
125890082Sobrien      add = next;
125918334Speter    }
126018334Speter}
126118334Speter
126290082Sobrien/* Merge the nodes of ADD into TO.  This merging process is done so that for
126390082Sobrien   each variable that already exists in TO, no new node is added; however if
126490082Sobrien   there is a write access recorded in ADD, and an occurrence on TO is only
126590082Sobrien   a read access, then the occurrence in TO will be modified to record the
126690082Sobrien   write.  */
126750449Sobrien
126850449Sobrienstatic void
1269132728Skanmerge_tlist (struct tlist **to, struct tlist *add, int copy)
127050449Sobrien{
127190082Sobrien  struct tlist **end = to;
127250449Sobrien
127390082Sobrien  while (*end)
127490082Sobrien    end = &(*end)->next;
127550449Sobrien
127690082Sobrien  while (add)
127750449Sobrien    {
127890082Sobrien      int found = 0;
127990082Sobrien      struct tlist *tmp2;
128090082Sobrien      struct tlist *next = add->next;
128150449Sobrien
128290082Sobrien      for (tmp2 = *to; tmp2; tmp2 = tmp2->next)
128390082Sobrien	if (tmp2->expr == add->expr)
128490082Sobrien	  {
128590082Sobrien	    found = 1;
1286169699Skan	    if (!tmp2->writer)
128790082Sobrien	      tmp2->writer = add->writer;
128890082Sobrien	  }
1289169699Skan      if (!found)
129090082Sobrien	{
129190082Sobrien	  *end = copy ? add : new_tlist (NULL, add->expr, add->writer);
129290082Sobrien	  end = &(*end)->next;
129390082Sobrien	  *end = 0;
129490082Sobrien	}
129590082Sobrien      add = next;
129650449Sobrien    }
129750449Sobrien}
129850449Sobrien
129990082Sobrien/* WRITTEN is a variable, WRITER is its parent.  Warn if any of the variable
130090082Sobrien   references in list LIST conflict with it, excluding reads if ONLY writers
130190082Sobrien   is nonzero.  */
130290082Sobrien
130352299Sobrienstatic void
1304132728Skanwarn_for_collisions_1 (tree written, tree writer, struct tlist *list,
1305132728Skan		       int only_writes)
130652299Sobrien{
130790082Sobrien  struct tlist *tmp;
130818334Speter
130990082Sobrien  /* Avoid duplicate warnings.  */
131090082Sobrien  for (tmp = warned_ids; tmp; tmp = tmp->next)
131190082Sobrien    if (tmp->expr == written)
131290082Sobrien      return;
131318334Speter
131490082Sobrien  while (list)
131518334Speter    {
131690082Sobrien      if (list->expr == written
131790082Sobrien	  && list->writer != writer
1318169699Skan	  && (!only_writes || list->writer)
1319169699Skan	  && DECL_NAME (list->expr))
132018334Speter	{
132190082Sobrien	  warned_ids = new_tlist (warned_ids, written, NULL_TREE);
1322169699Skan	  warning (0, "operation on %qE may be undefined", list->expr);
132318334Speter	}
132490082Sobrien      list = list->next;
132518334Speter    }
132618334Speter}
132718334Speter
132890082Sobrien/* Given a list LIST of references to variables, find whether any of these
132990082Sobrien   can cause conflicts due to missing sequence points.  */
133018334Speter
133118334Speterstatic void
1332132728Skanwarn_for_collisions (struct tlist *list)
133318334Speter{
133490082Sobrien  struct tlist *tmp;
1335132728Skan
133690082Sobrien  for (tmp = list; tmp; tmp = tmp->next)
133718334Speter    {
133890082Sobrien      if (tmp->writer)
133990082Sobrien	warn_for_collisions_1 (tmp->expr, tmp->writer, list, 0);
134018334Speter    }
134190082Sobrien}
134250449Sobrien
134390082Sobrien/* Return nonzero if X is a tree that can be verified by the sequence point
134490082Sobrien   warnings.  */
134590082Sobrienstatic int
1346132728Skanwarning_candidate_p (tree x)
134790082Sobrien{
134890082Sobrien  return TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == PARM_DECL;
134990082Sobrien}
135050449Sobrien
135190082Sobrien/* Walk the tree X, and record accesses to variables.  If X is written by the
135290082Sobrien   parent tree, WRITER is the parent.
135390082Sobrien   We store accesses in one of the two lists: PBEFORE_SP, and PNO_SP.  If this
135490082Sobrien   expression or its only operand forces a sequence point, then everything up
135590082Sobrien   to the sequence point is stored in PBEFORE_SP.  Everything else gets stored
135690082Sobrien   in PNO_SP.
135790082Sobrien   Once we return, we will have emitted warnings if any subexpression before
135890082Sobrien   such a sequence point could be undefined.  On a higher level, however, the
135990082Sobrien   sequence point may not be relevant, and we'll merge the two lists.
136050449Sobrien
136190082Sobrien   Example: (b++, a) + b;
136290082Sobrien   The call that processes the COMPOUND_EXPR will store the increment of B
136390082Sobrien   in PBEFORE_SP, and the use of A in PNO_SP.  The higher-level call that
136490082Sobrien   processes the PLUS_EXPR will need to merge the two lists so that
136590082Sobrien   eventually, all accesses end up on the same list (and we'll warn about the
136690082Sobrien   unordered subexpressions b++ and b.
136750449Sobrien
136890082Sobrien   A note on merging.  If we modify the former example so that our expression
136990082Sobrien   becomes
137090082Sobrien     (b++, b) + a
137190082Sobrien   care must be taken not simply to add all three expressions into the final
137290082Sobrien   PNO_SP list.  The function merge_tlist takes care of that by merging the
137390082Sobrien   before-SP list of the COMPOUND_EXPR into its after-SP list in a special
137490082Sobrien   way, so that no more than one access to B is recorded.  */
137550449Sobrien
137690082Sobrienstatic void
1377132728Skanverify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp,
1378132728Skan	     tree writer)
137990082Sobrien{
138090082Sobrien  struct tlist *tmp_before, *tmp_nosp, *tmp_list2, *tmp_list3;
138190082Sobrien  enum tree_code code;
1382169699Skan  enum tree_code_class cl;
138350449Sobrien
138490082Sobrien  /* X may be NULL if it is the operand of an empty statement expression
138590082Sobrien     ({ }).  */
138690082Sobrien  if (x == NULL)
138790082Sobrien    return;
138850449Sobrien
138990082Sobrien restart:
139090082Sobrien  code = TREE_CODE (x);
1391169699Skan  cl = TREE_CODE_CLASS (code);
139290082Sobrien
139390082Sobrien  if (warning_candidate_p (x))
139418334Speter    {
139590082Sobrien      *pno_sp = new_tlist (*pno_sp, x, writer);
139618334Speter      return;
139718334Speter    }
139890082Sobrien
139990082Sobrien  switch (code)
140018334Speter    {
140190082Sobrien    case CONSTRUCTOR:
140218334Speter      return;
140318334Speter
140490082Sobrien    case COMPOUND_EXPR:
140590082Sobrien    case TRUTH_ANDIF_EXPR:
140690082Sobrien    case TRUTH_ORIF_EXPR:
140790082Sobrien      tmp_before = tmp_nosp = tmp_list3 = 0;
140890082Sobrien      verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_nosp, NULL_TREE);
140990082Sobrien      warn_for_collisions (tmp_nosp);
141090082Sobrien      merge_tlist (pbefore_sp, tmp_before, 0);
141190082Sobrien      merge_tlist (pbefore_sp, tmp_nosp, 0);
141290082Sobrien      verify_tree (TREE_OPERAND (x, 1), &tmp_list3, pno_sp, NULL_TREE);
141390082Sobrien      merge_tlist (pbefore_sp, tmp_list3, 0);
141490082Sobrien      return;
141518334Speter
141690082Sobrien    case COND_EXPR:
141790082Sobrien      tmp_before = tmp_list2 = 0;
141890082Sobrien      verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_list2, NULL_TREE);
141990082Sobrien      warn_for_collisions (tmp_list2);
142090082Sobrien      merge_tlist (pbefore_sp, tmp_before, 0);
142190082Sobrien      merge_tlist (pbefore_sp, tmp_list2, 1);
142218334Speter
142390082Sobrien      tmp_list3 = tmp_nosp = 0;
142490082Sobrien      verify_tree (TREE_OPERAND (x, 1), &tmp_list3, &tmp_nosp, NULL_TREE);
142590082Sobrien      warn_for_collisions (tmp_nosp);
142690082Sobrien      merge_tlist (pbefore_sp, tmp_list3, 0);
142718334Speter
142890082Sobrien      tmp_list3 = tmp_list2 = 0;
142990082Sobrien      verify_tree (TREE_OPERAND (x, 2), &tmp_list3, &tmp_list2, NULL_TREE);
143090082Sobrien      warn_for_collisions (tmp_list2);
143190082Sobrien      merge_tlist (pbefore_sp, tmp_list3, 0);
143290082Sobrien      /* Rather than add both tmp_nosp and tmp_list2, we have to merge the
143390082Sobrien	 two first, to avoid warning for (a ? b++ : b++).  */
143490082Sobrien      merge_tlist (&tmp_nosp, tmp_list2, 0);
143590082Sobrien      add_tlist (pno_sp, tmp_nosp, NULL_TREE, 0);
143690082Sobrien      return;
143718334Speter
143890082Sobrien    case PREDECREMENT_EXPR:
143990082Sobrien    case PREINCREMENT_EXPR:
144090082Sobrien    case POSTDECREMENT_EXPR:
144190082Sobrien    case POSTINCREMENT_EXPR:
144290082Sobrien      verify_tree (TREE_OPERAND (x, 0), pno_sp, pno_sp, x);
144390082Sobrien      return;
144418334Speter
144590082Sobrien    case MODIFY_EXPR:
144690082Sobrien      tmp_before = tmp_nosp = tmp_list3 = 0;
144790082Sobrien      verify_tree (TREE_OPERAND (x, 1), &tmp_before, &tmp_nosp, NULL_TREE);
144890082Sobrien      verify_tree (TREE_OPERAND (x, 0), &tmp_list3, &tmp_list3, x);
144990082Sobrien      /* Expressions inside the LHS are not ordered wrt. the sequence points
145090082Sobrien	 in the RHS.  Example:
145190082Sobrien	   *a = (a++, 2)
145290082Sobrien	 Despite the fact that the modification of "a" is in the before_sp
145390082Sobrien	 list (tmp_before), it conflicts with the use of "a" in the LHS.
145490082Sobrien	 We can handle this by adding the contents of tmp_list3
145590082Sobrien	 to those of tmp_before, and redoing the collision warnings for that
145690082Sobrien	 list.  */
145790082Sobrien      add_tlist (&tmp_before, tmp_list3, x, 1);
145890082Sobrien      warn_for_collisions (tmp_before);
145990082Sobrien      /* Exclude the LHS itself here; we first have to merge it into the
146090082Sobrien	 tmp_nosp list.  This is done to avoid warning for "a = a"; if we
146190082Sobrien	 didn't exclude the LHS, we'd get it twice, once as a read and once
146290082Sobrien	 as a write.  */
146390082Sobrien      add_tlist (pno_sp, tmp_list3, x, 0);
146490082Sobrien      warn_for_collisions_1 (TREE_OPERAND (x, 0), x, tmp_nosp, 1);
146518334Speter
146690082Sobrien      merge_tlist (pbefore_sp, tmp_before, 0);
146790082Sobrien      if (warning_candidate_p (TREE_OPERAND (x, 0)))
146890082Sobrien	merge_tlist (&tmp_nosp, new_tlist (NULL, TREE_OPERAND (x, 0), x), 0);
146990082Sobrien      add_tlist (pno_sp, tmp_nosp, NULL_TREE, 1);
147090082Sobrien      return;
147150449Sobrien
147290082Sobrien    case CALL_EXPR:
147390082Sobrien      /* We need to warn about conflicts among arguments and conflicts between
147490082Sobrien	 args and the function address.  Side effects of the function address,
147590082Sobrien	 however, are not ordered by the sequence point of the call.  */
147690082Sobrien      tmp_before = tmp_nosp = tmp_list2 = tmp_list3 = 0;
147790082Sobrien      verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_nosp, NULL_TREE);
147890082Sobrien      if (TREE_OPERAND (x, 1))
147990082Sobrien	verify_tree (TREE_OPERAND (x, 1), &tmp_list2, &tmp_list3, NULL_TREE);
148090082Sobrien      merge_tlist (&tmp_list3, tmp_list2, 0);
148190082Sobrien      add_tlist (&tmp_before, tmp_list3, NULL_TREE, 0);
148290082Sobrien      add_tlist (&tmp_before, tmp_nosp, NULL_TREE, 0);
148390082Sobrien      warn_for_collisions (tmp_before);
148490082Sobrien      add_tlist (pbefore_sp, tmp_before, NULL_TREE, 0);
148590082Sobrien      return;
148650449Sobrien
148790082Sobrien    case TREE_LIST:
148890082Sobrien      /* Scan all the list, e.g. indices of multi dimensional array.  */
148990082Sobrien      while (x)
149018334Speter	{
149190082Sobrien	  tmp_before = tmp_nosp = 0;
149290082Sobrien	  verify_tree (TREE_VALUE (x), &tmp_before, &tmp_nosp, NULL_TREE);
149390082Sobrien	  merge_tlist (&tmp_nosp, tmp_before, 0);
149490082Sobrien	  add_tlist (pno_sp, tmp_nosp, NULL_TREE, 0);
149590082Sobrien	  x = TREE_CHAIN (x);
149618334Speter	}
149790082Sobrien      return;
149818334Speter
149990082Sobrien    case SAVE_EXPR:
150090082Sobrien      {
150190082Sobrien	struct tlist_cache *t;
150290082Sobrien	for (t = save_expr_cache; t; t = t->next)
150390082Sobrien	  if (t->expr == x)
150490082Sobrien	    break;
150518334Speter
1506169699Skan	if (!t)
150790082Sobrien	  {
1508169699Skan	    t = XOBNEW (&tlist_obstack, struct tlist_cache);
150990082Sobrien	    t->next = save_expr_cache;
151090082Sobrien	    t->expr = x;
151190082Sobrien	    save_expr_cache = t;
151250449Sobrien
151390082Sobrien	    tmp_before = tmp_nosp = 0;
151490082Sobrien	    verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_nosp, NULL_TREE);
151590082Sobrien	    warn_for_collisions (tmp_nosp);
151650449Sobrien
151790082Sobrien	    tmp_list3 = 0;
151890082Sobrien	    while (tmp_nosp)
151990082Sobrien	      {
152090082Sobrien		struct tlist *t = tmp_nosp;
152190082Sobrien		tmp_nosp = t->next;
152290082Sobrien		merge_tlist (&tmp_list3, t, 0);
152390082Sobrien	      }
152490082Sobrien	    t->cache_before_sp = tmp_before;
152590082Sobrien	    t->cache_after_sp = tmp_list3;
152690082Sobrien	  }
152790082Sobrien	merge_tlist (pbefore_sp, t->cache_before_sp, 1);
152890082Sobrien	add_tlist (pno_sp, t->cache_after_sp, NULL_TREE, 1);
152990082Sobrien	return;
153090082Sobrien      }
1531169699Skan
153290082Sobrien    default:
1533169699Skan      /* For other expressions, simply recurse on their operands.
1534169699Skan	 Manual tail recursion for unary expressions.
1535169699Skan	 Other non-expressions need not be processed.  */
1536169699Skan      if (cl == tcc_unary)
1537169699Skan	{
1538169699Skan	  x = TREE_OPERAND (x, 0);
1539169699Skan	  writer = 0;
1540169699Skan	  goto restart;
1541169699Skan	}
1542169699Skan      else if (IS_EXPR_CODE_CLASS (cl))
1543169699Skan	{
1544169699Skan	  int lp;
1545169699Skan	  int max = TREE_CODE_LENGTH (TREE_CODE (x));
1546169699Skan	  for (lp = 0; lp < max; lp++)
1547169699Skan	    {
1548169699Skan	      tmp_before = tmp_nosp = 0;
1549169699Skan	      verify_tree (TREE_OPERAND (x, lp), &tmp_before, &tmp_nosp, 0);
1550169699Skan	      merge_tlist (&tmp_nosp, tmp_before, 0);
1551169699Skan	      add_tlist (pno_sp, tmp_nosp, NULL_TREE, 0);
1552169699Skan	    }
1553169699Skan	}
1554169699Skan      return;
155518334Speter    }
155618334Speter}
155718334Speter
1558117404Skan/* Try to warn for undefined behavior in EXPR due to missing sequence
155990082Sobrien   points.  */
156018334Speter
1561169699Skanvoid
1562132728Skanverify_sequence_points (tree expr)
156318334Speter{
156490082Sobrien  struct tlist *before_sp = 0, *after_sp = 0;
156590082Sobrien
156690082Sobrien  warned_ids = 0;
156790082Sobrien  save_expr_cache = 0;
156890082Sobrien  if (tlist_firstobj == 0)
156918334Speter    {
157090082Sobrien      gcc_obstack_init (&tlist_obstack);
1571169699Skan      tlist_firstobj = (char *) obstack_alloc (&tlist_obstack, 0);
157218334Speter    }
157390082Sobrien
157490082Sobrien  verify_tree (expr, &before_sp, &after_sp, 0);
157590082Sobrien  warn_for_collisions (after_sp);
157690082Sobrien  obstack_free (&tlist_obstack, tlist_firstobj);
157718334Speter}
157818334Speter
157918334Speter/* Validate the expression after `case' and apply default promotions.  */
158018334Speter
1581169699Skanstatic tree
1582132728Skancheck_case_value (tree value)
158318334Speter{
158418334Speter  if (value == NULL_TREE)
158518334Speter    return value;
158618334Speter
1587169699Skan  /* ??? Can we ever get nops here for a valid case value?  We
1588169699Skan     shouldn't for C.  */
158918334Speter  STRIP_TYPE_NOPS (value);
159090082Sobrien  /* In C++, the following is allowed:
159118334Speter
159290082Sobrien       const int i = 3;
159390082Sobrien       switch (...) { case i: ... }
159490082Sobrien
159590082Sobrien     So, we try to reduce the VALUE to a constant that way.  */
1596132728Skan  if (c_dialect_cxx ())
159790082Sobrien    {
159890082Sobrien      value = decl_constant_value (value);
159990082Sobrien      STRIP_TYPE_NOPS (value);
160090082Sobrien      value = fold (value);
160190082Sobrien    }
160290082Sobrien
1603169699Skan  if (TREE_CODE (value) == INTEGER_CST)
1604169699Skan    /* Promote char or short to int.  */
1605169699Skan    value = perform_integral_promotions (value);
1606169699Skan  else if (value != error_mark_node)
160718334Speter    {
160818334Speter      error ("case label does not reduce to an integer constant");
160918334Speter      value = error_mark_node;
161018334Speter    }
161118334Speter
161218334Speter  constant_expression_warning (value);
161318334Speter
161418334Speter  return value;
161518334Speter}
161618334Speter
1617169699Skan/* See if the case values LOW and HIGH are in the range of the original
1618169699Skan   type (i.e. before the default conversion to int) of the switch testing
1619169699Skan   expression.
1620169699Skan   TYPE is the promoted type of the testing expression, and ORIG_TYPE is
1621169699Skan   the type before promoting it.  CASE_LOW_P is a pointer to the lower
1622169699Skan   bound of the case label, and CASE_HIGH_P is the upper bound or NULL
1623169699Skan   if the case is not a case range.
1624169699Skan   The caller has to make sure that we are not called with NULL for
1625169699Skan   CASE_LOW_P (i.e. the default case).
1626169699Skan   Returns true if the case label is in range of ORIG_TYPE (saturated or
1627169699Skan   untouched) or false if the label is out of range.  */
1628169699Skan
1629169699Skanstatic bool
1630169699Skancheck_case_bounds (tree type, tree orig_type,
1631169699Skan		   tree *case_low_p, tree *case_high_p)
1632169699Skan{
1633169699Skan  tree min_value, max_value;
1634169699Skan  tree case_low = *case_low_p;
1635169699Skan  tree case_high = case_high_p ? *case_high_p : case_low;
1636169699Skan
1637169699Skan  /* If there was a problem with the original type, do nothing.  */
1638169699Skan  if (orig_type == error_mark_node)
1639169699Skan    return true;
1640169699Skan
1641169699Skan  min_value = TYPE_MIN_VALUE (orig_type);
1642169699Skan  max_value = TYPE_MAX_VALUE (orig_type);
1643169699Skan
1644169699Skan  /* Case label is less than minimum for type.  */
1645169699Skan  if (tree_int_cst_compare (case_low, min_value) < 0
1646169699Skan      && tree_int_cst_compare (case_high, min_value) < 0)
1647169699Skan    {
1648169699Skan      warning (0, "case label value is less than minimum value for type");
1649169699Skan      return false;
1650169699Skan    }
1651169699Skan
1652169699Skan  /* Case value is greater than maximum for type.  */
1653169699Skan  if (tree_int_cst_compare (case_low, max_value) > 0
1654169699Skan      && tree_int_cst_compare (case_high, max_value) > 0)
1655169699Skan    {
1656169699Skan      warning (0, "case label value exceeds maximum value for type");
1657169699Skan      return false;
1658169699Skan    }
1659169699Skan
1660169699Skan  /* Saturate lower case label value to minimum.  */
1661169699Skan  if (tree_int_cst_compare (case_high, min_value) >= 0
1662169699Skan      && tree_int_cst_compare (case_low, min_value) < 0)
1663169699Skan    {
1664169699Skan      warning (0, "lower value in case label range"
1665169699Skan	       " less than minimum value for type");
1666169699Skan      case_low = min_value;
1667169699Skan    }
1668169699Skan
1669169699Skan  /* Saturate upper case label value to maximum.  */
1670169699Skan  if (tree_int_cst_compare (case_low, max_value) <= 0
1671169699Skan      && tree_int_cst_compare (case_high, max_value) > 0)
1672169699Skan    {
1673169699Skan      warning (0, "upper value in case label range"
1674169699Skan	       " exceeds maximum value for type");
1675169699Skan      case_high = max_value;
1676169699Skan    }
1677169699Skan
1678169699Skan  if (*case_low_p != case_low)
1679169699Skan    *case_low_p = convert (type, case_low);
1680169699Skan  if (case_high_p && *case_high_p != case_high)
1681169699Skan    *case_high_p = convert (type, case_high);
1682169699Skan
1683169699Skan  return true;
1684169699Skan}
1685169699Skan
168618334Speter/* Return an integer type with BITS bits of precision,
168718334Speter   that is unsigned if UNSIGNEDP is nonzero, otherwise signed.  */
168818334Speter
168918334Spetertree
1690132728Skanc_common_type_for_size (unsigned int bits, int unsignedp)
169118334Speter{
169218334Speter  if (bits == TYPE_PRECISION (integer_type_node))
169318334Speter    return unsignedp ? unsigned_type_node : integer_type_node;
169418334Speter
169518334Speter  if (bits == TYPE_PRECISION (signed_char_type_node))
169618334Speter    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
169718334Speter
169818334Speter  if (bits == TYPE_PRECISION (short_integer_type_node))
169918334Speter    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
170018334Speter
170118334Speter  if (bits == TYPE_PRECISION (long_integer_type_node))
170218334Speter    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
170318334Speter
170418334Speter  if (bits == TYPE_PRECISION (long_long_integer_type_node))
170518334Speter    return (unsignedp ? long_long_unsigned_type_node
170618334Speter	    : long_long_integer_type_node);
170718334Speter
170890082Sobrien  if (bits == TYPE_PRECISION (widest_integer_literal_type_node))
170990082Sobrien    return (unsignedp ? widest_unsigned_literal_type_node
171090082Sobrien	    : widest_integer_literal_type_node);
171190082Sobrien
171218334Speter  if (bits <= TYPE_PRECISION (intQI_type_node))
171318334Speter    return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
171418334Speter
171518334Speter  if (bits <= TYPE_PRECISION (intHI_type_node))
171618334Speter    return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
171718334Speter
171818334Speter  if (bits <= TYPE_PRECISION (intSI_type_node))
171918334Speter    return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
172018334Speter
172118334Speter  if (bits <= TYPE_PRECISION (intDI_type_node))
172218334Speter    return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
172318334Speter
172418334Speter  return 0;
172518334Speter}
172618334Speter
1727132728Skan/* Used for communication between c_common_type_for_mode and
1728132728Skan   c_register_builtin_type.  */
1729132728Skanstatic GTY(()) tree registered_builtin_types;
1730132728Skan
173118334Speter/* Return a data type that has machine mode MODE.
173218334Speter   If the mode is an integer,
173318334Speter   then UNSIGNEDP selects between signed and unsigned types.  */
173418334Speter
173518334Spetertree
1736132728Skanc_common_type_for_mode (enum machine_mode mode, int unsignedp)
173718334Speter{
1738132728Skan  tree t;
1739132728Skan
174018334Speter  if (mode == TYPE_MODE (integer_type_node))
174118334Speter    return unsignedp ? unsigned_type_node : integer_type_node;
174218334Speter
174318334Speter  if (mode == TYPE_MODE (signed_char_type_node))
174418334Speter    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
174518334Speter
174618334Speter  if (mode == TYPE_MODE (short_integer_type_node))
174718334Speter    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
174818334Speter
174918334Speter  if (mode == TYPE_MODE (long_integer_type_node))
175018334Speter    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
175118334Speter
175218334Speter  if (mode == TYPE_MODE (long_long_integer_type_node))
175318334Speter    return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
175418334Speter
175590082Sobrien  if (mode == TYPE_MODE (widest_integer_literal_type_node))
175690082Sobrien    return unsignedp ? widest_unsigned_literal_type_node
1757169699Skan		     : widest_integer_literal_type_node;
175890082Sobrien
175990082Sobrien  if (mode == QImode)
176018334Speter    return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
176118334Speter
176290082Sobrien  if (mode == HImode)
176318334Speter    return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
176418334Speter
176590082Sobrien  if (mode == SImode)
176618334Speter    return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
176718334Speter
176890082Sobrien  if (mode == DImode)
176918334Speter    return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
177018334Speter
177152299Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
177250449Sobrien  if (mode == TYPE_MODE (intTI_type_node))
177350449Sobrien    return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
177452299Sobrien#endif
177550449Sobrien
177618334Speter  if (mode == TYPE_MODE (float_type_node))
177718334Speter    return float_type_node;
177818334Speter
177918334Speter  if (mode == TYPE_MODE (double_type_node))
178018334Speter    return double_type_node;
178118334Speter
178218334Speter  if (mode == TYPE_MODE (long_double_type_node))
178318334Speter    return long_double_type_node;
178418334Speter
1785132728Skan  if (mode == TYPE_MODE (void_type_node))
1786132728Skan    return void_type_node;
1787169699Skan
178818334Speter  if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
1789169699Skan    return (unsignedp
1790169699Skan	    ? make_unsigned_type (GET_MODE_PRECISION (mode))
1791169699Skan	    : make_signed_type (GET_MODE_PRECISION (mode)));
179218334Speter
179318334Speter  if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
1794169699Skan    return (unsignedp
1795169699Skan	    ? make_unsigned_type (GET_MODE_PRECISION (mode))
1796169699Skan	    : make_signed_type (GET_MODE_PRECISION (mode)));
179718334Speter
1798169699Skan  if (COMPLEX_MODE_P (mode))
179990082Sobrien    {
1800169699Skan      enum machine_mode inner_mode;
1801169699Skan      tree inner_type;
1802169699Skan
1803169699Skan      if (mode == TYPE_MODE (complex_float_type_node))
1804169699Skan	return complex_float_type_node;
1805169699Skan      if (mode == TYPE_MODE (complex_double_type_node))
1806169699Skan	return complex_double_type_node;
1807169699Skan      if (mode == TYPE_MODE (complex_long_double_type_node))
1808169699Skan	return complex_long_double_type_node;
1809169699Skan
1810169699Skan      if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
1811169699Skan	return complex_integer_type_node;
1812169699Skan
1813169699Skan      inner_mode = GET_MODE_INNER (mode);
1814169699Skan      inner_type = c_common_type_for_mode (inner_mode, unsignedp);
1815169699Skan      if (inner_type != NULL_TREE)
1816169699Skan	return build_complex_type (inner_type);
181790082Sobrien    }
1818169699Skan  else if (VECTOR_MODE_P (mode))
1819169699Skan    {
1820169699Skan      enum machine_mode inner_mode = GET_MODE_INNER (mode);
1821169699Skan      tree inner_type = c_common_type_for_mode (inner_mode, unsignedp);
1822169699Skan      if (inner_type != NULL_TREE)
1823169699Skan	return build_vector_type_for_mode (inner_type, mode);
1824169699Skan    }
182590082Sobrien
1826169699Skan  if (mode == TYPE_MODE (dfloat32_type_node))
1827169699Skan    return dfloat32_type_node;
1828169699Skan  if (mode == TYPE_MODE (dfloat64_type_node))
1829169699Skan    return dfloat64_type_node;
1830169699Skan  if (mode == TYPE_MODE (dfloat128_type_node))
1831169699Skan    return dfloat128_type_node;
1832169699Skan
1833132728Skan  for (t = registered_builtin_types; t; t = TREE_CHAIN (t))
1834132728Skan    if (TYPE_MODE (TREE_VALUE (t)) == mode)
1835132728Skan      return TREE_VALUE (t);
1836132728Skan
183718334Speter  return 0;
183818334Speter}
183990082Sobrien
184090082Sobrien/* Return an unsigned type the same as TYPE in other respects.  */
184190082Sobrientree
1842132728Skanc_common_unsigned_type (tree type)
184390082Sobrien{
184490082Sobrien  tree type1 = TYPE_MAIN_VARIANT (type);
184590082Sobrien  if (type1 == signed_char_type_node || type1 == char_type_node)
184690082Sobrien    return unsigned_char_type_node;
184790082Sobrien  if (type1 == integer_type_node)
184890082Sobrien    return unsigned_type_node;
184990082Sobrien  if (type1 == short_integer_type_node)
185090082Sobrien    return short_unsigned_type_node;
185190082Sobrien  if (type1 == long_integer_type_node)
185290082Sobrien    return long_unsigned_type_node;
185390082Sobrien  if (type1 == long_long_integer_type_node)
185490082Sobrien    return long_long_unsigned_type_node;
185590082Sobrien  if (type1 == widest_integer_literal_type_node)
185690082Sobrien    return widest_unsigned_literal_type_node;
185790082Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
185890082Sobrien  if (type1 == intTI_type_node)
185990082Sobrien    return unsigned_intTI_type_node;
186090082Sobrien#endif
186190082Sobrien  if (type1 == intDI_type_node)
186290082Sobrien    return unsigned_intDI_type_node;
186390082Sobrien  if (type1 == intSI_type_node)
186490082Sobrien    return unsigned_intSI_type_node;
186590082Sobrien  if (type1 == intHI_type_node)
186690082Sobrien    return unsigned_intHI_type_node;
186790082Sobrien  if (type1 == intQI_type_node)
186890082Sobrien    return unsigned_intQI_type_node;
186990082Sobrien
1870117404Skan  return c_common_signed_or_unsigned_type (1, type);
187190082Sobrien}
187290082Sobrien
187390082Sobrien/* Return a signed type the same as TYPE in other respects.  */
187490082Sobrien
187590082Sobrientree
1876132728Skanc_common_signed_type (tree type)
187790082Sobrien{
187890082Sobrien  tree type1 = TYPE_MAIN_VARIANT (type);
187990082Sobrien  if (type1 == unsigned_char_type_node || type1 == char_type_node)
188090082Sobrien    return signed_char_type_node;
188190082Sobrien  if (type1 == unsigned_type_node)
188290082Sobrien    return integer_type_node;
188390082Sobrien  if (type1 == short_unsigned_type_node)
188490082Sobrien    return short_integer_type_node;
188590082Sobrien  if (type1 == long_unsigned_type_node)
188690082Sobrien    return long_integer_type_node;
188790082Sobrien  if (type1 == long_long_unsigned_type_node)
188890082Sobrien    return long_long_integer_type_node;
188990082Sobrien  if (type1 == widest_unsigned_literal_type_node)
189090082Sobrien    return widest_integer_literal_type_node;
189190082Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
189290082Sobrien  if (type1 == unsigned_intTI_type_node)
189390082Sobrien    return intTI_type_node;
189490082Sobrien#endif
189590082Sobrien  if (type1 == unsigned_intDI_type_node)
189690082Sobrien    return intDI_type_node;
189790082Sobrien  if (type1 == unsigned_intSI_type_node)
189890082Sobrien    return intSI_type_node;
189990082Sobrien  if (type1 == unsigned_intHI_type_node)
190090082Sobrien    return intHI_type_node;
190190082Sobrien  if (type1 == unsigned_intQI_type_node)
190290082Sobrien    return intQI_type_node;
190390082Sobrien
1904117404Skan  return c_common_signed_or_unsigned_type (0, type);
190590082Sobrien}
190690082Sobrien
190790082Sobrien/* Return a type the same as TYPE except unsigned or
190890082Sobrien   signed according to UNSIGNEDP.  */
190990082Sobrien
191090082Sobrientree
1911132728Skanc_common_signed_or_unsigned_type (int unsignedp, tree type)
191290082Sobrien{
1913169699Skan  if (!INTEGRAL_TYPE_P (type)
1914169699Skan      || TYPE_UNSIGNED (type) == unsignedp)
191590082Sobrien    return type;
191690082Sobrien
1917169699Skan  /* For ENUMERAL_TYPEs in C++, must check the mode of the types, not
1918169699Skan     the precision; they have precision set to match their range, but
1919169699Skan     may use a wider mode to match an ABI.  If we change modes, we may
1920169699Skan     wind up with bad conversions.  For INTEGER_TYPEs in C, must check
1921169699Skan     the precision as well, so as to yield correct results for
1922169699Skan     bit-field types.  C++ does not have these separate bit-field
1923169699Skan     types, and producing a signed or unsigned variant of an
1924169699Skan     ENUMERAL_TYPE may cause other problems as well.  */
1925132728Skan
1926169699Skan#define TYPE_OK(node)							    \
1927169699Skan  (TYPE_MODE (type) == TYPE_MODE (node)					    \
1928169699Skan   && (c_dialect_cxx () || TYPE_PRECISION (type) == TYPE_PRECISION (node)))
1929169699Skan  if (TYPE_OK (signed_char_type_node))
193090082Sobrien    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
1931169699Skan  if (TYPE_OK (integer_type_node))
193290082Sobrien    return unsignedp ? unsigned_type_node : integer_type_node;
1933169699Skan  if (TYPE_OK (short_integer_type_node))
193490082Sobrien    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
1935169699Skan  if (TYPE_OK (long_integer_type_node))
193690082Sobrien    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
1937169699Skan  if (TYPE_OK (long_long_integer_type_node))
193890082Sobrien    return (unsignedp ? long_long_unsigned_type_node
193990082Sobrien	    : long_long_integer_type_node);
1940169699Skan  if (TYPE_OK (widest_integer_literal_type_node))
194190082Sobrien    return (unsignedp ? widest_unsigned_literal_type_node
194290082Sobrien	    : widest_integer_literal_type_node);
194390082Sobrien
194490082Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
1945169699Skan  if (TYPE_OK (intTI_type_node))
194690082Sobrien    return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
194790082Sobrien#endif
1948169699Skan  if (TYPE_OK (intDI_type_node))
194990082Sobrien    return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
1950169699Skan  if (TYPE_OK (intSI_type_node))
195190082Sobrien    return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
1952169699Skan  if (TYPE_OK (intHI_type_node))
195390082Sobrien    return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
1954169699Skan  if (TYPE_OK (intQI_type_node))
195590082Sobrien    return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
1956169699Skan#undef TYPE_OK
195790082Sobrien
1958169699Skan  if (c_dialect_cxx ())
1959169699Skan    return type;
1960169699Skan  else
1961169699Skan    return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
196290082Sobrien}
1963132728Skan
1964169699Skan/* Build a bit-field integer type for the given WIDTH and UNSIGNEDP.  */
1965169699Skan
1966169699Skantree
1967169699Skanc_build_bitfield_integer_type (unsigned HOST_WIDE_INT width, int unsignedp)
1968169699Skan{
1969169699Skan  /* Extended integer types of the same width as a standard type have
1970169699Skan     lesser rank, so those of the same width as int promote to int or
1971169699Skan     unsigned int and are valid for printf formats expecting int or
1972169699Skan     unsigned int.  To avoid such special cases, avoid creating
1973169699Skan     extended integer types for bit-fields if a standard integer type
1974169699Skan     is available.  */
1975169699Skan  if (width == TYPE_PRECISION (integer_type_node))
1976169699Skan    return unsignedp ? unsigned_type_node : integer_type_node;
1977169699Skan  if (width == TYPE_PRECISION (signed_char_type_node))
1978169699Skan    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
1979169699Skan  if (width == TYPE_PRECISION (short_integer_type_node))
1980169699Skan    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
1981169699Skan  if (width == TYPE_PRECISION (long_integer_type_node))
1982169699Skan    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
1983169699Skan  if (width == TYPE_PRECISION (long_long_integer_type_node))
1984169699Skan    return (unsignedp ? long_long_unsigned_type_node
1985169699Skan	    : long_long_integer_type_node);
1986169699Skan  return build_nonstandard_integer_type (width, unsignedp);
1987169699Skan}
1988169699Skan
1989132728Skan/* The C version of the register_builtin_type langhook.  */
1990132728Skan
1991132728Skanvoid
1992132728Skanc_register_builtin_type (tree type, const char* name)
1993132728Skan{
1994132728Skan  tree decl;
1995132728Skan
1996132728Skan  decl = build_decl (TYPE_DECL, get_identifier (name), type);
1997132728Skan  DECL_ARTIFICIAL (decl) = 1;
1998132728Skan  if (!TYPE_NAME (type))
1999132728Skan    TYPE_NAME (type) = decl;
2000132728Skan  pushdecl (decl);
2001132728Skan
2002132728Skan  registered_builtin_types = tree_cons (0, type, registered_builtin_types);
2003132728Skan}
2004132728Skan
200518334Speter
200618334Speter/* Return the minimum number of bits needed to represent VALUE in a
200718334Speter   signed or unsigned type, UNSIGNEDP says which.  */
200818334Speter
200990082Sobrienunsigned int
2010132728Skanmin_precision (tree value, int unsignedp)
201118334Speter{
201218334Speter  int log;
201318334Speter
201418334Speter  /* If the value is negative, compute its negative minus 1.  The latter
201518334Speter     adjustment is because the absolute value of the largest negative value
201618334Speter     is one larger than the largest positive value.  This is equivalent to
201718334Speter     a bit-wise negation, so use that operation instead.  */
201818334Speter
201918334Speter  if (tree_int_cst_sgn (value) < 0)
2020169699Skan    value = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (value), value);
202118334Speter
202218334Speter  /* Return the number of bits needed, taking into account the fact
202318334Speter     that we need one more bit for a signed than unsigned type.  */
202418334Speter
202518334Speter  if (integer_zerop (value))
202618334Speter    log = 0;
202718334Speter  else
202890082Sobrien    log = tree_floor_log2 (value);
202918334Speter
2030169699Skan  return log + 1 + !unsignedp;
203118334Speter}
203218334Speter
2033117404Skan/* Print an error message for invalid operands to arith operation
2034259947Spfg   CODE with TYPE0 for operand 0, and TYPE1 for operand 1.  */
203518334Speter
203618334Spetervoid
2037259947Spfgbinary_op_error (enum tree_code code, tree type0, tree type1)
203818334Speter{
203990082Sobrien  const char *opname;
204018334Speter
204118334Speter  switch (code)
204218334Speter    {
204318334Speter    case PLUS_EXPR:
204418334Speter      opname = "+"; break;
204518334Speter    case MINUS_EXPR:
204618334Speter      opname = "-"; break;
204718334Speter    case MULT_EXPR:
204818334Speter      opname = "*"; break;
204918334Speter    case MAX_EXPR:
205018334Speter      opname = "max"; break;
205118334Speter    case MIN_EXPR:
205218334Speter      opname = "min"; break;
205318334Speter    case EQ_EXPR:
205418334Speter      opname = "=="; break;
205518334Speter    case NE_EXPR:
205618334Speter      opname = "!="; break;
205718334Speter    case LE_EXPR:
205818334Speter      opname = "<="; break;
205918334Speter    case GE_EXPR:
206018334Speter      opname = ">="; break;
206118334Speter    case LT_EXPR:
206218334Speter      opname = "<"; break;
206318334Speter    case GT_EXPR:
206418334Speter      opname = ">"; break;
206518334Speter    case LSHIFT_EXPR:
206618334Speter      opname = "<<"; break;
206718334Speter    case RSHIFT_EXPR:
206818334Speter      opname = ">>"; break;
206918334Speter    case TRUNC_MOD_EXPR:
207018334Speter    case FLOOR_MOD_EXPR:
207118334Speter      opname = "%"; break;
207218334Speter    case TRUNC_DIV_EXPR:
207318334Speter    case FLOOR_DIV_EXPR:
207418334Speter      opname = "/"; break;
207518334Speter    case BIT_AND_EXPR:
207618334Speter      opname = "&"; break;
207718334Speter    case BIT_IOR_EXPR:
207818334Speter      opname = "|"; break;
207918334Speter    case TRUTH_ANDIF_EXPR:
208018334Speter      opname = "&&"; break;
208118334Speter    case TRUTH_ORIF_EXPR:
208218334Speter      opname = "||"; break;
208318334Speter    case BIT_XOR_EXPR:
208418334Speter      opname = "^"; break;
208550449Sobrien    default:
2086169699Skan      gcc_unreachable ();
208718334Speter    }
2088259947Spfg  error ("invalid operands to binary %s (have %qT and %qT)", opname,
2089259947Spfg	 type0, type1);
209018334Speter}
209118334Speter
209218334Speter/* Subroutine of build_binary_op, used for comparison operations.
209318334Speter   See if the operands have both been converted from subword integer types
209418334Speter   and, if so, perhaps change them both back to their original type.
209518334Speter   This function is also responsible for converting the two operands
209618334Speter   to the proper common type for comparison.
209718334Speter
209818334Speter   The arguments of this function are all pointers to local variables
209918334Speter   of build_binary_op: OP0_PTR is &OP0, OP1_PTR is &OP1,
210018334Speter   RESTYPE_PTR is &RESULT_TYPE and RESCODE_PTR is &RESULTCODE.
210118334Speter
210218334Speter   If this function returns nonzero, it means that the comparison has
210318334Speter   a constant value.  What this function returns is an expression for
210418334Speter   that value.  */
210518334Speter
210618334Spetertree
2107132728Skanshorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
2108132728Skan		 enum tree_code *rescode_ptr)
210918334Speter{
211090082Sobrien  tree type;
211118334Speter  tree op0 = *op0_ptr;
211218334Speter  tree op1 = *op1_ptr;
211318334Speter  int unsignedp0, unsignedp1;
211418334Speter  int real1, real2;
211518334Speter  tree primop0, primop1;
211618334Speter  enum tree_code code = *rescode_ptr;
211718334Speter
211818334Speter  /* Throw away any conversions to wider types
211918334Speter     already present in the operands.  */
212018334Speter
212118334Speter  primop0 = get_narrower (op0, &unsignedp0);
212218334Speter  primop1 = get_narrower (op1, &unsignedp1);
212318334Speter
212418334Speter  /* Handle the case that OP0 does not *contain* a conversion
212518334Speter     but it *requires* conversion to FINAL_TYPE.  */
212618334Speter
212718334Speter  if (op0 == primop0 && TREE_TYPE (op0) != *restype_ptr)
2128169699Skan    unsignedp0 = TYPE_UNSIGNED (TREE_TYPE (op0));
212918334Speter  if (op1 == primop1 && TREE_TYPE (op1) != *restype_ptr)
2130169699Skan    unsignedp1 = TYPE_UNSIGNED (TREE_TYPE (op1));
213118334Speter
213218334Speter  /* If one of the operands must be floated, we cannot optimize.  */
213318334Speter  real1 = TREE_CODE (TREE_TYPE (primop0)) == REAL_TYPE;
213418334Speter  real2 = TREE_CODE (TREE_TYPE (primop1)) == REAL_TYPE;
213518334Speter
213618334Speter  /* If first arg is constant, swap the args (changing operation
213718334Speter     so value is preserved), for canonicalization.  Don't do this if
213818334Speter     the second arg is 0.  */
213918334Speter
214018334Speter  if (TREE_CONSTANT (primop0)
2141169699Skan      && !integer_zerop (primop1) && !real_zerop (primop1))
214218334Speter    {
214390082Sobrien      tree tem = primop0;
214490082Sobrien      int temi = unsignedp0;
214518334Speter      primop0 = primop1;
214618334Speter      primop1 = tem;
214718334Speter      tem = op0;
214818334Speter      op0 = op1;
214918334Speter      op1 = tem;
215018334Speter      *op0_ptr = op0;
215118334Speter      *op1_ptr = op1;
215218334Speter      unsignedp0 = unsignedp1;
215318334Speter      unsignedp1 = temi;
215418334Speter      temi = real1;
215518334Speter      real1 = real2;
215618334Speter      real2 = temi;
215718334Speter
215818334Speter      switch (code)
215918334Speter	{
216018334Speter	case LT_EXPR:
216118334Speter	  code = GT_EXPR;
216218334Speter	  break;
216318334Speter	case GT_EXPR:
216418334Speter	  code = LT_EXPR;
216518334Speter	  break;
216618334Speter	case LE_EXPR:
216718334Speter	  code = GE_EXPR;
216818334Speter	  break;
216918334Speter	case GE_EXPR:
217018334Speter	  code = LE_EXPR;
217118334Speter	  break;
217250449Sobrien	default:
217350449Sobrien	  break;
217418334Speter	}
217518334Speter      *rescode_ptr = code;
217618334Speter    }
217718334Speter
217818334Speter  /* If comparing an integer against a constant more bits wide,
217918334Speter     maybe we can deduce a value of 1 or 0 independent of the data.
218018334Speter     Or else truncate the constant now
218118334Speter     rather than extend the variable at run time.
218218334Speter
218318334Speter     This is only interesting if the constant is the wider arg.
218418334Speter     Also, it is not safe if the constant is unsigned and the
218518334Speter     variable arg is signed, since in this case the variable
218618334Speter     would be sign-extended and then regarded as unsigned.
218718334Speter     Our technique fails in this case because the lowest/highest
218818334Speter     possible unsigned results don't follow naturally from the
218918334Speter     lowest/highest possible values of the variable operand.
219018334Speter     For just EQ_EXPR and NE_EXPR there is another technique that
219118334Speter     could be used: see if the constant can be faithfully represented
219218334Speter     in the other operand's type, by truncating it and reextending it
219318334Speter     and see if that preserves the constant's value.  */
219418334Speter
219518334Speter  if (!real1 && !real2
219618334Speter      && TREE_CODE (primop1) == INTEGER_CST
219718334Speter      && TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (*restype_ptr))
219818334Speter    {
219918334Speter      int min_gt, max_gt, min_lt, max_lt;
220018334Speter      tree maxval, minval;
220118334Speter      /* 1 if comparison is nominally unsigned.  */
2202169699Skan      int unsignedp = TYPE_UNSIGNED (*restype_ptr);
220318334Speter      tree val;
220418334Speter
2205117404Skan      type = c_common_signed_or_unsigned_type (unsignedp0,
2206117404Skan					       TREE_TYPE (primop0));
220718334Speter
220818334Speter      maxval = TYPE_MAX_VALUE (type);
220918334Speter      minval = TYPE_MIN_VALUE (type);
221018334Speter
221118334Speter      if (unsignedp && !unsignedp0)
2212117404Skan	*restype_ptr = c_common_signed_type (*restype_ptr);
221318334Speter
221418334Speter      if (TREE_TYPE (primop1) != *restype_ptr)
2215169699Skan	{
2216169699Skan	  /* Convert primop1 to target type, but do not introduce
2217169699Skan	     additional overflow.  We know primop1 is an int_cst.  */
2218169699Skan	  tree tmp = build_int_cst_wide (*restype_ptr,
2219169699Skan					 TREE_INT_CST_LOW (primop1),
2220169699Skan					 TREE_INT_CST_HIGH (primop1));
2221169699Skan
2222169699Skan	  primop1 = force_fit_type (tmp, 0, TREE_OVERFLOW (primop1),
2223169699Skan				    TREE_CONSTANT_OVERFLOW (primop1));
2224169699Skan	}
222518334Speter      if (type != *restype_ptr)
222618334Speter	{
222718334Speter	  minval = convert (*restype_ptr, minval);
222818334Speter	  maxval = convert (*restype_ptr, maxval);
222918334Speter	}
223018334Speter
223118334Speter      if (unsignedp && unsignedp0)
223218334Speter	{
223318334Speter	  min_gt = INT_CST_LT_UNSIGNED (primop1, minval);
223418334Speter	  max_gt = INT_CST_LT_UNSIGNED (primop1, maxval);
223518334Speter	  min_lt = INT_CST_LT_UNSIGNED (minval, primop1);
223618334Speter	  max_lt = INT_CST_LT_UNSIGNED (maxval, primop1);
223718334Speter	}
223818334Speter      else
223918334Speter	{
224018334Speter	  min_gt = INT_CST_LT (primop1, minval);
224118334Speter	  max_gt = INT_CST_LT (primop1, maxval);
224218334Speter	  min_lt = INT_CST_LT (minval, primop1);
224318334Speter	  max_lt = INT_CST_LT (maxval, primop1);
224418334Speter	}
224518334Speter
224618334Speter      val = 0;
224718334Speter      /* This used to be a switch, but Genix compiler can't handle that.  */
224818334Speter      if (code == NE_EXPR)
224918334Speter	{
225018334Speter	  if (max_lt || min_gt)
2251132728Skan	    val = truthvalue_true_node;
225218334Speter	}
225318334Speter      else if (code == EQ_EXPR)
225418334Speter	{
225518334Speter	  if (max_lt || min_gt)
2256132728Skan	    val = truthvalue_false_node;
225718334Speter	}
225818334Speter      else if (code == LT_EXPR)
225918334Speter	{
226018334Speter	  if (max_lt)
2261132728Skan	    val = truthvalue_true_node;
226218334Speter	  if (!min_lt)
2263132728Skan	    val = truthvalue_false_node;
226418334Speter	}
226518334Speter      else if (code == GT_EXPR)
226618334Speter	{
226718334Speter	  if (min_gt)
2268132728Skan	    val = truthvalue_true_node;
226918334Speter	  if (!max_gt)
2270132728Skan	    val = truthvalue_false_node;
227118334Speter	}
227218334Speter      else if (code == LE_EXPR)
227318334Speter	{
227418334Speter	  if (!max_gt)
2275132728Skan	    val = truthvalue_true_node;
227618334Speter	  if (min_gt)
2277132728Skan	    val = truthvalue_false_node;
227818334Speter	}
227918334Speter      else if (code == GE_EXPR)
228018334Speter	{
228118334Speter	  if (!min_lt)
2282132728Skan	    val = truthvalue_true_node;
228318334Speter	  if (max_lt)
2284132728Skan	    val = truthvalue_false_node;
228518334Speter	}
228618334Speter
228718334Speter      /* If primop0 was sign-extended and unsigned comparison specd,
228818334Speter	 we did a signed comparison above using the signed type bounds.
228918334Speter	 But the comparison we output must be unsigned.
229018334Speter
229118334Speter	 Also, for inequalities, VAL is no good; but if the signed
229218334Speter	 comparison had *any* fixed result, it follows that the
229318334Speter	 unsigned comparison just tests the sign in reverse
229418334Speter	 (positive values are LE, negative ones GE).
229518334Speter	 So we can generate an unsigned comparison
229618334Speter	 against an extreme value of the signed type.  */
229718334Speter
229818334Speter      if (unsignedp && !unsignedp0)
229918334Speter	{
230018334Speter	  if (val != 0)
230118334Speter	    switch (code)
230218334Speter	      {
230318334Speter	      case LT_EXPR:
230418334Speter	      case GE_EXPR:
230518334Speter		primop1 = TYPE_MIN_VALUE (type);
230618334Speter		val = 0;
230718334Speter		break;
230818334Speter
230918334Speter	      case LE_EXPR:
231018334Speter	      case GT_EXPR:
231118334Speter		primop1 = TYPE_MAX_VALUE (type);
231218334Speter		val = 0;
231318334Speter		break;
231450449Sobrien
231550449Sobrien	      default:
231650449Sobrien		break;
231718334Speter	      }
2318117404Skan	  type = c_common_unsigned_type (type);
231918334Speter	}
232018334Speter
2321117404Skan      if (TREE_CODE (primop0) != INTEGER_CST)
232218334Speter	{
2323132728Skan	  if (val == truthvalue_false_node)
2324169699Skan	    warning (0, "comparison is always false due to limited range of data type");
2325132728Skan	  if (val == truthvalue_true_node)
2326169699Skan	    warning (0, "comparison is always true due to limited range of data type");
232718334Speter	}
232818334Speter
232918334Speter      if (val != 0)
233018334Speter	{
233118334Speter	  /* Don't forget to evaluate PRIMOP0 if it has side effects.  */
233218334Speter	  if (TREE_SIDE_EFFECTS (primop0))
2333169699Skan	    return build2 (COMPOUND_EXPR, TREE_TYPE (val), primop0, val);
233418334Speter	  return val;
233518334Speter	}
233618334Speter
233718334Speter      /* Value is not predetermined, but do the comparison
233818334Speter	 in the type of the operand that is not constant.
233918334Speter	 TYPE is already properly set.  */
234018334Speter    }
2341169699Skan
2342169699Skan  /* If either arg is decimal float and the other is float, find the
2343169699Skan     proper common type to use for comparison.  */
234418334Speter  else if (real1 && real2
2345169699Skan	   && (DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop0)))
2346169699Skan	       || DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop1)))))
2347169699Skan    type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1));
2348169699Skan
2349169699Skan  else if (real1 && real2
235018334Speter	   && (TYPE_PRECISION (TREE_TYPE (primop0))
235118334Speter	       == TYPE_PRECISION (TREE_TYPE (primop1))))
235218334Speter    type = TREE_TYPE (primop0);
235318334Speter
235418334Speter  /* If args' natural types are both narrower than nominal type
235518334Speter     and both extend in the same manner, compare them
235618334Speter     in the type of the wider arg.
235718334Speter     Otherwise must actually extend both to the nominal
235818334Speter     common type lest different ways of extending
235918334Speter     alter the result.
236018334Speter     (eg, (short)-1 == (unsigned short)-1  should be 0.)  */
236118334Speter
236218334Speter  else if (unsignedp0 == unsignedp1 && real1 == real2
236318334Speter	   && TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (*restype_ptr)
236418334Speter	   && TYPE_PRECISION (TREE_TYPE (primop1)) < TYPE_PRECISION (*restype_ptr))
236518334Speter    {
236618334Speter      type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1));
2367117404Skan      type = c_common_signed_or_unsigned_type (unsignedp0
2368169699Skan					       || TYPE_UNSIGNED (*restype_ptr),
2369117404Skan					       type);
237018334Speter      /* Make sure shorter operand is extended the right way
237118334Speter	 to match the longer operand.  */
2372117404Skan      primop0
2373117404Skan	= convert (c_common_signed_or_unsigned_type (unsignedp0,
2374117404Skan						     TREE_TYPE (primop0)),
2375117404Skan		   primop0);
2376117404Skan      primop1
2377117404Skan	= convert (c_common_signed_or_unsigned_type (unsignedp1,
2378117404Skan						     TREE_TYPE (primop1)),
2379117404Skan		   primop1);
238018334Speter    }
238118334Speter  else
238218334Speter    {
238318334Speter      /* Here we must do the comparison on the nominal type
238418334Speter	 using the args exactly as we received them.  */
238518334Speter      type = *restype_ptr;
238618334Speter      primop0 = op0;
238718334Speter      primop1 = op1;
238818334Speter
238918334Speter      if (!real1 && !real2 && integer_zerop (primop1)
2390169699Skan	  && TYPE_UNSIGNED (*restype_ptr))
239118334Speter	{
239218334Speter	  tree value = 0;
239318334Speter	  switch (code)
239418334Speter	    {
239518334Speter	    case GE_EXPR:
239618334Speter	      /* All unsigned values are >= 0, so we warn if extra warnings
239718334Speter		 are requested.  However, if OP0 is a constant that is
239818334Speter		 >= 0, the signedness of the comparison isn't an issue,
239918334Speter		 so suppress the warning.  */
240090082Sobrien	      if (extra_warnings && !in_system_header
2401169699Skan		  && !(TREE_CODE (primop0) == INTEGER_CST
2402169699Skan		       && !TREE_OVERFLOW (convert (c_common_signed_type (type),
2403169699Skan						   primop0))))
2404169699Skan		warning (0, "comparison of unsigned expression >= 0 is always true");
2405132728Skan	      value = truthvalue_true_node;
240618334Speter	      break;
240718334Speter
240818334Speter	    case LT_EXPR:
240990082Sobrien	      if (extra_warnings && !in_system_header
2410169699Skan		  && !(TREE_CODE (primop0) == INTEGER_CST
2411169699Skan		       && !TREE_OVERFLOW (convert (c_common_signed_type (type),
2412169699Skan						   primop0))))
2413169699Skan		warning (0, "comparison of unsigned expression < 0 is always false");
2414132728Skan	      value = truthvalue_false_node;
241550449Sobrien	      break;
241650449Sobrien
241750449Sobrien	    default:
241850449Sobrien	      break;
241918334Speter	    }
242018334Speter
242118334Speter	  if (value != 0)
242218334Speter	    {
242318334Speter	      /* Don't forget to evaluate PRIMOP0 if it has side effects.  */
242418334Speter	      if (TREE_SIDE_EFFECTS (primop0))
2425169699Skan		return build2 (COMPOUND_EXPR, TREE_TYPE (value),
2426169699Skan			       primop0, value);
242718334Speter	      return value;
242818334Speter	    }
242918334Speter	}
243018334Speter    }
243118334Speter
243218334Speter  *op0_ptr = convert (type, primop0);
243318334Speter  *op1_ptr = convert (type, primop1);
243418334Speter
2435132728Skan  *restype_ptr = truthvalue_type_node;
243618334Speter
243718334Speter  return 0;
243818334Speter}
243918334Speter
244096275Sobrien/* Return a tree for the sum or difference (RESULTCODE says which)
244196275Sobrien   of pointer PTROP and integer INTOP.  */
244296275Sobrien
244396275Sobrientree
2444132728Skanpointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
244596275Sobrien{
2446169699Skan  tree size_exp, ret;
244796275Sobrien
244896275Sobrien  /* The result is a pointer of the same type that is being added.  */
244996275Sobrien
245096275Sobrien  tree result_type = TREE_TYPE (ptrop);
245196275Sobrien
245296275Sobrien  if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
245396275Sobrien    {
245496275Sobrien      if (pedantic || warn_pointer_arith)
2455169699Skan	pedwarn ("pointer of type %<void *%> used in arithmetic");
245696275Sobrien      size_exp = integer_one_node;
245796275Sobrien    }
245896275Sobrien  else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
245996275Sobrien    {
246096275Sobrien      if (pedantic || warn_pointer_arith)
246196275Sobrien	pedwarn ("pointer to a function used in arithmetic");
246296275Sobrien      size_exp = integer_one_node;
246396275Sobrien    }
246496275Sobrien  else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE)
246596275Sobrien    {
246696275Sobrien      if (pedantic || warn_pointer_arith)
246796275Sobrien	pedwarn ("pointer to member function used in arithmetic");
246896275Sobrien      size_exp = integer_one_node;
246996275Sobrien    }
247096275Sobrien  else
247196275Sobrien    size_exp = size_in_bytes (TREE_TYPE (result_type));
247296275Sobrien
2473169699Skan  /* We are manipulating pointer values, so we don't need to warn
2474169699Skan     about relying on undefined signed overflow.  We disable the
2475169699Skan     warning here because we use integer types so fold won't know that
2476169699Skan     they are really pointers.  */
2477169699Skan  fold_defer_overflow_warnings ();
2478169699Skan
247996275Sobrien  /* If what we are about to multiply by the size of the elements
248096275Sobrien     contains a constant term, apply distributive law
248196275Sobrien     and multiply that constant term separately.
248296275Sobrien     This helps produce common subexpressions.  */
248396275Sobrien
248496275Sobrien  if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR)
2485169699Skan      && !TREE_CONSTANT (intop)
248696275Sobrien      && TREE_CONSTANT (TREE_OPERAND (intop, 1))
248796275Sobrien      && TREE_CONSTANT (size_exp)
248896275Sobrien      /* If the constant comes from pointer subtraction,
248996275Sobrien	 skip this optimization--it would cause an error.  */
249096275Sobrien      && TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE
249196275Sobrien      /* If the constant is unsigned, and smaller than the pointer size,
249296275Sobrien	 then we must skip this optimization.  This is because it could cause
249396275Sobrien	 an overflow error if the constant is negative but INTOP is not.  */
2494169699Skan      && (!TYPE_UNSIGNED (TREE_TYPE (intop))
249596275Sobrien	  || (TYPE_PRECISION (TREE_TYPE (intop))
249696275Sobrien	      == TYPE_PRECISION (TREE_TYPE (ptrop)))))
249796275Sobrien    {
249896275Sobrien      enum tree_code subcode = resultcode;
249996275Sobrien      tree int_type = TREE_TYPE (intop);
250096275Sobrien      if (TREE_CODE (intop) == MINUS_EXPR)
250196275Sobrien	subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR);
250296275Sobrien      /* Convert both subexpression types to the type of intop,
250396275Sobrien	 because weird cases involving pointer arithmetic
250496275Sobrien	 can result in a sum or difference with different type args.  */
250596275Sobrien      ptrop = build_binary_op (subcode, ptrop,
250696275Sobrien			       convert (int_type, TREE_OPERAND (intop, 1)), 1);
250796275Sobrien      intop = convert (int_type, TREE_OPERAND (intop, 0));
250896275Sobrien    }
250996275Sobrien
251096275Sobrien  /* Convert the integer argument to a type the same size as sizetype
251196275Sobrien     so the multiply won't overflow spuriously.  */
251296275Sobrien
251396275Sobrien  if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
2514169699Skan      || TYPE_UNSIGNED (TREE_TYPE (intop)) != TYPE_UNSIGNED (sizetype))
2515132728Skan    intop = convert (c_common_type_for_size (TYPE_PRECISION (sizetype),
2516169699Skan					     TYPE_UNSIGNED (sizetype)), intop);
251796275Sobrien
251896275Sobrien  /* Replace the integer argument with a suitable product by the object size.
251996275Sobrien     Do this multiplication as signed, then convert to the appropriate
252096275Sobrien     pointer type (actually unsigned integral).  */
252196275Sobrien
252296275Sobrien  intop = convert (result_type,
252396275Sobrien		   build_binary_op (MULT_EXPR, intop,
252496275Sobrien				    convert (TREE_TYPE (intop), size_exp), 1));
252596275Sobrien
252696275Sobrien  /* Create the sum or difference.  */
2527169699Skan  ret = fold_build2 (resultcode, result_type, ptrop, intop);
252896275Sobrien
2529169699Skan  fold_undefer_and_ignore_overflow_warnings ();
253096275Sobrien
2531169699Skan  return ret;
253296275Sobrien}
253396275Sobrien
253418334Speter/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
2535169699Skan   or for an `if' or `while' statement or ?..: exp.  It should already
2536169699Skan   have been validated to be of suitable type; otherwise, a bad
2537169699Skan   diagnostic may result.
253818334Speter
253918334Speter   This preparation consists of taking the ordinary
254018334Speter   representation of an expression expr and producing a valid tree
254118334Speter   boolean expression describing whether expr is nonzero.  We could
2542132728Skan   simply always do build_binary_op (NE_EXPR, expr, truthvalue_false_node, 1),
254318334Speter   but we optimize comparisons, &&, ||, and !.
254418334Speter
2545132728Skan   The resulting type should always be `truthvalue_type_node'.  */
254618334Speter
254718334Spetertree
2548132728Skanc_common_truthvalue_conversion (tree expr)
254918334Speter{
2550169699Skan  switch (TREE_CODE (expr))
255118334Speter    {
2552169699Skan    case EQ_EXPR:   case NE_EXPR:   case UNEQ_EXPR: case LTGT_EXPR:
2553169699Skan    case LE_EXPR:   case GE_EXPR:   case LT_EXPR:   case GT_EXPR:
2554169699Skan    case UNLE_EXPR: case UNGE_EXPR: case UNLT_EXPR: case UNGT_EXPR:
2555169699Skan    case ORDERED_EXPR: case UNORDERED_EXPR:
2556169699Skan      if (TREE_TYPE (expr) == truthvalue_type_node)
2557169699Skan	return expr;
2558169699Skan      return build2 (TREE_CODE (expr), truthvalue_type_node,
2559169699Skan		     TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
256018334Speter
256118334Speter    case TRUTH_ANDIF_EXPR:
256218334Speter    case TRUTH_ORIF_EXPR:
256318334Speter    case TRUTH_AND_EXPR:
256418334Speter    case TRUTH_OR_EXPR:
256518334Speter    case TRUTH_XOR_EXPR:
2566169699Skan      if (TREE_TYPE (expr) == truthvalue_type_node)
2567169699Skan	return expr;
2568169699Skan      return build2 (TREE_CODE (expr), truthvalue_type_node,
2569169699Skan		 c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)),
2570169699Skan		 c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)));
2571169699Skan
257218334Speter    case TRUTH_NOT_EXPR:
2573169699Skan      if (TREE_TYPE (expr) == truthvalue_type_node)
2574169699Skan	return expr;
2575169699Skan      return build1 (TREE_CODE (expr), truthvalue_type_node,
2576169699Skan		 c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)));
257718334Speter
257818334Speter    case ERROR_MARK:
257918334Speter      return expr;
258018334Speter
258118334Speter    case INTEGER_CST:
2582169699Skan      /* Avoid integer_zerop to ignore TREE_CONSTANT_OVERFLOW.  */
2583169699Skan      return (TREE_INT_CST_LOW (expr) != 0 || TREE_INT_CST_HIGH (expr) != 0)
2584169699Skan	     ? truthvalue_true_node
2585169699Skan	     : truthvalue_false_node;
258618334Speter
258718334Speter    case REAL_CST:
2588169699Skan      return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0)
2589169699Skan	     ? truthvalue_true_node
2590169699Skan	     : truthvalue_false_node;
259118334Speter
2592169699Skan    case FUNCTION_DECL:
2593169699Skan      expr = build_unary_op (ADDR_EXPR, expr, 0);
2594169699Skan      /* Fall through.  */
2595169699Skan
259618334Speter    case ADDR_EXPR:
2597132728Skan      {
2598169699Skan 	tree inner = TREE_OPERAND (expr, 0);
2599169699Skan	if (DECL_P (inner)
2600169699Skan	    && (TREE_CODE (inner) == PARM_DECL
2601169699Skan		|| TREE_CODE (inner) == LABEL_DECL
2602169699Skan		|| !DECL_WEAK (inner)))
2603132728Skan	  {
2604169699Skan            /* Common Ada/Pascal programmer's mistake.  We always warn
2605132728Skan	       about this since it is so bad.  */
2606169699Skan	    warning (OPT_Waddress,
2607169699Skan		     "the address of %qD will always evaluate as %<true%>",
2608169699Skan		     inner);
2609132728Skan	    return truthvalue_true_node;
2610132728Skan	  }
261150449Sobrien
2612132728Skan	/* If we are taking the address of an external decl, it might be
2613132728Skan	   zero if it is weak, so we cannot optimize.  */
2614169699Skan	if (DECL_P (inner)
2615169699Skan	    && DECL_EXTERNAL (inner))
2616132728Skan	  break;
261718334Speter
2618169699Skan	if (TREE_SIDE_EFFECTS (inner))
2619169699Skan	  return build2 (COMPOUND_EXPR, truthvalue_type_node,
2620169699Skan			 inner, truthvalue_true_node);
2621132728Skan	else
2622132728Skan	  return truthvalue_true_node;
2623132728Skan      }
2624132728Skan
262518334Speter    case COMPLEX_EXPR:
262618334Speter      return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
262718334Speter			       ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
2628117404Skan		c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)),
2629117404Skan		c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)),
263018334Speter			      0);
263118334Speter
263218334Speter    case NEGATE_EXPR:
263318334Speter    case ABS_EXPR:
263418334Speter    case FLOAT_EXPR:
2635117404Skan      /* These don't change whether an object is nonzero or zero.  */
2636117404Skan      return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
263718334Speter
263818334Speter    case LROTATE_EXPR:
263918334Speter    case RROTATE_EXPR:
2640117404Skan      /* These don't change whether an object is zero or nonzero, but
264118334Speter	 we can't ignore them if their second arg has side-effects.  */
264218334Speter      if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
2643169699Skan	return build2 (COMPOUND_EXPR, truthvalue_type_node,
2644169699Skan		       TREE_OPERAND (expr, 1),
2645169699Skan		       c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)));
264618334Speter      else
2647117404Skan	return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
264850449Sobrien
264918334Speter    case COND_EXPR:
265018334Speter      /* Distribute the conversion into the arms of a COND_EXPR.  */
2651169699Skan      return fold_build3 (COND_EXPR, truthvalue_type_node,
2652169699Skan		TREE_OPERAND (expr, 0),
2653117404Skan		c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)),
2654169699Skan		c_common_truthvalue_conversion (TREE_OPERAND (expr, 2)));
265518334Speter
265618334Speter    case CONVERT_EXPR:
2657169699Skan    case NOP_EXPR:
265818334Speter      /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
265918334Speter	 since that affects how `default_conversion' will behave.  */
266018334Speter      if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
266118334Speter	  || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
266218334Speter	break;
266318334Speter      /* If this is widening the argument, we can ignore it.  */
266418334Speter      if (TYPE_PRECISION (TREE_TYPE (expr))
266518334Speter	  >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
2666117404Skan	return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
266718334Speter      break;
266818334Speter
266918334Speter    case MODIFY_EXPR:
2670259268Spfg      if (!TREE_NO_WARNING (expr)
2671259268Spfg	  && warn_parentheses)
2672259268Spfg	{
2673259268Spfg	  warning (OPT_Wparentheses,
2674259268Spfg		   "suggest parentheses around assignment used as truth value");
2675259268Spfg	  TREE_NO_WARNING (expr) = 1;
2676259268Spfg	}
267718334Speter      break;
267850449Sobrien
267950449Sobrien    default:
268050449Sobrien      break;
268118334Speter    }
268218334Speter
268318334Speter  if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
268450449Sobrien    {
2685117404Skan      tree t = save_expr (expr);
268650449Sobrien      return (build_binary_op
268750449Sobrien	      ((TREE_SIDE_EFFECTS (expr)
268850449Sobrien		? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
2689117404Skan	c_common_truthvalue_conversion (build_unary_op (REALPART_EXPR, t, 0)),
2690117404Skan	c_common_truthvalue_conversion (build_unary_op (IMAGPART_EXPR, t, 0)),
269150449Sobrien	       0));
269250449Sobrien    }
269318334Speter
269418334Speter  return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
269518334Speter}
269618334Speter
2697169699Skanstatic void def_builtin_1  (enum built_in_function fncode,
2698169699Skan			    const char *name,
2699169699Skan			    enum built_in_class fnclass,
2700169699Skan			    tree fntype, tree libtype,
2701169699Skan			    bool both_p, bool fallback_p, bool nonansi_p,
2702169699Skan			    tree fnattrs, bool implicit_p);
270318334Speter
270490082Sobrien/* Make a variant type in the proper way for C/C++, propagating qualifiers
270590082Sobrien   down to the element type of an array.  */
270618334Speter
270790082Sobrientree
2708132728Skanc_build_qualified_type (tree type, int type_quals)
270990082Sobrien{
2710132728Skan  if (type == error_mark_node)
2711132728Skan    return type;
2712169699Skan
2713132728Skan  if (TREE_CODE (type) == ARRAY_TYPE)
2714169699Skan    {
2715169699Skan      tree t;
2716169699Skan      tree element_type = c_build_qualified_type (TREE_TYPE (type),
2717169699Skan						  type_quals);
2718132728Skan
2719169699Skan      /* See if we already have an identically qualified type.  */
2720169699Skan      for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
2721169699Skan	{
2722169699Skan	  if (TYPE_QUALS (strip_array_types (t)) == type_quals
2723169699Skan	      && TYPE_NAME (t) == TYPE_NAME (type)
2724169699Skan	      && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
2725169699Skan	      && attribute_list_equal (TYPE_ATTRIBUTES (t),
2726169699Skan				       TYPE_ATTRIBUTES (type)))
2727169699Skan	    break;
2728169699Skan	}
2729169699Skan      if (!t)
2730169699Skan	{
2731169699Skan	  t = build_variant_type_copy (type);
2732169699Skan	  TREE_TYPE (t) = element_type;
2733169699Skan	}
2734169699Skan      return t;
2735169699Skan    }
2736169699Skan
273790082Sobrien  /* A restrict-qualified pointer type must be a pointer to object or
273890082Sobrien     incomplete type.  Note that the use of POINTER_TYPE_P also allows
2739132728Skan     REFERENCE_TYPEs, which is appropriate for C++.  */
274090082Sobrien  if ((type_quals & TYPE_QUAL_RESTRICT)
274190082Sobrien      && (!POINTER_TYPE_P (type)
274290082Sobrien	  || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
274390082Sobrien    {
2744169699Skan      error ("invalid use of %<restrict%>");
274590082Sobrien      type_quals &= ~TYPE_QUAL_RESTRICT;
274690082Sobrien    }
274750449Sobrien
274890082Sobrien  return build_qualified_type (type, type_quals);
274990082Sobrien}
275090082Sobrien
275190082Sobrien/* Apply the TYPE_QUALS to the new DECL.  */
275290082Sobrien
275390082Sobrienvoid
2754132728Skanc_apply_type_quals_to_decl (int type_quals, tree decl)
275550449Sobrien{
2756132728Skan  tree type = TREE_TYPE (decl);
2757169699Skan
2758132728Skan  if (type == error_mark_node)
2759132728Skan    return;
2760132728Skan
2761132728Skan  if (((type_quals & TYPE_QUAL_CONST)
2762132728Skan       || (type && TREE_CODE (type) == REFERENCE_TYPE))
2763132728Skan      /* An object declared 'const' is only readonly after it is
2764132728Skan	 initialized.  We don't have any way of expressing this currently,
2765132728Skan	 so we need to be conservative and unset TREE_READONLY for types
2766132728Skan	 with constructors.  Otherwise aliasing code will ignore stores in
2767132728Skan	 an inline constructor.  */
2768132728Skan      && !(type && TYPE_NEEDS_CONSTRUCTING (type)))
276990082Sobrien    TREE_READONLY (decl) = 1;
277090082Sobrien  if (type_quals & TYPE_QUAL_VOLATILE)
277150449Sobrien    {
277290082Sobrien      TREE_SIDE_EFFECTS (decl) = 1;
277390082Sobrien      TREE_THIS_VOLATILE (decl) = 1;
277450449Sobrien    }
277590082Sobrien  if (type_quals & TYPE_QUAL_RESTRICT)
277690082Sobrien    {
2777132728Skan      while (type && TREE_CODE (type) == ARRAY_TYPE)
2778132728Skan	/* Allow 'restrict' on arrays of pointers.
2779132728Skan	   FIXME currently we just ignore it.  */
2780132728Skan	type = TREE_TYPE (type);
2781132728Skan      if (!type
2782132728Skan	  || !POINTER_TYPE_P (type)
2783132728Skan	  || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type)))
2784169699Skan	error ("invalid use of %<restrict%>");
2785132728Skan      else if (flag_strict_aliasing && type == TREE_TYPE (decl))
278690082Sobrien	/* Indicate we need to make a unique alias set for this pointer.
278790082Sobrien	   We can't do it here because it might be pointing to an
278890082Sobrien	   incomplete type.  */
278990082Sobrien	DECL_POINTER_ALIAS_SET (decl) = -2;
279090082Sobrien    }
279150449Sobrien}
279250449Sobrien
2793169699Skan/* Hash function for the problem of multiple type definitions in
2794169699Skan   different files.  This must hash all types that will compare
2795169699Skan   equal via comptypes to the same value.  In practice it hashes
2796169699Skan   on some of the simple stuff and leaves the details to comptypes.  */
2797169699Skan
2798169699Skanstatic hashval_t
2799169699Skanc_type_hash (const void *p)
2800169699Skan{
2801169699Skan  int i = 0;
2802169699Skan  int shift, size;
2803169699Skan  tree t = (tree) p;
2804169699Skan  tree t2;
2805169699Skan  switch (TREE_CODE (t))
2806169699Skan    {
2807169699Skan    /* For pointers, hash on pointee type plus some swizzling.  */
2808169699Skan    case POINTER_TYPE:
2809169699Skan      return c_type_hash (TREE_TYPE (t)) ^ 0x3003003;
2810169699Skan    /* Hash on number of elements and total size.  */
2811169699Skan    case ENUMERAL_TYPE:
2812169699Skan      shift = 3;
2813169699Skan      t2 = TYPE_VALUES (t);
2814169699Skan      break;
2815169699Skan    case RECORD_TYPE:
2816169699Skan      shift = 0;
2817169699Skan      t2 = TYPE_FIELDS (t);
2818169699Skan      break;
2819169699Skan    case QUAL_UNION_TYPE:
2820169699Skan      shift = 1;
2821169699Skan      t2 = TYPE_FIELDS (t);
2822169699Skan      break;
2823169699Skan    case UNION_TYPE:
2824169699Skan      shift = 2;
2825169699Skan      t2 = TYPE_FIELDS (t);
2826169699Skan      break;
2827169699Skan    default:
2828169699Skan      gcc_unreachable ();
2829169699Skan    }
2830169699Skan  for (; t2; t2 = TREE_CHAIN (t2))
2831169699Skan    i++;
2832169699Skan  size = TREE_INT_CST_LOW (TYPE_SIZE (t));
2833169699Skan  return ((size << 24) | (i << shift));
2834169699Skan}
2835169699Skan
2836169699Skanstatic GTY((param_is (union tree_node))) htab_t type_hash_table;
2837169699Skan
283890082Sobrien/* Return the typed-based alias set for T, which may be an expression
283990082Sobrien   or a type.  Return -1 if we don't do anything special.  */
284090082Sobrien
284190082SobrienHOST_WIDE_INT
2842132728Skanc_common_get_alias_set (tree t)
284350449Sobrien{
284490082Sobrien  tree u;
2845169699Skan  PTR *slot;
2846132728Skan
284790082Sobrien  /* Permit type-punning when accessing a union, provided the access
284890082Sobrien     is directly through the union.  For example, this code does not
284990082Sobrien     permit taking the address of a union member and then storing
285090082Sobrien     through it.  Even the type-punning allowed here is a GCC
285190082Sobrien     extension, albeit a common and useful one; the C standard says
285290082Sobrien     that such accesses have implementation-defined behavior.  */
285390082Sobrien  for (u = t;
285490082Sobrien       TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
285590082Sobrien       u = TREE_OPERAND (u, 0))
285690082Sobrien    if (TREE_CODE (u) == COMPONENT_REF
285790082Sobrien	&& TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
285890082Sobrien      return 0;
285950449Sobrien
286090082Sobrien  /* That's all the expressions we handle specially.  */
2861169699Skan  if (!TYPE_P (t))
286290082Sobrien    return -1;
286390082Sobrien
2864132728Skan  /* The C standard guarantees that any object may be accessed via an
2865102798Skan     lvalue that has character type.  */
2866102798Skan  if (t == char_type_node
2867102798Skan      || t == signed_char_type_node
2868102798Skan      || t == unsigned_char_type_node)
2869102798Skan    return 0;
2870117404Skan
2871117404Skan  /* If it has the may_alias attribute, it can alias anything.  */
2872117404Skan  if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (t)))
2873117404Skan    return 0;
2874117404Skan
287590082Sobrien  /* The C standard specifically allows aliasing between signed and
287690082Sobrien     unsigned variants of the same type.  We treat the signed
287790082Sobrien     variant as canonical.  */
2878169699Skan  if (TREE_CODE (t) == INTEGER_TYPE && TYPE_UNSIGNED (t))
287950449Sobrien    {
2880117404Skan      tree t1 = c_common_signed_type (t);
288190082Sobrien
288290082Sobrien      /* t1 == t can happen for boolean nodes which are always unsigned.  */
288390082Sobrien      if (t1 != t)
288490082Sobrien	return get_alias_set (t1);
288550449Sobrien    }
288690082Sobrien  else if (POINTER_TYPE_P (t))
288790082Sobrien    {
288890082Sobrien      tree t1;
288950449Sobrien
289090082Sobrien      /* Unfortunately, there is no canonical form of a pointer type.
289190082Sobrien	 In particular, if we have `typedef int I', then `int *', and
289290082Sobrien	 `I *' are different types.  So, we have to pick a canonical
289390082Sobrien	 representative.  We do this below.
289450449Sobrien
289590082Sobrien	 Technically, this approach is actually more conservative that
289690082Sobrien	 it needs to be.  In particular, `const int *' and `int *'
289790082Sobrien	 should be in different alias sets, according to the C and C++
289890082Sobrien	 standard, since their types are not the same, and so,
289990082Sobrien	 technically, an `int **' and `const int **' cannot point at
290090082Sobrien	 the same thing.
290190082Sobrien
2902169699Skan	 But, the standard is wrong.  In particular, this code is
290390082Sobrien	 legal C++:
290490082Sobrien
2905169699Skan	    int *ip;
2906169699Skan	    int **ipp = &ip;
2907169699Skan	    const int* const* cipp = ipp;
290890082Sobrien
2909169699Skan	 And, it doesn't make sense for that to be legal unless you
291090082Sobrien	 can dereference IPP and CIPP.  So, we ignore cv-qualifiers on
291190082Sobrien	 the pointed-to types.  This issue has been reported to the
291290082Sobrien	 C++ committee.  */
291390082Sobrien      t1 = build_type_no_quals (t);
291490082Sobrien      if (t1 != t)
291590082Sobrien	return get_alias_set (t1);
291690082Sobrien    }
291790082Sobrien
2918169699Skan  /* Handle the case of multiple type nodes referring to "the same" type,
2919169699Skan     which occurs with IMA.  These share an alias set.  FIXME:  Currently only
2920169699Skan     C90 is handled.  (In C99 type compatibility is not transitive, which
2921169699Skan     complicates things mightily. The alias set splay trees can theoretically
2922169699Skan     represent this, but insertion is tricky when you consider all the
2923169699Skan     different orders things might arrive in.) */
2924169699Skan
2925169699Skan  if (c_language != clk_c || flag_isoc99)
2926169699Skan    return -1;
2927169699Skan
2928169699Skan  /* Save time if there's only one input file.  */
2929169699Skan  if (num_in_fnames == 1)
2930169699Skan    return -1;
2931169699Skan
2932169699Skan  /* Pointers need special handling if they point to any type that
2933169699Skan     needs special handling (below).  */
2934169699Skan  if (TREE_CODE (t) == POINTER_TYPE)
2935169699Skan    {
2936169699Skan      tree t2;
2937169699Skan      /* Find bottom type under any nested POINTERs.  */
2938169699Skan      for (t2 = TREE_TYPE (t);
2939169699Skan     TREE_CODE (t2) == POINTER_TYPE;
2940169699Skan     t2 = TREE_TYPE (t2))
2941169699Skan  ;
2942169699Skan      if (TREE_CODE (t2) != RECORD_TYPE
2943169699Skan    && TREE_CODE (t2) != ENUMERAL_TYPE
2944169699Skan    && TREE_CODE (t2) != QUAL_UNION_TYPE
2945169699Skan    && TREE_CODE (t2) != UNION_TYPE)
294690082Sobrien  return -1;
2947169699Skan      if (TYPE_SIZE (t2) == 0)
2948169699Skan  return -1;
2949169699Skan    }
2950169699Skan  /* These are the only cases that need special handling.  */
2951169699Skan  if (TREE_CODE (t) != RECORD_TYPE
2952169699Skan      && TREE_CODE (t) != ENUMERAL_TYPE
2953169699Skan      && TREE_CODE (t) != QUAL_UNION_TYPE
2954169699Skan      && TREE_CODE (t) != UNION_TYPE
2955169699Skan      && TREE_CODE (t) != POINTER_TYPE)
2956169699Skan    return -1;
2957169699Skan  /* Undefined? */
2958169699Skan  if (TYPE_SIZE (t) == 0)
2959169699Skan    return -1;
2960169699Skan
2961169699Skan  /* Look up t in hash table.  Only one of the compatible types within each
2962169699Skan     alias set is recorded in the table.  */
2963169699Skan  if (!type_hash_table)
2964169699Skan    type_hash_table = htab_create_ggc (1021, c_type_hash,
2965169699Skan	    (htab_eq) lang_hooks.types_compatible_p,
2966169699Skan	    NULL);
2967169699Skan  slot = htab_find_slot (type_hash_table, t, INSERT);
2968169699Skan  if (*slot != NULL)
2969169699Skan    {
2970169699Skan      TYPE_ALIAS_SET (t) = TYPE_ALIAS_SET ((tree)*slot);
2971169699Skan      return TYPE_ALIAS_SET ((tree)*slot);
2972169699Skan    }
2973169699Skan  else
2974169699Skan    /* Our caller will assign and record (in t) a new alias set; all we need
2975169699Skan       to do is remember t in the hash table.  */
2976169699Skan    *slot = t;
2977169699Skan
2978169699Skan  return -1;
297990082Sobrien}
298090082Sobrien
2981117404Skan/* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where the
2982117404Skan   second parameter indicates which OPERATOR is being applied.  The COMPLAIN
2983117404Skan   flag controls whether we should diagnose possibly ill-formed
2984117404Skan   constructs or not.  */
2985169699Skan
298690082Sobrientree
2987169699Skanc_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
298890082Sobrien{
2989117404Skan  const char *op_name;
2990117404Skan  tree value = NULL;
2991117404Skan  enum tree_code type_code = TREE_CODE (type);
2992132728Skan
2993169699Skan  op_name = is_sizeof ? "sizeof" : "__alignof__";
2994132728Skan
2995117404Skan  if (type_code == FUNCTION_TYPE)
299650449Sobrien    {
2997169699Skan      if (is_sizeof)
2998117404Skan	{
2999117404Skan	  if (complain && (pedantic || warn_pointer_arith))
3000169699Skan	    pedwarn ("invalid application of %<sizeof%> to a function type");
3001117404Skan	  value = size_one_node;
3002117404Skan	}
3003117404Skan      else
3004117404Skan	value = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
300590082Sobrien    }
3006117404Skan  else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
3007117404Skan    {
3008132728Skan      if (type_code == VOID_TYPE
3009117404Skan	  && complain && (pedantic || warn_pointer_arith))
3010169699Skan	pedwarn ("invalid application of %qs to a void type", op_name);
3011117404Skan      value = size_one_node;
3012117404Skan    }
301390082Sobrien  else if (!COMPLETE_TYPE_P (type))
301490082Sobrien    {
3015117404Skan      if (complain)
3016169699Skan	error ("invalid application of %qs to incomplete type %qT ",
3017132728Skan	       op_name, type);
3018117404Skan      value = size_zero_node;
301990082Sobrien    }
302090082Sobrien  else
3021117404Skan    {
3022169699Skan      if (is_sizeof)
3023117404Skan	/* Convert in case a char is more than one unit.  */
3024117404Skan	value = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
3025117404Skan			    size_int (TYPE_PRECISION (char_type_node)
3026117404Skan				      / BITS_PER_UNIT));
3027117404Skan      else
3028169699Skan	value = size_int (TYPE_ALIGN_UNIT (type));
3029117404Skan    }
303050449Sobrien
3031117404Skan  /* VALUE will have an integer type with TYPE_IS_SIZETYPE set.
3032117404Skan     TYPE_IS_SIZETYPE means that certain things (like overflow) will
3033117404Skan     never happen.  However, this node should really have type
3034117404Skan     `size_t', which is just a typedef for an ordinary integer type.  */
3035169699Skan  value = fold_convert (size_type_node, value);
3036169699Skan  gcc_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (value)));
3037132728Skan
3038117404Skan  return value;
303990082Sobrien}
304050449Sobrien
304190082Sobrien/* Implement the __alignof keyword: Return the minimum required
3042259694Spfg   alignment of EXPR, measured in bytes.  For VAR_DECLs,
3043259694Spfg   FUNCTION_DECLs and FIELD_DECLs return DECL_ALIGN (which can be set
3044259694Spfg   from an "aligned" __attribute__ specification).  */
304550449Sobrien
304690082Sobrientree
3047132728Skanc_alignof_expr (tree expr)
304890082Sobrien{
304990082Sobrien  tree t;
305050449Sobrien
3051259694Spfg  if (VAR_OR_FUNCTION_DECL_P (expr))
3052169699Skan    t = size_int (DECL_ALIGN_UNIT (expr));
3053132728Skan
305490082Sobrien  else if (TREE_CODE (expr) == COMPONENT_REF
305590082Sobrien	   && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
305690082Sobrien    {
3057169699Skan      error ("%<__alignof%> applied to a bit-field");
305890082Sobrien      t = size_one_node;
305990082Sobrien    }
306090082Sobrien  else if (TREE_CODE (expr) == COMPONENT_REF
306190082Sobrien	   && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL)
3062169699Skan    t = size_int (DECL_ALIGN_UNIT (TREE_OPERAND (expr, 1)));
3063132728Skan
306490082Sobrien  else if (TREE_CODE (expr) == INDIRECT_REF)
306590082Sobrien    {
306690082Sobrien      tree t = TREE_OPERAND (expr, 0);
306790082Sobrien      tree best = t;
306890082Sobrien      int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
3069132728Skan
3070169699Skan      while ((TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR)
307190082Sobrien	     && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
307250449Sobrien	{
307390082Sobrien	  int thisalign;
307490082Sobrien
307590082Sobrien	  t = TREE_OPERAND (t, 0);
307690082Sobrien	  thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
307790082Sobrien	  if (thisalign > bestalign)
307890082Sobrien	    best = t, bestalign = thisalign;
307950449Sobrien	}
308090082Sobrien      return c_alignof (TREE_TYPE (TREE_TYPE (best)));
308190082Sobrien    }
308290082Sobrien  else
308390082Sobrien    return c_alignof (TREE_TYPE (expr));
308450449Sobrien
3085169699Skan  return fold_convert (size_type_node, t);
308690082Sobrien}
308790082Sobrien
3088117404Skan/* Handle C and C++ default attributes.  */
308950449Sobrien
3090117404Skanenum built_in_attribute
309190082Sobrien{
3092117404Skan#define DEF_ATTR_NULL_TREE(ENUM) ENUM,
3093117404Skan#define DEF_ATTR_INT(ENUM, VALUE) ENUM,
3094117404Skan#define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
3095117404Skan#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
3096117404Skan#include "builtin-attrs.def"
3097117404Skan#undef DEF_ATTR_NULL_TREE
3098117404Skan#undef DEF_ATTR_INT
3099117404Skan#undef DEF_ATTR_IDENT
3100117404Skan#undef DEF_ATTR_TREE_LIST
3101117404Skan  ATTR_LAST
310290082Sobrien};
310350449Sobrien
3104117404Skanstatic GTY(()) tree built_in_attributes[(int) ATTR_LAST];
3105117404Skan
3106132728Skanstatic void c_init_attributes (void);
3107117404Skan
3108169699Skanenum c_builtin_type
310990082Sobrien{
311090082Sobrien#define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
311190082Sobrien#define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
311290082Sobrien#define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
311390082Sobrien#define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
311490082Sobrien#define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
311590082Sobrien#define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
3116169699Skan#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
3117169699Skan#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) NAME,
3118169699Skan#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) NAME,
311990082Sobrien#define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
312090082Sobrien#define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
312190082Sobrien#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
3122117404Skan#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
3123169699Skan#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
3124169699Skan#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \
3125169699Skan  NAME,
312690082Sobrien#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
312790082Sobrien#include "builtin-types.def"
312890082Sobrien#undef DEF_PRIMITIVE_TYPE
312990082Sobrien#undef DEF_FUNCTION_TYPE_0
313090082Sobrien#undef DEF_FUNCTION_TYPE_1
313190082Sobrien#undef DEF_FUNCTION_TYPE_2
313290082Sobrien#undef DEF_FUNCTION_TYPE_3
313390082Sobrien#undef DEF_FUNCTION_TYPE_4
3134169699Skan#undef DEF_FUNCTION_TYPE_5
3135169699Skan#undef DEF_FUNCTION_TYPE_6
3136169699Skan#undef DEF_FUNCTION_TYPE_7
313790082Sobrien#undef DEF_FUNCTION_TYPE_VAR_0
313890082Sobrien#undef DEF_FUNCTION_TYPE_VAR_1
313990082Sobrien#undef DEF_FUNCTION_TYPE_VAR_2
3140117404Skan#undef DEF_FUNCTION_TYPE_VAR_3
3141169699Skan#undef DEF_FUNCTION_TYPE_VAR_4
3142169699Skan#undef DEF_FUNCTION_TYPE_VAR_5
314390082Sobrien#undef DEF_POINTER_TYPE
3144169699Skan  BT_LAST
3145169699Skan};
314690082Sobrien
3147169699Skantypedef enum c_builtin_type builtin_type;
314890082Sobrien
3149169699Skan/* A temporary array for c_common_nodes_and_builtins.  Used in
3150169699Skan   communication with def_fn_type.  */
3151169699Skanstatic tree builtin_types[(int) BT_LAST + 1];
3152169699Skan
3153169699Skan/* A helper function for c_common_nodes_and_builtins.  Build function type
3154169699Skan   for DEF with return type RET and N arguments.  If VAR is true, then the
3155169699Skan   function should be variadic after those N arguments.
3156169699Skan
3157169699Skan   Takes special care not to ICE if any of the types involved are
3158169699Skan   error_mark_node, which indicates that said type is not in fact available
3159169699Skan   (see builtin_type_for_size).  In which case the function type as a whole
3160169699Skan   should be error_mark_node.  */
3161169699Skan
3162169699Skanstatic void
3163169699Skandef_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
3164169699Skan{
3165169699Skan  tree args = NULL, t;
3166169699Skan  va_list list;
3167169699Skan  int i;
3168169699Skan
3169169699Skan  va_start (list, n);
3170169699Skan  for (i = 0; i < n; ++i)
3171169699Skan    {
3172169699Skan      builtin_type a = va_arg (list, builtin_type);
3173169699Skan      t = builtin_types[a];
3174169699Skan      if (t == error_mark_node)
3175169699Skan	goto egress;
3176169699Skan      args = tree_cons (NULL_TREE, t, args);
3177169699Skan    }
3178169699Skan  va_end (list);
3179169699Skan
3180169699Skan  args = nreverse (args);
3181169699Skan  if (!var)
3182169699Skan    args = chainon (args, void_list_node);
3183169699Skan
3184169699Skan  t = builtin_types[ret];
3185169699Skan  if (t == error_mark_node)
3186169699Skan    goto egress;
3187169699Skan  t = build_function_type (t, args);
3188169699Skan
3189169699Skan egress:
3190169699Skan  builtin_types[def] = t;
3191169699Skan}
3192169699Skan
3193259405Spfg/* Build builtin functions common to both C and C++ language
3194259405Spfg   frontends.  */
3195259405Spfg
3196259405Spfgstatic void
3197259405Spfgc_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node)
3198259405Spfg{
3199259405Spfg#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
3200259405Spfg  builtin_types[ENUM] = VALUE;
3201259405Spfg#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
3202259405Spfg  def_fn_type (ENUM, RETURN, 0, 0);
3203259405Spfg#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
3204259405Spfg  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
3205259405Spfg#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
3206259405Spfg  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
3207259405Spfg#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
3208259405Spfg  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
3209259405Spfg#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
3210259405Spfg  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
3211259405Spfg#define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)	\
3212259405Spfg  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
3213259405Spfg#define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
3214259405Spfg			    ARG6)					\
3215259405Spfg  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
3216259405Spfg#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
3217259405Spfg			    ARG6, ARG7)					\
3218259405Spfg  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
3219259405Spfg#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
3220259405Spfg  def_fn_type (ENUM, RETURN, 1, 0);
3221259405Spfg#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
3222259405Spfg  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
3223259405Spfg#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
3224259405Spfg  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
3225259405Spfg#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
3226259405Spfg  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
3227259405Spfg#define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
3228259405Spfg  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
3229259405Spfg#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
3230259405Spfg  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
3231259405Spfg#define DEF_POINTER_TYPE(ENUM, TYPE) \
3232259405Spfg  builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
3233259405Spfg
3234259405Spfg#include "builtin-types.def"
3235259405Spfg
3236259405Spfg#undef DEF_PRIMITIVE_TYPE
3237259405Spfg#undef DEF_FUNCTION_TYPE_1
3238259405Spfg#undef DEF_FUNCTION_TYPE_2
3239259405Spfg#undef DEF_FUNCTION_TYPE_3
3240259405Spfg#undef DEF_FUNCTION_TYPE_4
3241259405Spfg#undef DEF_FUNCTION_TYPE_5
3242259405Spfg#undef DEF_FUNCTION_TYPE_6
3243259405Spfg#undef DEF_FUNCTION_TYPE_VAR_0
3244259405Spfg#undef DEF_FUNCTION_TYPE_VAR_1
3245259405Spfg#undef DEF_FUNCTION_TYPE_VAR_2
3246259405Spfg#undef DEF_FUNCTION_TYPE_VAR_3
3247259405Spfg#undef DEF_FUNCTION_TYPE_VAR_4
3248259405Spfg#undef DEF_FUNCTION_TYPE_VAR_5
3249259405Spfg#undef DEF_POINTER_TYPE
3250259405Spfg  builtin_types[(int) BT_LAST] = NULL_TREE;
3251259405Spfg
3252259405Spfg  c_init_attributes ();
3253259405Spfg
3254259405Spfg#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
3255259405Spfg		    NONANSI_P, ATTRS, IMPLICIT, COND)			\
3256259405Spfg  if (NAME && COND)							\
3257259405Spfg    def_builtin_1 (ENUM, NAME, CLASS,                                   \
3258259405Spfg		   builtin_types[(int) TYPE],                           \
3259259405Spfg		   builtin_types[(int) LIBTYPE],                        \
3260259405Spfg		   BOTH_P, FALLBACK_P, NONANSI_P,                       \
3261259405Spfg		   built_in_attributes[(int) ATTRS], IMPLICIT);
3262259405Spfg#include "builtins.def"
3263259405Spfg#undef DEF_BUILTIN
3264259405Spfg
3265259405Spfg  build_common_builtin_nodes ();
3266259405Spfg
3267259405Spfg  targetm.init_builtins ();
3268259405Spfg  if (flag_mudflap)
3269259405Spfg    mudflap_init ();
3270259405Spfg}
3271259405Spfg
3272169699Skan/* Build tree nodes and builtin functions common to both C and C++ language
3273169699Skan   frontends.  */
3274169699Skan
3275169699Skanvoid
3276169699Skanc_common_nodes_and_builtins (void)
3277169699Skan{
327890082Sobrien  int wchar_type_size;
327990082Sobrien  tree array_domain_type;
328090082Sobrien  tree va_list_ref_type_node;
328190082Sobrien  tree va_list_arg_type_node;
328290082Sobrien
328390082Sobrien  /* Define `int' and `char' first so that dbx will output them first.  */
328490082Sobrien  record_builtin_type (RID_INT, NULL, integer_type_node);
328590082Sobrien  record_builtin_type (RID_CHAR, "char", char_type_node);
328690082Sobrien
328790082Sobrien  /* `signed' is the same as `int'.  FIXME: the declarations of "signed",
328890082Sobrien     "unsigned long", "long long unsigned" and "unsigned short" were in C++
328990082Sobrien     but not C.  Are the conditionals here needed?  */
3290132728Skan  if (c_dialect_cxx ())
329190082Sobrien    record_builtin_type (RID_SIGNED, NULL, integer_type_node);
329290082Sobrien  record_builtin_type (RID_LONG, "long int", long_integer_type_node);
329390082Sobrien  record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node);
329490082Sobrien  record_builtin_type (RID_MAX, "long unsigned int",
329590082Sobrien		       long_unsigned_type_node);
3296132728Skan  if (c_dialect_cxx ())
329790082Sobrien    record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node);
329890082Sobrien  record_builtin_type (RID_MAX, "long long int",
329990082Sobrien		       long_long_integer_type_node);
330090082Sobrien  record_builtin_type (RID_MAX, "long long unsigned int",
330190082Sobrien		       long_long_unsigned_type_node);
3302132728Skan  if (c_dialect_cxx ())
330390082Sobrien    record_builtin_type (RID_MAX, "long long unsigned",
330490082Sobrien			 long_long_unsigned_type_node);
330590082Sobrien  record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
330690082Sobrien  record_builtin_type (RID_MAX, "short unsigned int",
330790082Sobrien		       short_unsigned_type_node);
3308132728Skan  if (c_dialect_cxx ())
330990082Sobrien    record_builtin_type (RID_MAX, "unsigned short",
331090082Sobrien			 short_unsigned_type_node);
331190082Sobrien
331290082Sobrien  /* Define both `signed char' and `unsigned char'.  */
331390082Sobrien  record_builtin_type (RID_MAX, "signed char", signed_char_type_node);
331490082Sobrien  record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node);
331590082Sobrien
3316117404Skan  /* These are types that c_common_type_for_size and
3317117404Skan     c_common_type_for_mode use.  */
3318169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
3319169699Skan					 intQI_type_node));
3320169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
3321169699Skan					 intHI_type_node));
3322169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
3323169699Skan					 intSI_type_node));
3324169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
3325169699Skan					 intDI_type_node));
332690082Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
3327169699Skan  if (targetm.scalar_mode_supported_p (TImode))
3328169699Skan    lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
3329169699Skan					   get_identifier ("__int128_t"),
3330169699Skan					   intTI_type_node));
333190082Sobrien#endif
3332169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
3333169699Skan					 unsigned_intQI_type_node));
3334169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
3335169699Skan					 unsigned_intHI_type_node));
3336169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
3337169699Skan					 unsigned_intSI_type_node));
3338169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
3339169699Skan					 unsigned_intDI_type_node));
334090082Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
3341169699Skan  if (targetm.scalar_mode_supported_p (TImode))
3342169699Skan    lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
3343169699Skan					   get_identifier ("__uint128_t"),
3344169699Skan					   unsigned_intTI_type_node));
334590082Sobrien#endif
334690082Sobrien
334790082Sobrien  /* Create the widest literal types.  */
334890082Sobrien  widest_integer_literal_type_node
334990082Sobrien    = make_signed_type (HOST_BITS_PER_WIDE_INT * 2);
3350169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
3351169699Skan					 widest_integer_literal_type_node));
335290082Sobrien
335390082Sobrien  widest_unsigned_literal_type_node
335490082Sobrien    = make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2);
3355169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
3356169699Skan					 widest_unsigned_literal_type_node));
335790082Sobrien
335890082Sobrien  /* `unsigned long' is the standard type for sizeof.
335990082Sobrien     Note that stddef.h uses `unsigned long',
336090082Sobrien     and this must agree, even if long and int are the same size.  */
3361110621Skan  size_type_node =
336290082Sobrien    TREE_TYPE (identifier_global_value (get_identifier (SIZE_TYPE)));
3363117404Skan  signed_size_type_node = c_common_signed_type (size_type_node);
3364110621Skan  set_sizetype (size_type_node);
336590082Sobrien
3366169699Skan  pid_type_node =
3367169699Skan    TREE_TYPE (identifier_global_value (get_identifier (PID_TYPE)));
3368169699Skan
336990082Sobrien  build_common_tree_nodes_2 (flag_short_double);
337090082Sobrien
337190082Sobrien  record_builtin_type (RID_FLOAT, NULL, float_type_node);
337290082Sobrien  record_builtin_type (RID_DOUBLE, NULL, double_type_node);
337390082Sobrien  record_builtin_type (RID_MAX, "long double", long_double_type_node);
337490082Sobrien
3375169699Skan  /* Only supported decimal floating point extension if the target
3376169699Skan     actually supports underlying modes. */
3377169699Skan  if (targetm.scalar_mode_supported_p (SDmode)
3378169699Skan      && targetm.scalar_mode_supported_p (DDmode)
3379169699Skan      && targetm.scalar_mode_supported_p (TDmode))
3380110621Skan    {
3381169699Skan      record_builtin_type (RID_DFLOAT32, NULL, dfloat32_type_node);
3382169699Skan      record_builtin_type (RID_DFLOAT64, NULL, dfloat64_type_node);
3383169699Skan      record_builtin_type (RID_DFLOAT128, NULL, dfloat128_type_node);
3384110621Skan    }
3385110621Skan
3386169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
3387169699Skan					 get_identifier ("complex int"),
3388169699Skan					 complex_integer_type_node));
3389169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
3390169699Skan					 get_identifier ("complex float"),
3391169699Skan					 complex_float_type_node));
3392169699Skan  lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
3393169699Skan					 get_identifier ("complex double"),
3394169699Skan					 complex_double_type_node));
3395169699Skan  lang_hooks.decls.pushdecl
3396169699Skan    (build_decl (TYPE_DECL, get_identifier ("complex long double"),
3397169699Skan		 complex_long_double_type_node));
3398110621Skan
3399169699Skan  if (c_dialect_cxx ())
3400169699Skan    /* For C++, make fileptr_type_node a distinct void * type until
3401169699Skan       FILE type is defined.  */
3402169699Skan    fileptr_type_node = build_variant_type_copy (ptr_type_node);
3403110621Skan
340490082Sobrien  record_builtin_type (RID_VOID, NULL, void_type_node);
340590082Sobrien
3406169699Skan  /* This node must not be shared.  */
3407169699Skan  void_zero_node = make_node (INTEGER_CST);
340890082Sobrien  TREE_TYPE (void_zero_node) = void_type_node;
340990082Sobrien
341090082Sobrien  void_list_node = build_void_list_node ();
341190082Sobrien
341290082Sobrien  /* Make a type to be the domain of a few array types
341390082Sobrien     whose domains don't really matter.
341490082Sobrien     200 is small enough that it always fits in size_t
341590082Sobrien     and large enough that it can hold most function names for the
341690082Sobrien     initializations of __FUNCTION__ and __PRETTY_FUNCTION__.  */
341790082Sobrien  array_domain_type = build_index_type (size_int (200));
341890082Sobrien
341990082Sobrien  /* Make a type for arrays of characters.
342090082Sobrien     With luck nothing will ever really depend on the length of this
342190082Sobrien     array type.  */
342290082Sobrien  char_array_type_node
342390082Sobrien    = build_array_type (char_type_node, array_domain_type);
342490082Sobrien
342590082Sobrien  /* Likewise for arrays of ints.  */
342690082Sobrien  int_array_type_node
342790082Sobrien    = build_array_type (integer_type_node, array_domain_type);
342890082Sobrien
342990082Sobrien  string_type_node = build_pointer_type (char_type_node);
343090082Sobrien  const_string_type_node
343190082Sobrien    = build_pointer_type (build_qualified_type
343290082Sobrien			  (char_type_node, TYPE_QUAL_CONST));
343390082Sobrien
343490082Sobrien  /* This is special for C++ so functions can be overloaded.  */
3435117404Skan  wchar_type_node = get_identifier (MODIFIED_WCHAR_TYPE);
343690082Sobrien  wchar_type_node = TREE_TYPE (identifier_global_value (wchar_type_node));
343790082Sobrien  wchar_type_size = TYPE_PRECISION (wchar_type_node);
3438132728Skan  if (c_dialect_cxx ())
343990082Sobrien    {
3440169699Skan      if (TYPE_UNSIGNED (wchar_type_node))
344190082Sobrien	wchar_type_node = make_unsigned_type (wchar_type_size);
344250449Sobrien      else
344390082Sobrien	wchar_type_node = make_signed_type (wchar_type_size);
344490082Sobrien      record_builtin_type (RID_WCHAR, "wchar_t", wchar_type_node);
344590082Sobrien    }
344690082Sobrien  else
344790082Sobrien    {
3448117404Skan      signed_wchar_type_node = c_common_signed_type (wchar_type_node);
3449117404Skan      unsigned_wchar_type_node = c_common_unsigned_type (wchar_type_node);
345090082Sobrien    }
345150449Sobrien
345290082Sobrien  /* This is for wide string constants.  */
345390082Sobrien  wchar_array_type_node
345490082Sobrien    = build_array_type (wchar_type_node, array_domain_type);
345590082Sobrien
345690082Sobrien  wint_type_node =
345790082Sobrien    TREE_TYPE (identifier_global_value (get_identifier (WINT_TYPE)));
345890082Sobrien
345990082Sobrien  intmax_type_node =
346090082Sobrien    TREE_TYPE (identifier_global_value (get_identifier (INTMAX_TYPE)));
346190082Sobrien  uintmax_type_node =
346290082Sobrien    TREE_TYPE (identifier_global_value (get_identifier (UINTMAX_TYPE)));
346390082Sobrien
346490082Sobrien  default_function_type = build_function_type (integer_type_node, NULL_TREE);
346590082Sobrien  ptrdiff_type_node
346690082Sobrien    = TREE_TYPE (identifier_global_value (get_identifier (PTRDIFF_TYPE)));
3467117404Skan  unsigned_ptrdiff_type_node = c_common_unsigned_type (ptrdiff_type_node);
346890082Sobrien
3469169699Skan  lang_hooks.decls.pushdecl
3470117404Skan    (build_decl (TYPE_DECL, get_identifier ("__builtin_va_list"),
3471117404Skan		 va_list_type_node));
347290082Sobrien
347390082Sobrien  if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
347490082Sobrien    {
347590082Sobrien      va_list_arg_type_node = va_list_ref_type_node =
347690082Sobrien	build_pointer_type (TREE_TYPE (va_list_type_node));
347750449Sobrien    }
347890082Sobrien  else
347990082Sobrien    {
348090082Sobrien      va_list_arg_type_node = va_list_type_node;
348190082Sobrien      va_list_ref_type_node = build_reference_type (va_list_type_node);
348290082Sobrien    }
3483132728Skan
3484259405Spfg  if (!flag_preprocess_only)
3485259405Spfg    c_define_builtins (va_list_ref_type_node, va_list_arg_type_node);
348690082Sobrien
348790082Sobrien  main_identifier_node = get_identifier ("main");
3488169699Skan
3489169699Skan  /* Create the built-in __null node.  It is important that this is
3490169699Skan     not shared.  */
3491169699Skan  null_node = make_node (INTEGER_CST);
3492169699Skan  TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0);
3493169699Skan
3494169699Skan  /* Since builtin_types isn't gc'ed, don't export these nodes.  */
3495169699Skan  memset (builtin_types, 0, sizeof (builtin_types));
349650449Sobrien}
349750449Sobrien
3498169699Skan/* Look up the function in built_in_decls that corresponds to DECL
3499169699Skan   and set ASMSPEC as its user assembler name.  DECL must be a
3500169699Skan   function decl that declares a builtin.  */
3501169699Skan
3502169699Skanvoid
3503169699Skanset_builtin_user_assembler_name (tree decl, const char *asmspec)
3504169699Skan{
3505169699Skan  tree builtin;
3506169699Skan  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
3507169699Skan	      && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
3508169699Skan	      && asmspec != 0);
3509169699Skan
3510169699Skan  builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
3511169699Skan  set_user_assembler_name (builtin, asmspec);
3512169699Skan  if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMCPY)
3513169699Skan    init_block_move_fn (asmspec);
3514169699Skan  else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMSET)
3515169699Skan    init_block_clear_fn (asmspec);
3516169699Skan}
3517169699Skan
3518169699Skan/* The number of named compound-literals generated thus far.  */
3519169699Skanstatic GTY(()) int compound_literal_number;
3520169699Skan
3521169699Skan/* Set DECL_NAME for DECL, a VAR_DECL for a compound-literal.  */
3522169699Skan
3523169699Skanvoid
3524169699Skanset_compound_literal_name (tree decl)
3525169699Skan{
3526169699Skan  char *name;
3527169699Skan  ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal",
3528169699Skan			   compound_literal_number);
3529169699Skan  compound_literal_number++;
3530169699Skan  DECL_NAME (decl) = get_identifier (name);
3531169699Skan}
3532169699Skan
353390082Sobrientree
3534132728Skanbuild_va_arg (tree expr, tree type)
353590082Sobrien{
353690082Sobrien  return build1 (VA_ARG_EXPR, type, expr);
353790082Sobrien}
353850449Sobrien
353950449Sobrien
354090082Sobrien/* Linked list of disabled built-in functions.  */
354190082Sobrien
354290082Sobrientypedef struct disabled_builtin
354318334Speter{
354490082Sobrien  const char *name;
354590082Sobrien  struct disabled_builtin *next;
354690082Sobrien} disabled_builtin;
354790082Sobrienstatic disabled_builtin *disabled_builtins = NULL;
354818334Speter
3549132728Skanstatic bool builtin_function_disabled_p (const char *);
355090082Sobrien
355190082Sobrien/* Disable a built-in function specified by -fno-builtin-NAME.  If NAME
355290082Sobrien   begins with "__builtin_", give an error.  */
355390082Sobrien
355490082Sobrienvoid
3555132728Skandisable_builtin_function (const char *name)
355690082Sobrien{
355790082Sobrien  if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0)
3558169699Skan    error ("cannot disable built-in function %qs", name);
355990082Sobrien  else
356018334Speter    {
3561169699Skan      disabled_builtin *new_disabled_builtin = XNEW (disabled_builtin);
3562169699Skan      new_disabled_builtin->name = name;
3563169699Skan      new_disabled_builtin->next = disabled_builtins;
3564169699Skan      disabled_builtins = new_disabled_builtin;
356518334Speter    }
356690082Sobrien}
356718334Speter
356818334Speter
356990082Sobrien/* Return true if the built-in function NAME has been disabled, false
357090082Sobrien   otherwise.  */
357190082Sobrien
357290082Sobrienstatic bool
3573132728Skanbuiltin_function_disabled_p (const char *name)
357490082Sobrien{
357590082Sobrien  disabled_builtin *p;
357690082Sobrien  for (p = disabled_builtins; p != NULL; p = p->next)
357718334Speter    {
357890082Sobrien      if (strcmp (name, p->name) == 0)
357990082Sobrien	return true;
358090082Sobrien    }
358190082Sobrien  return false;
358290082Sobrien}
358318334Speter
358418334Speter
3585169699Skan/* Worker for DEF_BUILTIN.
3586169699Skan   Possibly define a builtin function with one or two names.
3587169699Skan   Does not declare a non-__builtin_ function if flag_no_builtin, or if
3588169699Skan   nonansi_p and flag_no_nonansi_builtin.  */
358918334Speter
3590169699Skanstatic void
3591169699Skandef_builtin_1 (enum built_in_function fncode,
3592169699Skan	       const char *name,
3593169699Skan	       enum built_in_class fnclass,
3594169699Skan	       tree fntype, tree libtype,
3595169699Skan	       bool both_p, bool fallback_p, bool nonansi_p,
3596169699Skan	       tree fnattrs, bool implicit_p)
359790082Sobrien{
3598169699Skan  tree decl;
3599169699Skan  const char *libname;
3600132728Skan
3601169699Skan  if (fntype == error_mark_node)
3602169699Skan    return;
3603132728Skan
3604169699Skan  gcc_assert ((!both_p && !fallback_p)
3605169699Skan	      || !strncmp (name, "__builtin_",
3606169699Skan			   strlen ("__builtin_")));
3607169699Skan
3608169699Skan  libname = name + strlen ("__builtin_");
3609169699Skan  decl = lang_hooks.builtin_function (name, fntype, fncode, fnclass,
3610169699Skan				      (fallback_p ? libname : NULL),
3611169699Skan				      fnattrs);
3612169699Skan  if (both_p
3613169699Skan      && !flag_no_builtin && !builtin_function_disabled_p (libname)
361490082Sobrien      && !(nonansi_p && flag_no_nonansi_builtin))
3615169699Skan    lang_hooks.builtin_function (libname, libtype, fncode, fnclass,
3616169699Skan				 NULL, fnattrs);
3617132728Skan
3618169699Skan  built_in_decls[(int) fncode] = decl;
3619169699Skan  if (implicit_p)
3620169699Skan    implicit_built_in_decls[(int) fncode] = decl;
362190082Sobrien}
362290082Sobrien
362390082Sobrien/* Nonzero if the type T promotes to int.  This is (nearly) the
362490082Sobrien   integral promotions defined in ISO C99 6.3.1.1/2.  */
362518334Speter
362690082Sobrienbool
3627132728Skanc_promoting_integer_type_p (tree t)
362890082Sobrien{
362990082Sobrien  switch (TREE_CODE (t))
363090082Sobrien    {
363190082Sobrien    case INTEGER_TYPE:
363290082Sobrien      return (TYPE_MAIN_VARIANT (t) == char_type_node
363390082Sobrien	      || TYPE_MAIN_VARIANT (t) == signed_char_type_node
363490082Sobrien	      || TYPE_MAIN_VARIANT (t) == unsigned_char_type_node
363590082Sobrien	      || TYPE_MAIN_VARIANT (t) == short_integer_type_node
363690082Sobrien	      || TYPE_MAIN_VARIANT (t) == short_unsigned_type_node
363790082Sobrien	      || TYPE_PRECISION (t) < TYPE_PRECISION (integer_type_node));
363818334Speter
363990082Sobrien    case ENUMERAL_TYPE:
364090082Sobrien      /* ??? Technically all enumerations not larger than an int
364190082Sobrien	 promote to an int.  But this is used along code paths
364290082Sobrien	 that only want to notice a size change.  */
364390082Sobrien      return TYPE_PRECISION (t) < TYPE_PRECISION (integer_type_node);
364418334Speter
364590082Sobrien    case BOOLEAN_TYPE:
364690082Sobrien      return 1;
364718334Speter
364890082Sobrien    default:
364990082Sobrien      return 0;
365018334Speter    }
365118334Speter}
365218334Speter
365390082Sobrien/* Return 1 if PARMS specifies a fixed number of parameters
365490082Sobrien   and none of their types is affected by default promotions.  */
365552299Sobrien
365690082Sobrienint
3657132728Skanself_promoting_args_p (tree parms)
365852299Sobrien{
365990082Sobrien  tree t;
366090082Sobrien  for (t = parms; t; t = TREE_CHAIN (t))
366152299Sobrien    {
366290082Sobrien      tree type = TREE_VALUE (t);
366390082Sobrien
3664169699Skan      if (type == error_mark_node)
3665169699Skan	continue;
3666169699Skan
366790082Sobrien      if (TREE_CHAIN (t) == 0 && type != void_type_node)
366890082Sobrien	return 0;
366990082Sobrien
367090082Sobrien      if (type == 0)
367190082Sobrien	return 0;
367290082Sobrien
367390082Sobrien      if (TYPE_MAIN_VARIANT (type) == float_type_node)
367490082Sobrien	return 0;
367590082Sobrien
367690082Sobrien      if (c_promoting_integer_type_p (type))
367790082Sobrien	return 0;
367852299Sobrien    }
367990082Sobrien  return 1;
368090082Sobrien}
368190082Sobrien
368290082Sobrien/* Recursively examines the array elements of TYPE, until a non-array
368390082Sobrien   element type is found.  */
368490082Sobrien
368590082Sobrientree
3686132728Skanstrip_array_types (tree type)
368790082Sobrien{
368890082Sobrien  while (TREE_CODE (type) == ARRAY_TYPE)
368990082Sobrien    type = TREE_TYPE (type);
369090082Sobrien
369190082Sobrien  return type;
369290082Sobrien}
369390082Sobrien
3694132728Skan/* Recursively remove any '*' or '&' operator from TYPE.  */
3695132728Skantree
3696132728Skanstrip_pointer_operator (tree t)
3697132728Skan{
3698132728Skan  while (POINTER_TYPE_P (t))
3699132728Skan    t = TREE_TYPE (t);
3700132728Skan  return t;
3701132728Skan}
3702117404Skan
370390082Sobrien/* Used to compare case labels.  K1 and K2 are actually tree nodes
370490082Sobrien   representing case labels, or NULL_TREE for a `default' label.
370590082Sobrien   Returns -1 if K1 is ordered before K2, -1 if K1 is ordered after
370690082Sobrien   K2, and 0 if K1 and K2 are equal.  */
370790082Sobrien
370890082Sobrienint
3709132728Skancase_compare (splay_tree_key k1, splay_tree_key k2)
371090082Sobrien{
371190082Sobrien  /* Consider a NULL key (such as arises with a `default' label) to be
371290082Sobrien     smaller than anything else.  */
371390082Sobrien  if (!k1)
371490082Sobrien    return k2 ? -1 : 0;
371590082Sobrien  else if (!k2)
371690082Sobrien    return k1 ? 1 : 0;
371790082Sobrien
371890082Sobrien  return tree_int_cst_compare ((tree) k1, (tree) k2);
371990082Sobrien}
372090082Sobrien
372190082Sobrien/* Process a case label for the range LOW_VALUE ... HIGH_VALUE.  If
372290082Sobrien   LOW_VALUE and HIGH_VALUE are both NULL_TREE then this case label is
372390082Sobrien   actually a `default' label.  If only HIGH_VALUE is NULL_TREE, then
372490082Sobrien   case label was declared using the usual C/C++ syntax, rather than
372590082Sobrien   the GNU case range extension.  CASES is a tree containing all the
372690082Sobrien   case ranges processed so far; COND is the condition for the
3727169699Skan   switch-statement itself.  Returns the CASE_LABEL_EXPR created, or
3728169699Skan   ERROR_MARK_NODE if no CASE_LABEL_EXPR is created.  */
372990082Sobrien
373090082Sobrientree
3731169699Skanc_add_case_label (splay_tree cases, tree cond, tree orig_type,
3732169699Skan		  tree low_value, tree high_value)
373390082Sobrien{
373490082Sobrien  tree type;
373590082Sobrien  tree label;
373690082Sobrien  tree case_label;
373790082Sobrien  splay_tree_node node;
373890082Sobrien
373990082Sobrien  /* Create the LABEL_DECL itself.  */
3740169699Skan  label = create_artificial_label ();
374190082Sobrien
374290082Sobrien  /* If there was an error processing the switch condition, bail now
374390082Sobrien     before we get more confused.  */
374490082Sobrien  if (!cond || cond == error_mark_node)
3745169699Skan    goto error_out;
374690082Sobrien
3747132728Skan  if ((low_value && TREE_TYPE (low_value)
3748132728Skan       && POINTER_TYPE_P (TREE_TYPE (low_value)))
374990082Sobrien      || (high_value && TREE_TYPE (high_value)
375090082Sobrien	  && POINTER_TYPE_P (TREE_TYPE (high_value))))
3751169699Skan    {
3752169699Skan      error ("pointers are not permitted as case values");
3753169699Skan      goto error_out;
3754169699Skan    }
375590082Sobrien
375690082Sobrien  /* Case ranges are a GNU extension.  */
375790082Sobrien  if (high_value && pedantic)
3758132728Skan    pedwarn ("range expressions in switch statements are non-standard");
375990082Sobrien
376090082Sobrien  type = TREE_TYPE (cond);
376190082Sobrien  if (low_value)
376290082Sobrien    {
376390082Sobrien      low_value = check_case_value (low_value);
376490082Sobrien      low_value = convert_and_check (type, low_value);
3765169699Skan      if (low_value == error_mark_node)
3766169699Skan	goto error_out;
376790082Sobrien    }
376890082Sobrien  if (high_value)
376990082Sobrien    {
377090082Sobrien      high_value = check_case_value (high_value);
377190082Sobrien      high_value = convert_and_check (type, high_value);
3772169699Skan      if (high_value == error_mark_node)
3773169699Skan	goto error_out;
377490082Sobrien    }
377590082Sobrien
3776169699Skan  if (low_value && high_value)
377790082Sobrien    {
3778169699Skan      /* If the LOW_VALUE and HIGH_VALUE are the same, then this isn't
3779169699Skan	 really a case range, even though it was written that way.
3780169699Skan	 Remove the HIGH_VALUE to simplify later processing.  */
3781169699Skan      if (tree_int_cst_equal (low_value, high_value))
3782169699Skan	high_value = NULL_TREE;
3783169699Skan      else if (!tree_int_cst_lt (low_value, high_value))
3784169699Skan	warning (0, "empty range specified");
378590082Sobrien    }
378690082Sobrien
3787169699Skan  /* See if the case is in range of the type of the original testing
3788169699Skan     expression.  If both low_value and high_value are out of range,
3789169699Skan     don't insert the case label and return NULL_TREE.  */
3790169699Skan  if (low_value
3791169699Skan      && !check_case_bounds (type, orig_type,
3792169699Skan			     &low_value, high_value ? &high_value : NULL))
3793169699Skan    return NULL_TREE;
379490082Sobrien
379590082Sobrien  /* Look up the LOW_VALUE in the table of case labels we already
379690082Sobrien     have.  */
379790082Sobrien  node = splay_tree_lookup (cases, (splay_tree_key) low_value);
379890082Sobrien  /* If there was not an exact match, check for overlapping ranges.
379990082Sobrien     There's no need to do this if there's no LOW_VALUE or HIGH_VALUE;
380090082Sobrien     that's a `default' label and the only overlap is an exact match.  */
380190082Sobrien  if (!node && (low_value || high_value))
380290082Sobrien    {
380390082Sobrien      splay_tree_node low_bound;
380490082Sobrien      splay_tree_node high_bound;
380590082Sobrien
380690082Sobrien      /* Even though there wasn't an exact match, there might be an
380790082Sobrien	 overlap between this case range and another case range.
380890082Sobrien	 Since we've (inductively) not allowed any overlapping case
380990082Sobrien	 ranges, we simply need to find the greatest low case label
381090082Sobrien	 that is smaller that LOW_VALUE, and the smallest low case
381190082Sobrien	 label that is greater than LOW_VALUE.  If there is an overlap
381290082Sobrien	 it will occur in one of these two ranges.  */
381390082Sobrien      low_bound = splay_tree_predecessor (cases,
381490082Sobrien					  (splay_tree_key) low_value);
381590082Sobrien      high_bound = splay_tree_successor (cases,
381690082Sobrien					 (splay_tree_key) low_value);
381790082Sobrien
381890082Sobrien      /* Check to see if the LOW_BOUND overlaps.  It is smaller than
381990082Sobrien	 the LOW_VALUE, so there is no need to check unless the
382090082Sobrien	 LOW_BOUND is in fact itself a case range.  */
382190082Sobrien      if (low_bound
382290082Sobrien	  && CASE_HIGH ((tree) low_bound->value)
382390082Sobrien	  && tree_int_cst_compare (CASE_HIGH ((tree) low_bound->value),
382490082Sobrien				    low_value) >= 0)
382590082Sobrien	node = low_bound;
382690082Sobrien      /* Check to see if the HIGH_BOUND overlaps.  The low end of that
382790082Sobrien	 range is bigger than the low end of the current range, so we
382890082Sobrien	 are only interested if the current range is a real range, and
382990082Sobrien	 not an ordinary case label.  */
3830132728Skan      else if (high_bound
383190082Sobrien	       && high_value
383290082Sobrien	       && (tree_int_cst_compare ((tree) high_bound->key,
383390082Sobrien					 high_value)
383490082Sobrien		   <= 0))
383590082Sobrien	node = high_bound;
383690082Sobrien    }
383790082Sobrien  /* If there was an overlap, issue an error.  */
383890082Sobrien  if (node)
383990082Sobrien    {
3840169699Skan      tree duplicate = CASE_LABEL ((tree) node->value);
384190082Sobrien
384290082Sobrien      if (high_value)
384352299Sobrien	{
384490082Sobrien	  error ("duplicate (or overlapping) case value");
3845132728Skan	  error ("%Jthis is the first entry overlapping that value", duplicate);
384652299Sobrien	}
384790082Sobrien      else if (low_value)
384890082Sobrien	{
384990082Sobrien	  error ("duplicate case value") ;
3850132728Skan	  error ("%Jpreviously used here", duplicate);
385190082Sobrien	}
385290082Sobrien      else
385390082Sobrien	{
385490082Sobrien	  error ("multiple default labels in one switch");
3855132728Skan	  error ("%Jthis is the first default label", duplicate);
385690082Sobrien	}
3857169699Skan      goto error_out;
385890082Sobrien    }
385990082Sobrien
386090082Sobrien  /* Add a CASE_LABEL to the statement-tree.  */
386190082Sobrien  case_label = add_stmt (build_case_label (low_value, high_value, label));
386290082Sobrien  /* Register this case label in the splay tree.  */
3863132728Skan  splay_tree_insert (cases,
386490082Sobrien		     (splay_tree_key) low_value,
386590082Sobrien		     (splay_tree_value) case_label);
386690082Sobrien
386790082Sobrien  return case_label;
3868169699Skan
3869169699Skan error_out:
3870169699Skan  /* Add a label so that the back-end doesn't think that the beginning of
3871169699Skan     the switch is unreachable.  Note that we do not add a case label, as
3872169699Skan     that just leads to duplicates and thence to failure later on.  */
3873169699Skan  if (!cases->root)
3874169699Skan    {
3875169699Skan      tree t = create_artificial_label ();
3876169699Skan      add_stmt (build_stmt (LABEL_EXPR, t));
3877169699Skan    }
3878169699Skan  return error_mark_node;
387990082Sobrien}
388090082Sobrien
3881169699Skan/* Subroutines of c_do_switch_warnings, called via splay_tree_foreach.
3882169699Skan   Used to verify that case values match up with enumerator values.  */
3883169699Skan
3884169699Skanstatic void
3885169699Skanmatch_case_to_enum_1 (tree key, tree type, tree label)
3886169699Skan{
3887169699Skan  char buf[2 + 2*HOST_BITS_PER_WIDE_INT/4 + 1];
3888169699Skan
3889169699Skan  /* ??? Not working too hard to print the double-word value.
3890169699Skan     Should perhaps be done with %lwd in the diagnostic routines?  */
3891169699Skan  if (TREE_INT_CST_HIGH (key) == 0)
3892169699Skan    snprintf (buf, sizeof (buf), HOST_WIDE_INT_PRINT_UNSIGNED,
3893169699Skan	      TREE_INT_CST_LOW (key));
3894169699Skan  else if (!TYPE_UNSIGNED (type)
3895169699Skan	   && TREE_INT_CST_HIGH (key) == -1
3896169699Skan	   && TREE_INT_CST_LOW (key) != 0)
3897169699Skan    snprintf (buf, sizeof (buf), "-" HOST_WIDE_INT_PRINT_UNSIGNED,
3898169699Skan	      -TREE_INT_CST_LOW (key));
3899169699Skan  else
3900169699Skan    snprintf (buf, sizeof (buf), HOST_WIDE_INT_PRINT_DOUBLE_HEX,
3901169699Skan	      TREE_INT_CST_HIGH (key), TREE_INT_CST_LOW (key));
3902169699Skan
3903169699Skan  if (TYPE_NAME (type) == 0)
3904169699Skan    warning (0, "%Jcase value %qs not in enumerated type",
3905169699Skan	     CASE_LABEL (label), buf);
3906169699Skan  else
3907169699Skan    warning (0, "%Jcase value %qs not in enumerated type %qT",
3908169699Skan	     CASE_LABEL (label), buf, type);
3909169699Skan}
3910169699Skan
3911169699Skan/* Subroutine of c_do_switch_warnings, called via splay_tree_foreach.
3912169699Skan   Used to verify that case values match up with enumerator values.  */
3913169699Skan
3914169699Skanstatic int
3915169699Skanmatch_case_to_enum (splay_tree_node node, void *data)
3916169699Skan{
3917169699Skan  tree label = (tree) node->value;
3918169699Skan  tree type = (tree) data;
3919169699Skan
3920169699Skan  /* Skip default case.  */
3921169699Skan  if (!CASE_LOW (label))
3922169699Skan    return 0;
3923169699Skan
3924169699Skan  /* If CASE_LOW_SEEN is not set, that means CASE_LOW did not appear
3925169699Skan     when we did our enum->case scan.  Reset our scratch bit after.  */
3926169699Skan  if (!CASE_LOW_SEEN (label))
3927169699Skan    match_case_to_enum_1 (CASE_LOW (label), type, label);
3928169699Skan  else
3929169699Skan    CASE_LOW_SEEN (label) = 0;
3930169699Skan
3931169699Skan  /* If CASE_HIGH is non-null, we have a range.  If CASE_HIGH_SEEN is
3932169699Skan     not set, that means that CASE_HIGH did not appear when we did our
3933169699Skan     enum->case scan.  Reset our scratch bit after.  */
3934169699Skan  if (CASE_HIGH (label))
3935169699Skan    {
3936169699Skan      if (!CASE_HIGH_SEEN (label))
3937169699Skan	match_case_to_enum_1 (CASE_HIGH (label), type, label);
3938169699Skan      else
3939169699Skan	CASE_HIGH_SEEN (label) = 0;
3940169699Skan    }
3941169699Skan
3942169699Skan  return 0;
3943169699Skan}
3944169699Skan
3945169699Skan/* Handle -Wswitch*.  Called from the front end after parsing the
3946169699Skan   switch construct.  */
3947169699Skan/* ??? Should probably be somewhere generic, since other languages
3948169699Skan   besides C and C++ would want this.  At the moment, however, C/C++
3949169699Skan   are the only tree-ssa languages that support enumerations at all,
3950169699Skan   so the point is moot.  */
3951169699Skan
3952169699Skanvoid
3953169699Skanc_do_switch_warnings (splay_tree cases, location_t switch_location,
3954169699Skan		      tree type, tree cond)
3955169699Skan{
3956169699Skan  splay_tree_node default_node;
3957169699Skan  splay_tree_node node;
3958169699Skan  tree chain;
3959169699Skan
3960169699Skan  if (!warn_switch && !warn_switch_enum && !warn_switch_default)
3961169699Skan    return;
3962169699Skan
3963169699Skan  default_node = splay_tree_lookup (cases, (splay_tree_key) NULL);
3964169699Skan  if (!default_node)
3965169699Skan    warning (OPT_Wswitch_default, "%Hswitch missing default case",
3966169699Skan	     &switch_location);
3967169699Skan
3968169699Skan  /* From here on, we only care about about enumerated types.  */
3969169699Skan  if (!type || TREE_CODE (type) != ENUMERAL_TYPE)
3970169699Skan    return;
3971169699Skan
3972169699Skan  /* If the switch expression was an enumerated type, check that
3973169699Skan     exactly all enumeration literals are covered by the cases.
3974169699Skan     The check is made when -Wswitch was specified and there is no
3975169699Skan     default case, or when -Wswitch-enum was specified.  */
3976169699Skan
3977169699Skan  if (!warn_switch_enum
3978169699Skan      && !(warn_switch && !default_node))
3979169699Skan    return;
3980169699Skan
3981169699Skan  /* Clearing COND if it is not an integer constant simplifies
3982169699Skan     the tests inside the loop below.  */
3983169699Skan  if (TREE_CODE (cond) != INTEGER_CST)
3984169699Skan    cond = NULL_TREE;
3985169699Skan
3986169699Skan  /* The time complexity here is O(N*lg(N)) worst case, but for the
3987169699Skan      common case of monotonically increasing enumerators, it is
3988169699Skan      O(N), since the nature of the splay tree will keep the next
3989169699Skan      element adjacent to the root at all times.  */
3990169699Skan
3991169699Skan  for (chain = TYPE_VALUES (type); chain; chain = TREE_CHAIN (chain))
3992169699Skan    {
3993169699Skan      tree value = TREE_VALUE (chain);
3994169699Skan      node = splay_tree_lookup (cases, (splay_tree_key) value);
3995169699Skan      if (node)
3996169699Skan	{
3997169699Skan	  /* Mark the CASE_LOW part of the case entry as seen.  */
3998169699Skan	  tree label = (tree) node->value;
3999169699Skan	  CASE_LOW_SEEN (label) = 1;
4000169699Skan	  continue;
4001169699Skan	}
4002169699Skan
4003169699Skan      /* Even though there wasn't an exact match, there might be a
4004169699Skan	 case range which includes the enumator's value.  */
4005169699Skan      node = splay_tree_predecessor (cases, (splay_tree_key) value);
4006169699Skan      if (node && CASE_HIGH ((tree) node->value))
4007169699Skan	{
4008169699Skan	  tree label = (tree) node->value;
4009169699Skan	  int cmp = tree_int_cst_compare (CASE_HIGH (label), value);
4010169699Skan	  if (cmp >= 0)
4011169699Skan	    {
4012169699Skan	      /* If we match the upper bound exactly, mark the CASE_HIGH
4013169699Skan		 part of the case entry as seen.  */
4014169699Skan	      if (cmp == 0)
4015169699Skan		CASE_HIGH_SEEN (label) = 1;
4016169699Skan	      continue;
4017169699Skan	    }
4018169699Skan	}
4019169699Skan
4020169699Skan      /* We've now determined that this enumerated literal isn't
4021169699Skan	 handled by the case labels of the switch statement.  */
4022169699Skan
4023169699Skan      /* If the switch expression is a constant, we only really care
4024169699Skan	 about whether that constant is handled by the switch.  */
4025169699Skan      if (cond && tree_int_cst_compare (cond, value))
4026169699Skan	continue;
4027169699Skan
4028169699Skan      warning (0, "%Henumeration value %qE not handled in switch",
4029169699Skan	       &switch_location, TREE_PURPOSE (chain));
4030169699Skan    }
4031169699Skan
4032169699Skan  /* Warn if there are case expressions that don't correspond to
4033169699Skan     enumerators.  This can occur since C and C++ don't enforce
4034169699Skan     type-checking of assignments to enumeration variables.
4035169699Skan
4036169699Skan     The time complexity here is now always O(N) worst case, since
4037169699Skan     we should have marked both the lower bound and upper bound of
4038169699Skan     every disjoint case label, with CASE_LOW_SEEN and CASE_HIGH_SEEN
4039169699Skan     above.  This scan also resets those fields.  */
4040169699Skan  splay_tree_foreach (cases, match_case_to_enum, type);
4041169699Skan}
4042169699Skan
4043132728Skan/* Finish an expression taking the address of LABEL (an
4044132728Skan   IDENTIFIER_NODE).  Returns an expression for the address.  */
404590082Sobrien
4046132728Skantree
4047132728Skanfinish_label_address_expr (tree label)
404890082Sobrien{
404990082Sobrien  tree result;
405090082Sobrien
405190082Sobrien  if (pedantic)
4052132728Skan    pedwarn ("taking the address of a label is non-standard");
405390082Sobrien
4054132728Skan  if (label == error_mark_node)
4055132728Skan    return error_mark_node;
4056132728Skan
405790082Sobrien  label = lookup_label (label);
405890082Sobrien  if (label == NULL_TREE)
405990082Sobrien    result = null_pointer_node;
406090082Sobrien  else
406190082Sobrien    {
406290082Sobrien      TREE_USED (label) = 1;
406390082Sobrien      result = build1 (ADDR_EXPR, ptr_type_node, label);
406490082Sobrien      /* The current function in not necessarily uninlinable.
406590082Sobrien	 Computed gotos are incompatible with inlining, but the value
406690082Sobrien	 here could be used only in a diagnostic, for example.  */
406790082Sobrien    }
406890082Sobrien
406990082Sobrien  return result;
407090082Sobrien}
407190082Sobrien
407290082Sobrien/* Hook used by expand_expr to expand language-specific tree codes.  */
4073169699Skan/* The only things that should go here are bits needed to expand
4074169699Skan   constant initializers.  Everything else should be handled by the
4075169699Skan   gimplification routines.  */
407690082Sobrien
407790082Sobrienrtx
4078169699Skanc_expand_expr (tree exp, rtx target, enum machine_mode tmode,
4079132728Skan	       int modifier /* Actually enum_modifier.  */,
4080132728Skan	       rtx *alt_rtl)
408190082Sobrien{
408290082Sobrien  switch (TREE_CODE (exp))
408390082Sobrien    {
408490082Sobrien    case COMPOUND_LITERAL_EXPR:
408590082Sobrien      {
408690082Sobrien	/* Initialize the anonymous variable declared in the compound
408790082Sobrien	   literal, then return the variable.  */
408890082Sobrien	tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
408990082Sobrien	emit_local_var (decl);
4090132728Skan	return expand_expr_real (decl, target, tmode, modifier, alt_rtl);
409190082Sobrien      }
409290082Sobrien
409352299Sobrien    default:
4094169699Skan      gcc_unreachable ();
409552299Sobrien    }
409652299Sobrien}
409752299Sobrien
409890082Sobrien/* Hook used by staticp to handle language-specific tree codes.  */
409990082Sobrien
4100169699Skantree
4101132728Skanc_staticp (tree exp)
410290082Sobrien{
4103169699Skan  return (TREE_CODE (exp) == COMPOUND_LITERAL_EXPR
4104169699Skan	  && TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (exp))
4105169699Skan	  ? exp : NULL);
410690082Sobrien}
410790082Sobrien
410852761Sobrien
410990082Sobrien/* Given a boolean expression ARG, return a tree representing an increment
411090082Sobrien   or decrement (as indicated by CODE) of ARG.  The front end must check for
411190082Sobrien   invalid cases (e.g., decrement in C++).  */
411290082Sobrientree
4113132728Skanboolean_increment (enum tree_code code, tree arg)
411490082Sobrien{
411590082Sobrien  tree val;
4116132728Skan  tree true_res = boolean_true_node;
4117132728Skan
411890082Sobrien  arg = stabilize_reference (arg);
411990082Sobrien  switch (code)
412052761Sobrien    {
412190082Sobrien    case PREINCREMENT_EXPR:
4122169699Skan      val = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg, true_res);
412390082Sobrien      break;
412490082Sobrien    case POSTINCREMENT_EXPR:
4125169699Skan      val = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg, true_res);
412690082Sobrien      arg = save_expr (arg);
4127169699Skan      val = build2 (COMPOUND_EXPR, TREE_TYPE (arg), val, arg);
4128169699Skan      val = build2 (COMPOUND_EXPR, TREE_TYPE (arg), arg, val);
412990082Sobrien      break;
413090082Sobrien    case PREDECREMENT_EXPR:
4131169699Skan      val = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg,
4132169699Skan		    invert_truthvalue (arg));
413390082Sobrien      break;
413490082Sobrien    case POSTDECREMENT_EXPR:
4135169699Skan      val = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg,
4136169699Skan		    invert_truthvalue (arg));
413790082Sobrien      arg = save_expr (arg);
4138169699Skan      val = build2 (COMPOUND_EXPR, TREE_TYPE (arg), val, arg);
4139169699Skan      val = build2 (COMPOUND_EXPR, TREE_TYPE (arg), arg, val);
414090082Sobrien      break;
414190082Sobrien    default:
4142169699Skan      gcc_unreachable ();
414352761Sobrien    }
414490082Sobrien  TREE_SIDE_EFFECTS (val) = 1;
414590082Sobrien  return val;
414690082Sobrien}
414790082Sobrien
4148132728Skan/* Built-in macros for stddef.h, that require macros defined in this
4149132728Skan   file.  */
415090082Sobrienvoid
4151132728Skanc_stddef_cpp_builtins(void)
415290082Sobrien{
4153117404Skan  builtin_define_with_value ("__SIZE_TYPE__", SIZE_TYPE, 0);
4154117404Skan  builtin_define_with_value ("__PTRDIFF_TYPE__", PTRDIFF_TYPE, 0);
4155117404Skan  builtin_define_with_value ("__WCHAR_TYPE__", MODIFIED_WCHAR_TYPE, 0);
4156117404Skan  builtin_define_with_value ("__WINT_TYPE__", WINT_TYPE, 0);
4157169699Skan  builtin_define_with_value ("__INTMAX_TYPE__", INTMAX_TYPE, 0);
4158169699Skan  builtin_define_with_value ("__UINTMAX_TYPE__", UINTMAX_TYPE, 0);
415918334Speter}
416090082Sobrien
4161117404Skanstatic void
4162132728Skanc_init_attributes (void)
4163117404Skan{
416490082Sobrien  /* Fill in the built_in_attributes array.  */
4165169699Skan#define DEF_ATTR_NULL_TREE(ENUM)				\
416690082Sobrien  built_in_attributes[(int) ENUM] = NULL_TREE;
4167169699Skan#define DEF_ATTR_INT(ENUM, VALUE)				\
4168169699Skan  built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
416990082Sobrien#define DEF_ATTR_IDENT(ENUM, STRING)				\
417090082Sobrien  built_in_attributes[(int) ENUM] = get_identifier (STRING);
417190082Sobrien#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN)	\
417290082Sobrien  built_in_attributes[(int) ENUM]			\
417390082Sobrien    = tree_cons (built_in_attributes[(int) PURPOSE],	\
417490082Sobrien		 built_in_attributes[(int) VALUE],	\
417590082Sobrien		 built_in_attributes[(int) CHAIN]);
417690082Sobrien#include "builtin-attrs.def"
417790082Sobrien#undef DEF_ATTR_NULL_TREE
417890082Sobrien#undef DEF_ATTR_INT
417990082Sobrien#undef DEF_ATTR_IDENT
418090082Sobrien#undef DEF_ATTR_TREE_LIST
418190082Sobrien}
418290082Sobrien
4183117404Skan/* Attribute handlers common to C front ends.  */
4184117404Skan
4185117404Skan/* Handle a "packed" attribute; arguments as in
4186117404Skan   struct attribute_spec.handler.  */
4187117404Skan
4188117404Skanstatic tree
4189169699Skanhandle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
4190132728Skan			 int flags, bool *no_add_attrs)
4191117404Skan{
4192132728Skan  if (TYPE_P (*node))
4193117404Skan    {
4194117404Skan      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
4195169699Skan	*node = build_variant_type_copy (*node);
4196132728Skan      TYPE_PACKED (*node) = 1;
4197117404Skan    }
4198117404Skan  else if (TREE_CODE (*node) == FIELD_DECL)
4199169699Skan    {
4200169699Skan      if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT)
4201169699Skan	warning (OPT_Wattributes,
4202169699Skan		 "%qE attribute ignored for field of type %qT",
4203169699Skan		 name, TREE_TYPE (*node));
4204169699Skan      else
4205169699Skan	DECL_PACKED (*node) = 1;
4206169699Skan    }
4207117404Skan  /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
4208132728Skan     used for DECL_REGISTER.  It wouldn't mean anything anyway.
4209132728Skan     We can't set DECL_PACKED on the type of a TYPE_DECL, because
4210132728Skan     that changes what the typedef is typing.  */
4211117404Skan  else
4212117404Skan    {
4213169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4214117404Skan      *no_add_attrs = true;
4215117404Skan    }
4216117404Skan
4217117404Skan  return NULL_TREE;
4218117404Skan}
4219117404Skan
4220117404Skan/* Handle a "nocommon" attribute; arguments as in
4221117404Skan   struct attribute_spec.handler.  */
4222117404Skan
4223117404Skanstatic tree
4224132728Skanhandle_nocommon_attribute (tree *node, tree name,
4225169699Skan			   tree ARG_UNUSED (args),
4226169699Skan			   int ARG_UNUSED (flags), bool *no_add_attrs)
4227117404Skan{
4228117404Skan  if (TREE_CODE (*node) == VAR_DECL)
4229117404Skan    DECL_COMMON (*node) = 0;
4230117404Skan  else
4231117404Skan    {
4232169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4233117404Skan      *no_add_attrs = true;
4234117404Skan    }
4235117404Skan
4236117404Skan  return NULL_TREE;
4237117404Skan}
4238117404Skan
4239117404Skan/* Handle a "common" attribute; arguments as in
4240117404Skan   struct attribute_spec.handler.  */
4241117404Skan
4242117404Skanstatic tree
4243169699Skanhandle_common_attribute (tree *node, tree name, tree ARG_UNUSED (args),
4244169699Skan			 int ARG_UNUSED (flags), bool *no_add_attrs)
4245117404Skan{
4246117404Skan  if (TREE_CODE (*node) == VAR_DECL)
4247117404Skan    DECL_COMMON (*node) = 1;
4248117404Skan  else
4249117404Skan    {
4250169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4251117404Skan      *no_add_attrs = true;
4252117404Skan    }
4253117404Skan
4254117404Skan  return NULL_TREE;
4255117404Skan}
4256117404Skan
4257117404Skan/* Handle a "noreturn" attribute; arguments as in
4258117404Skan   struct attribute_spec.handler.  */
4259117404Skan
4260117404Skanstatic tree
4261169699Skanhandle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args),
4262169699Skan			   int ARG_UNUSED (flags), bool *no_add_attrs)
4263117404Skan{
4264117404Skan  tree type = TREE_TYPE (*node);
4265117404Skan
4266117404Skan  /* See FIXME comment in c_common_attribute_table.  */
4267261188Spfg  /* APPLE LOCAL begin radar 4727659 */
4268261188Spfg  if (TREE_CODE (*node) == FUNCTION_DECL
4269261188Spfg      || objc_method_decl (TREE_CODE (*node)))
4270261188Spfg  /* APPLE LOCAL end radar 4727659 */
4271117404Skan    TREE_THIS_VOLATILE (*node) = 1;
4272117404Skan  else if (TREE_CODE (type) == POINTER_TYPE
4273117404Skan	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
4274117404Skan    TREE_TYPE (*node)
4275117404Skan      = build_pointer_type
4276117404Skan	(build_type_variant (TREE_TYPE (type),
4277169699Skan			     TYPE_READONLY (TREE_TYPE (type)), 1));
4278261188Spfg  /* APPLE LOCAL begin radar 6237713 */
4279261188Spfg  else if (TREE_CODE (type) == BLOCK_POINTER_TYPE
4280261188Spfg	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
4281261188Spfg    TREE_TYPE (*node)
4282261188Spfg      = build_block_pointer_type
4283261188Spfg	(build_type_variant (TREE_TYPE (type),
4284261188Spfg			     TYPE_READONLY (TREE_TYPE (type)), 1));
4285261188Spfg  /* APPLE LOCAL end radar 6237713 */
4286117404Skan  else
4287117404Skan    {
4288169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4289117404Skan      *no_add_attrs = true;
4290117404Skan    }
4291117404Skan
4292117404Skan  return NULL_TREE;
4293117404Skan}
4294117404Skan
4295117404Skan/* Handle a "noinline" attribute; arguments as in
4296117404Skan   struct attribute_spec.handler.  */
4297117404Skan
4298117404Skanstatic tree
4299132728Skanhandle_noinline_attribute (tree *node, tree name,
4300169699Skan			   tree ARG_UNUSED (args),
4301169699Skan			   int ARG_UNUSED (flags), bool *no_add_attrs)
4302117404Skan{
4303117404Skan  if (TREE_CODE (*node) == FUNCTION_DECL)
4304117404Skan    DECL_UNINLINABLE (*node) = 1;
4305117404Skan  else
4306117404Skan    {
4307169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4308117404Skan      *no_add_attrs = true;
4309117404Skan    }
4310117404Skan
4311117404Skan  return NULL_TREE;
4312117404Skan}
4313117404Skan
4314117404Skan/* Handle a "always_inline" attribute; arguments as in
4315117404Skan   struct attribute_spec.handler.  */
4316117404Skan
4317117404Skanstatic tree
4318132728Skanhandle_always_inline_attribute (tree *node, tree name,
4319169699Skan				tree ARG_UNUSED (args),
4320169699Skan				int ARG_UNUSED (flags),
4321132728Skan				bool *no_add_attrs)
4322117404Skan{
4323117404Skan  if (TREE_CODE (*node) == FUNCTION_DECL)
4324117404Skan    {
4325117404Skan      /* Do nothing else, just set the attribute.  We'll get at
4326117404Skan	 it later with lookup_attribute.  */
4327117404Skan    }
4328117404Skan  else
4329117404Skan    {
4330169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4331117404Skan      *no_add_attrs = true;
4332117404Skan    }
4333117404Skan
4334117404Skan  return NULL_TREE;
4335117404Skan}
4336117404Skan
4337169699Skan/* Handle a "gnu_inline" attribute; arguments as in
4338169699Skan   struct attribute_spec.handler.  */
4339169699Skan
4340169699Skanstatic tree
4341169699Skanhandle_gnu_inline_attribute (tree *node, tree name,
4342169699Skan			     tree ARG_UNUSED (args),
4343169699Skan			     int ARG_UNUSED (flags),
4344169699Skan			     bool *no_add_attrs)
4345169699Skan{
4346169699Skan  if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
4347169699Skan    {
4348169699Skan      /* Do nothing else, just set the attribute.  We'll get at
4349169699Skan	 it later with lookup_attribute.  */
4350169699Skan    }
4351169699Skan  else
4352169699Skan    {
4353169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4354169699Skan      *no_add_attrs = true;
4355169699Skan    }
4356169699Skan
4357169699Skan  return NULL_TREE;
4358169699Skan}
4359169699Skan
4360169699Skan/* Handle a "flatten" attribute; arguments as in
4361169699Skan   struct attribute_spec.handler.  */
4362169699Skan
4363169699Skanstatic tree
4364169699Skanhandle_flatten_attribute (tree *node, tree name,
4365169699Skan			  tree args ATTRIBUTE_UNUSED,
4366169699Skan			  int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
4367169699Skan{
4368169699Skan  if (TREE_CODE (*node) == FUNCTION_DECL)
4369169699Skan    /* Do nothing else, just set the attribute.  We'll get at
4370169699Skan       it later with lookup_attribute.  */
4371169699Skan    ;
4372169699Skan  else
4373169699Skan    {
4374169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4375169699Skan      *no_add_attrs = true;
4376169699Skan    }
4377169699Skan
4378169699Skan  return NULL_TREE;
4379169699Skan}
4380169699Skan
4381169699Skan
4382117404Skan/* Handle a "used" attribute; arguments as in
4383117404Skan   struct attribute_spec.handler.  */
4384117404Skan
4385117404Skanstatic tree
4386169699Skanhandle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
4387169699Skan		       int ARG_UNUSED (flags), bool *no_add_attrs)
4388117404Skan{
4389117404Skan  tree node = *pnode;
4390117404Skan
4391117404Skan  if (TREE_CODE (node) == FUNCTION_DECL
4392117404Skan      || (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node)))
4393132728Skan    {
4394132728Skan      TREE_USED (node) = 1;
4395169699Skan      DECL_PRESERVE_P (node) = 1;
4396132728Skan    }
4397117404Skan  else
4398117404Skan    {
4399169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4400117404Skan      *no_add_attrs = true;
4401117404Skan    }
4402117404Skan
4403117404Skan  return NULL_TREE;
4404117404Skan}
4405117404Skan
4406117404Skan/* Handle a "unused" attribute; arguments as in
4407117404Skan   struct attribute_spec.handler.  */
4408117404Skan
4409117404Skanstatic tree
4410169699Skanhandle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
4411169699Skan			 int flags, bool *no_add_attrs)
4412117404Skan{
4413117404Skan  if (DECL_P (*node))
4414117404Skan    {
4415117404Skan      tree decl = *node;
4416117404Skan
4417117404Skan      if (TREE_CODE (decl) == PARM_DECL
4418117404Skan	  || TREE_CODE (decl) == VAR_DECL
4419117404Skan	  || TREE_CODE (decl) == FUNCTION_DECL
4420260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4421260918Spfg	  || (TREE_CODE (decl) == LABEL_DECL
4422260918Spfg	      && ! DECL_ARTIFICIAL (decl))
4423260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4424117404Skan	  || TREE_CODE (decl) == TYPE_DECL)
4425117404Skan	TREE_USED (decl) = 1;
4426117404Skan      else
4427117404Skan	{
4428169699Skan	  warning (OPT_Wattributes, "%qE attribute ignored", name);
4429117404Skan	  *no_add_attrs = true;
4430117404Skan	}
4431117404Skan    }
4432117404Skan  else
4433117404Skan    {
4434117404Skan      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
4435169699Skan	*node = build_variant_type_copy (*node);
4436117404Skan      TREE_USED (*node) = 1;
4437117404Skan    }
4438117404Skan
4439117404Skan  return NULL_TREE;
4440117404Skan}
4441117404Skan
4442169699Skan/* Handle a "externally_visible" attribute; arguments as in
4443169699Skan   struct attribute_spec.handler.  */
4444169699Skan
4445169699Skanstatic tree
4446169699Skanhandle_externally_visible_attribute (tree *pnode, tree name,
4447169699Skan				     tree ARG_UNUSED (args),
4448169699Skan				     int ARG_UNUSED (flags),
4449169699Skan				     bool *no_add_attrs)
4450169699Skan{
4451169699Skan  tree node = *pnode;
4452169699Skan
4453169699Skan  if (TREE_CODE (node) == FUNCTION_DECL || TREE_CODE (node) == VAR_DECL)
4454169699Skan    {
4455169699Skan      if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL
4456169699Skan	   && !DECL_EXTERNAL (node)) || !TREE_PUBLIC (node))
4457169699Skan	{
4458169699Skan	  warning (OPT_Wattributes,
4459169699Skan		   "%qE attribute have effect only on public objects", name);
4460169699Skan	  *no_add_attrs = true;
4461169699Skan	}
4462169699Skan    }
4463169699Skan  else
4464169699Skan    {
4465169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4466169699Skan      *no_add_attrs = true;
4467169699Skan    }
4468169699Skan
4469169699Skan  return NULL_TREE;
4470169699Skan}
4471169699Skan
4472117404Skan/* Handle a "const" attribute; arguments as in
4473117404Skan   struct attribute_spec.handler.  */
4474117404Skan
4475117404Skanstatic tree
4476169699Skanhandle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
4477169699Skan			int ARG_UNUSED (flags), bool *no_add_attrs)
4478117404Skan{
4479117404Skan  tree type = TREE_TYPE (*node);
4480117404Skan
4481117404Skan  /* See FIXME comment on noreturn in c_common_attribute_table.  */
4482117404Skan  if (TREE_CODE (*node) == FUNCTION_DECL)
4483117404Skan    TREE_READONLY (*node) = 1;
4484117404Skan  else if (TREE_CODE (type) == POINTER_TYPE
4485117404Skan	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
4486117404Skan    TREE_TYPE (*node)
4487117404Skan      = build_pointer_type
4488117404Skan	(build_type_variant (TREE_TYPE (type), 1,
4489117404Skan			     TREE_THIS_VOLATILE (TREE_TYPE (type))));
4490117404Skan  else
4491117404Skan    {
4492169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4493117404Skan      *no_add_attrs = true;
4494117404Skan    }
4495117404Skan
4496117404Skan  return NULL_TREE;
4497117404Skan}
4498117404Skan
4499117404Skan/* Handle a "transparent_union" attribute; arguments as in
4500117404Skan   struct attribute_spec.handler.  */
4501117404Skan
4502117404Skanstatic tree
4503132728Skanhandle_transparent_union_attribute (tree *node, tree name,
4504169699Skan				    tree ARG_UNUSED (args), int flags,
4505132728Skan				    bool *no_add_attrs)
4506117404Skan{
4507169699Skan  tree type = NULL;
4508117404Skan
4509169699Skan  *no_add_attrs = true;
4510169699Skan
4511117404Skan  if (DECL_P (*node))
4512117404Skan    {
4513169699Skan      if (TREE_CODE (*node) != TYPE_DECL)
4514169699Skan	goto ignored;
4515169699Skan      node = &TREE_TYPE (*node);
4516169699Skan      type = *node;
4517117404Skan    }
4518117404Skan  else if (TYPE_P (*node))
4519169699Skan    type = *node;
4520169699Skan  else
4521169699Skan    goto ignored;
4522117404Skan
4523169699Skan  if (TREE_CODE (type) == UNION_TYPE)
4524117404Skan    {
4525169699Skan      /* When IN_PLACE is set, leave the check for FIELDS and MODE to
4526169699Skan	 the code in finish_struct.  */
4527117404Skan      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
4528169699Skan	{
4529169699Skan	  if (TYPE_FIELDS (type) == NULL_TREE
4530169699Skan	      || TYPE_MODE (type) != DECL_MODE (TYPE_FIELDS (type)))
4531169699Skan	    goto ignored;
4532169699Skan
4533169699Skan	  /* A type variant isn't good enough, since we don't a cast
4534169699Skan	     to such a type removed as a no-op.  */
4535169699Skan	  *node = type = build_duplicate_type (type);
4536169699Skan	}
4537169699Skan
4538169699Skan      TYPE_TRANSPARENT_UNION (type) = 1;
4539169699Skan      return NULL_TREE;
4540117404Skan    }
4541117404Skan
4542169699Skan ignored:
4543169699Skan  warning (OPT_Wattributes, "%qE attribute ignored", name);
4544117404Skan  return NULL_TREE;
4545117404Skan}
4546117404Skan
4547117404Skan/* Handle a "constructor" attribute; arguments as in
4548117404Skan   struct attribute_spec.handler.  */
4549117404Skan
4550117404Skanstatic tree
4551132728Skanhandle_constructor_attribute (tree *node, tree name,
4552169699Skan			      tree ARG_UNUSED (args),
4553169699Skan			      int ARG_UNUSED (flags),
4554132728Skan			      bool *no_add_attrs)
4555117404Skan{
4556117404Skan  tree decl = *node;
4557117404Skan  tree type = TREE_TYPE (decl);
4558117404Skan
4559117404Skan  if (TREE_CODE (decl) == FUNCTION_DECL
4560117404Skan      && TREE_CODE (type) == FUNCTION_TYPE
4561117404Skan      && decl_function_context (decl) == 0)
4562117404Skan    {
4563117404Skan      DECL_STATIC_CONSTRUCTOR (decl) = 1;
4564117404Skan      TREE_USED (decl) = 1;
4565117404Skan    }
4566117404Skan  else
4567117404Skan    {
4568169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4569117404Skan      *no_add_attrs = true;
4570117404Skan    }
4571117404Skan
4572117404Skan  return NULL_TREE;
4573117404Skan}
4574117404Skan
4575117404Skan/* Handle a "destructor" attribute; arguments as in
4576117404Skan   struct attribute_spec.handler.  */
4577117404Skan
4578117404Skanstatic tree
4579132728Skanhandle_destructor_attribute (tree *node, tree name,
4580169699Skan			     tree ARG_UNUSED (args),
4581169699Skan			     int ARG_UNUSED (flags),
4582132728Skan			     bool *no_add_attrs)
4583117404Skan{
4584117404Skan  tree decl = *node;
4585117404Skan  tree type = TREE_TYPE (decl);
4586117404Skan
4587117404Skan  if (TREE_CODE (decl) == FUNCTION_DECL
4588117404Skan      && TREE_CODE (type) == FUNCTION_TYPE
4589117404Skan      && decl_function_context (decl) == 0)
4590117404Skan    {
4591117404Skan      DECL_STATIC_DESTRUCTOR (decl) = 1;
4592117404Skan      TREE_USED (decl) = 1;
4593117404Skan    }
4594117404Skan  else
4595117404Skan    {
4596169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4597117404Skan      *no_add_attrs = true;
4598117404Skan    }
4599117404Skan
4600117404Skan  return NULL_TREE;
4601117404Skan}
4602117404Skan
4603117404Skan/* Handle a "mode" attribute; arguments as in
4604117404Skan   struct attribute_spec.handler.  */
4605117404Skan
4606117404Skanstatic tree
4607169699Skanhandle_mode_attribute (tree *node, tree name, tree args,
4608169699Skan		       int ARG_UNUSED (flags), bool *no_add_attrs)
4609117404Skan{
4610117404Skan  tree type = *node;
4611117404Skan
4612117404Skan  *no_add_attrs = true;
4613117404Skan
4614117404Skan  if (TREE_CODE (TREE_VALUE (args)) != IDENTIFIER_NODE)
4615169699Skan    warning (OPT_Wattributes, "%qE attribute ignored", name);
4616117404Skan  else
4617117404Skan    {
4618117404Skan      int j;
4619117404Skan      const char *p = IDENTIFIER_POINTER (TREE_VALUE (args));
4620117404Skan      int len = strlen (p);
4621117404Skan      enum machine_mode mode = VOIDmode;
4622117404Skan      tree typefm;
4623169699Skan      bool valid_mode;
4624117404Skan
4625117404Skan      if (len > 4 && p[0] == '_' && p[1] == '_'
4626117404Skan	  && p[len - 1] == '_' && p[len - 2] == '_')
4627117404Skan	{
4628169699Skan	  char *newp = (char *) alloca (len - 1);
4629117404Skan
4630117404Skan	  strcpy (newp, &p[2]);
4631117404Skan	  newp[len - 4] = '\0';
4632117404Skan	  p = newp;
4633117404Skan	}
4634117404Skan
4635117404Skan      /* Change this type to have a type with the specified mode.
4636117404Skan	 First check for the special modes.  */
4637169699Skan      if (!strcmp (p, "byte"))
4638117404Skan	mode = byte_mode;
4639117404Skan      else if (!strcmp (p, "word"))
4640117404Skan	mode = word_mode;
4641169699Skan      else if (!strcmp (p, "pointer"))
4642117404Skan	mode = ptr_mode;
4643117404Skan      else
4644117404Skan	for (j = 0; j < NUM_MACHINE_MODES; j++)
4645117404Skan	  if (!strcmp (p, GET_MODE_NAME (j)))
4646146908Skan	    {
4647146908Skan	      mode = (enum machine_mode) j;
4648146908Skan	      break;
4649146908Skan	    }
4650117404Skan
4651117404Skan      if (mode == VOIDmode)
4652117404Skan	{
4653169699Skan	  error ("unknown machine mode %qs", p);
4654169699Skan	  return NULL_TREE;
4655169699Skan	}
4656169699Skan
4657169699Skan      valid_mode = false;
4658169699Skan      switch (GET_MODE_CLASS (mode))
4659169699Skan	{
4660169699Skan	case MODE_INT:
4661169699Skan	case MODE_PARTIAL_INT:
4662169699Skan	case MODE_FLOAT:
4663169699Skan	case MODE_DECIMAL_FLOAT:
4664169699Skan	  valid_mode = targetm.scalar_mode_supported_p (mode);
4665169699Skan	  break;
4666169699Skan
4667169699Skan	case MODE_COMPLEX_INT:
4668169699Skan	case MODE_COMPLEX_FLOAT:
4669169699Skan	  valid_mode = targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
4670169699Skan	  break;
4671169699Skan
4672169699Skan	case MODE_VECTOR_INT:
4673169699Skan	case MODE_VECTOR_FLOAT:
4674169699Skan	  warning (OPT_Wattributes, "specifying vector types with "
4675169699Skan		   "__attribute__ ((mode)) is deprecated");
4676169699Skan	  warning (OPT_Wattributes,
4677169699Skan		   "use __attribute__ ((vector_size)) instead");
4678169699Skan	  valid_mode = vector_mode_valid_p (mode);
4679169699Skan	  break;
4680169699Skan
4681169699Skan	default:
4682169699Skan	  break;
4683169699Skan	}
4684169699Skan      if (!valid_mode)
4685169699Skan	{
4686169699Skan	  error ("unable to emulate %qs", p);
4687169699Skan	  return NULL_TREE;
4688169699Skan	}
4689169699Skan
4690169699Skan      if (POINTER_TYPE_P (type))
4691169699Skan	{
4692169699Skan	  tree (*fn)(tree, enum machine_mode, bool);
4693169699Skan
4694169699Skan	  if (!targetm.valid_pointer_mode (mode))
4695117404Skan	    {
4696169699Skan	      error ("invalid pointer mode %qs", p);
4697117404Skan	      return NULL_TREE;
4698117404Skan	    }
4699117404Skan
4700132728Skan	  if (TREE_CODE (type) == POINTER_TYPE)
4701169699Skan	    fn = build_pointer_type_for_mode;
4702169699Skan	  else
4703169699Skan	    fn = build_reference_type_for_mode;
4704169699Skan	  typefm = fn (TREE_TYPE (type), mode, false);
4705169699Skan	}
4706169699Skan      else
4707169699Skan	typefm = lang_hooks.types.type_for_mode (mode, TYPE_UNSIGNED (type));
4708169699Skan
4709169699Skan      if (typefm == NULL_TREE)
4710169699Skan	{
4711169699Skan	  error ("no data type for mode %qs", p);
4712169699Skan	  return NULL_TREE;
4713169699Skan	}
4714169699Skan      else if (TREE_CODE (type) == ENUMERAL_TYPE)
4715169699Skan	{
4716169699Skan	  /* For enumeral types, copy the precision from the integer
4717169699Skan	     type returned above.  If not an INTEGER_TYPE, we can't use
4718169699Skan	     this mode for this type.  */
4719169699Skan	  if (TREE_CODE (typefm) != INTEGER_TYPE)
4720132728Skan	    {
4721169699Skan	      error ("cannot use mode %qs for enumeral types", p);
4722169699Skan	      return NULL_TREE;
4723132728Skan	    }
4724169699Skan
4725169699Skan	  if (flags & ATTR_FLAG_TYPE_IN_PLACE)
4726132728Skan	    {
4727146908Skan	      TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
4728169699Skan	      typefm = type;
4729146908Skan	    }
4730169699Skan	  else
4731146908Skan	    {
4732169699Skan	      /* We cannot build a type variant, as there's code that assumes
4733169699Skan		 that TYPE_MAIN_VARIANT has the same mode.  This includes the
4734169699Skan		 debug generators.  Instead, create a subrange type.  This
4735169699Skan		 results in all of the enumeral values being emitted only once
4736169699Skan		 in the original, and the subtype gets them by reference.  */
4737169699Skan	      if (TYPE_UNSIGNED (type))
4738169699Skan		typefm = make_unsigned_type (TYPE_PRECISION (typefm));
4739169699Skan	      else
4740169699Skan		typefm = make_signed_type (TYPE_PRECISION (typefm));
4741169699Skan	      TREE_TYPE (typefm) = type;
4742146908Skan	    }
4743169699Skan	}
4744169699Skan      else if (VECTOR_MODE_P (mode)
4745169699Skan	       ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm))
4746169699Skan	       : TREE_CODE (type) != TREE_CODE (typefm))
4747169699Skan	{
4748169699Skan	  error ("mode %qs applied to inappropriate type", p);
4749169699Skan	  return NULL_TREE;
4750169699Skan	}
4751146908Skan
4752169699Skan      *node = typefm;
4753117404Skan    }
4754117404Skan
4755117404Skan  return NULL_TREE;
4756117404Skan}
4757117404Skan
4758117404Skan/* Handle a "section" attribute; arguments as in
4759117404Skan   struct attribute_spec.handler.  */
4760117404Skan
4761117404Skanstatic tree
4762169699Skanhandle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args,
4763169699Skan			  int ARG_UNUSED (flags), bool *no_add_attrs)
4764117404Skan{
4765117404Skan  tree decl = *node;
4766117404Skan
4767117404Skan  if (targetm.have_named_sections)
4768117404Skan    {
4769169699Skan      user_defined_section_attribute = true;
4770169699Skan
4771117404Skan      if ((TREE_CODE (decl) == FUNCTION_DECL
4772117404Skan	   || TREE_CODE (decl) == VAR_DECL)
4773117404Skan	  && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
4774117404Skan	{
4775117404Skan	  if (TREE_CODE (decl) == VAR_DECL
4776117404Skan	      && current_function_decl != NULL_TREE
4777169699Skan	      && !TREE_STATIC (decl))
4778117404Skan	    {
4779132728Skan	      error ("%Jsection attribute cannot be specified for "
4780169699Skan		     "local variables", decl);
4781117404Skan	      *no_add_attrs = true;
4782117404Skan	    }
4783117404Skan
4784117404Skan	  /* The decl may have already been given a section attribute
4785117404Skan	     from a previous declaration.  Ensure they match.  */
4786117404Skan	  else if (DECL_SECTION_NAME (decl) != NULL_TREE
4787117404Skan		   && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
4788117404Skan			      TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
4789117404Skan	    {
4790169699Skan	      error ("section of %q+D conflicts with previous declaration",
4791169699Skan		     *node);
4792117404Skan	      *no_add_attrs = true;
4793117404Skan	    }
4794117404Skan	  else
4795117404Skan	    DECL_SECTION_NAME (decl) = TREE_VALUE (args);
4796117404Skan	}
4797117404Skan      else
4798117404Skan	{
4799169699Skan	  error ("section attribute not allowed for %q+D", *node);
4800117404Skan	  *no_add_attrs = true;
4801117404Skan	}
4802117404Skan    }
4803117404Skan  else
4804117404Skan    {
4805132728Skan      error ("%Jsection attributes are not supported for this target", *node);
4806117404Skan      *no_add_attrs = true;
4807117404Skan    }
4808117404Skan
4809117404Skan  return NULL_TREE;
4810117404Skan}
4811117404Skan
4812117404Skan/* Handle a "aligned" attribute; arguments as in
4813117404Skan   struct attribute_spec.handler.  */
4814117404Skan
4815117404Skanstatic tree
4816169699Skanhandle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
4817132728Skan			  int flags, bool *no_add_attrs)
4818117404Skan{
4819117404Skan  tree decl = NULL_TREE;
4820117404Skan  tree *type = NULL;
4821117404Skan  int is_type = 0;
4822117404Skan  tree align_expr = (args ? TREE_VALUE (args)
4823117404Skan		     : size_int (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
4824117404Skan  int i;
4825117404Skan
4826117404Skan  if (DECL_P (*node))
4827117404Skan    {
4828117404Skan      decl = *node;
4829117404Skan      type = &TREE_TYPE (decl);
4830117404Skan      is_type = TREE_CODE (*node) == TYPE_DECL;
4831117404Skan    }
4832117404Skan  else if (TYPE_P (*node))
4833117404Skan    type = node, is_type = 1;
4834117404Skan
4835117404Skan  if (TREE_CODE (align_expr) != INTEGER_CST)
4836117404Skan    {
4837117404Skan      error ("requested alignment is not a constant");
4838117404Skan      *no_add_attrs = true;
4839117404Skan    }
4840117404Skan  else if ((i = tree_log2 (align_expr)) == -1)
4841117404Skan    {
4842117404Skan      error ("requested alignment is not a power of 2");
4843117404Skan      *no_add_attrs = true;
4844117404Skan    }
4845117404Skan  else if (i > HOST_BITS_PER_INT - 2)
4846117404Skan    {
4847117404Skan      error ("requested alignment is too large");
4848117404Skan      *no_add_attrs = true;
4849117404Skan    }
4850117404Skan  else if (is_type)
4851117404Skan    {
4852117404Skan      /* If we have a TYPE_DECL, then copy the type, so that we
4853117404Skan	 don't accidentally modify a builtin type.  See pushdecl.  */
4854117404Skan      if (decl && TREE_TYPE (decl) != error_mark_node
4855117404Skan	  && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
4856117404Skan	{
4857117404Skan	  tree tt = TREE_TYPE (decl);
4858169699Skan	  *type = build_variant_type_copy (*type);
4859117404Skan	  DECL_ORIGINAL_TYPE (decl) = tt;
4860117404Skan	  TYPE_NAME (*type) = decl;
4861117404Skan	  TREE_USED (*type) = TREE_USED (decl);
4862117404Skan	  TREE_TYPE (decl) = *type;
4863117404Skan	}
4864117404Skan      else if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
4865169699Skan	*type = build_variant_type_copy (*type);
4866117404Skan
4867117404Skan      TYPE_ALIGN (*type) = (1 << i) * BITS_PER_UNIT;
4868117404Skan      TYPE_USER_ALIGN (*type) = 1;
4869117404Skan    }
4870259694Spfg  else if (! VAR_OR_FUNCTION_DECL_P (decl)
4871260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4872260918Spfg	   && TREE_CODE (decl) != FIELD_DECL
4873260918Spfg	   && TREE_CODE (decl) != LABEL_DECL)
4874260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4875117404Skan    {
4876169699Skan      error ("alignment may not be specified for %q+D", decl);
4877117404Skan      *no_add_attrs = true;
4878117404Skan    }
4879259694Spfg  else if (TREE_CODE (decl) == FUNCTION_DECL
4880259694Spfg	   && DECL_ALIGN (decl) > (1 << i) * BITS_PER_UNIT)
4881259694Spfg    {
4882259694Spfg      if (DECL_USER_ALIGN (decl))
4883259694Spfg	error ("alignment for %q+D was previously specified as %d "
4884259694Spfg	       "and may not be decreased", decl,
4885259694Spfg	       DECL_ALIGN (decl) / BITS_PER_UNIT);
4886259694Spfg      else
4887259694Spfg	error ("alignment for %q+D must be at least %d", decl,
4888259694Spfg	       DECL_ALIGN (decl) / BITS_PER_UNIT);
4889259694Spfg      *no_add_attrs = true;
4890259694Spfg    }
4891117404Skan  else
4892117404Skan    {
4893117404Skan      DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT;
4894117404Skan      DECL_USER_ALIGN (decl) = 1;
4895117404Skan    }
4896117404Skan
4897117404Skan  return NULL_TREE;
4898117404Skan}
4899117404Skan
4900117404Skan/* Handle a "weak" attribute; arguments as in
4901117404Skan   struct attribute_spec.handler.  */
4902117404Skan
4903117404Skanstatic tree
4904169699Skanhandle_weak_attribute (tree *node, tree name,
4905169699Skan		       tree ARG_UNUSED (args),
4906169699Skan		       int ARG_UNUSED (flags),
4907169699Skan		       bool * ARG_UNUSED (no_add_attrs))
4908117404Skan{
4909169699Skan  if (TREE_CODE (*node) == FUNCTION_DECL
4910169699Skan      || TREE_CODE (*node) == VAR_DECL)
4911169699Skan    declare_weak (*node);
4912261188Spfg  /* APPLE LOCAL begin weak types 5954418 */
4913261188Spfg  else if (!DECL_P (*node)
4914261188Spfg	   /* If the weak flag can be associated with something else,
4915261188Spfg	      prefer that. */
4916261188Spfg	   && (flags & (ATTR_FLAG_FUNCTION_NEXT
4917261188Spfg			|ATTR_FLAG_DECL_NEXT
4918261188Spfg			|ATTR_FLAG_ARRAY_NEXT)))
4919261188Spfg    {
4920261188Spfg      *no_add_attrs = true;
4921261188Spfg      return tree_cons (name, args, NULL_TREE);
4922261188Spfg    }
4923261188Spfg  else if (! targetm.cxx.class_data_always_comdat ()
4924261188Spfg	   && TREE_CODE (*node) == RECORD_TYPE)
4925261188Spfg    {
4926261188Spfg      /* Leave on the type for the C++ front end */
4927261188Spfg    }
4928261188Spfg  /* APPLE LOCAL end weak types 5954418 */
4929169699Skan  else
4930169699Skan    warning (OPT_Wattributes, "%qE attribute ignored", name);
4931169699Skan
4932117404Skan
4933117404Skan  return NULL_TREE;
4934117404Skan}
4935117404Skan
4936117404Skan/* Handle an "alias" attribute; arguments as in
4937117404Skan   struct attribute_spec.handler.  */
4938117404Skan
4939117404Skanstatic tree
4940132728Skanhandle_alias_attribute (tree *node, tree name, tree args,
4941169699Skan			int ARG_UNUSED (flags), bool *no_add_attrs)
4942117404Skan{
4943117404Skan  tree decl = *node;
4944117404Skan
4945117404Skan  if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
4946169699Skan      || (TREE_CODE (decl) != FUNCTION_DECL
4947169699Skan	  && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
4948169699Skan      /* A static variable declaration is always a tentative definition,
4949169699Skan	 but the alias is a non-tentative definition which overrides.  */
4950169699Skan      || (TREE_CODE (decl) != FUNCTION_DECL
4951169699Skan	  && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl)))
4952117404Skan    {
4953169699Skan      error ("%q+D defined both normally and as an alias", decl);
4954117404Skan      *no_add_attrs = true;
4955117404Skan    }
4956169699Skan
4957169699Skan  /* Note that the very first time we process a nested declaration,
4958169699Skan     decl_function_context will not be set.  Indeed, *would* never
4959169699Skan     be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that
4960169699Skan     we do below.  After such frobbery, pushdecl would set the context.
4961169699Skan     In any case, this is never what we want.  */
4962169699Skan  else if (decl_function_context (decl) == 0 && current_function_decl == NULL)
4963117404Skan    {
4964117404Skan      tree id;
4965117404Skan
4966117404Skan      id = TREE_VALUE (args);
4967117404Skan      if (TREE_CODE (id) != STRING_CST)
4968117404Skan	{
4969169699Skan	  error ("alias argument not a string");
4970117404Skan	  *no_add_attrs = true;
4971117404Skan	  return NULL_TREE;
4972117404Skan	}
4973117404Skan      id = get_identifier (TREE_STRING_POINTER (id));
4974117404Skan      /* This counts as a use of the object pointed to.  */
4975117404Skan      TREE_USED (id) = 1;
4976117404Skan
4977117404Skan      if (TREE_CODE (decl) == FUNCTION_DECL)
4978117404Skan	DECL_INITIAL (decl) = error_mark_node;
4979117404Skan      else
4980169699Skan	{
4981169699Skan	  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
4982169699Skan	    DECL_EXTERNAL (decl) = 1;
4983169699Skan	  else
4984169699Skan	    DECL_EXTERNAL (decl) = 0;
4985169699Skan	  TREE_STATIC (decl) = 1;
4986169699Skan	}
4987117404Skan    }
4988117404Skan  else
4989117404Skan    {
4990169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
4991117404Skan      *no_add_attrs = true;
4992117404Skan    }
4993117404Skan
4994117404Skan  return NULL_TREE;
4995117404Skan}
4996117404Skan
4997169699Skan/* Handle a "weakref" attribute; arguments as in struct
4998169699Skan   attribute_spec.handler.  */
4999169699Skan
5000169699Skanstatic tree
5001169699Skanhandle_weakref_attribute (tree *node, tree ARG_UNUSED (name), tree args,
5002169699Skan			  int flags, bool *no_add_attrs)
5003169699Skan{
5004169699Skan  tree attr = NULL_TREE;
5005169699Skan
5006169699Skan  /* We must ignore the attribute when it is associated with
5007169699Skan     local-scoped decls, since attribute alias is ignored and many
5008169699Skan     such symbols do not even have a DECL_WEAK field.  */
5009169699Skan  if (decl_function_context (*node) || current_function_decl)
5010169699Skan    {
5011169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
5012169699Skan      *no_add_attrs = true;
5013169699Skan      return NULL_TREE;
5014169699Skan    }
5015169699Skan
5016169699Skan  /* The idea here is that `weakref("name")' mutates into `weakref,
5017169699Skan     alias("name")', and weakref without arguments, in turn,
5018169699Skan     implicitly adds weak. */
5019169699Skan
5020169699Skan  if (args)
5021169699Skan    {
5022169699Skan      attr = tree_cons (get_identifier ("alias"), args, attr);
5023169699Skan      attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr);
5024169699Skan
5025169699Skan      *no_add_attrs = true;
5026169699Skan
5027169699Skan      decl_attributes (node, attr, flags);
5028169699Skan    }
5029169699Skan  else
5030169699Skan    {
5031169699Skan      if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node)))
5032169699Skan	error ("%Jweakref attribute must appear before alias attribute",
5033169699Skan	       *node);
5034169699Skan
5035169699Skan      /* Can't call declare_weak because it wants this to be TREE_PUBLIC,
5036169699Skan	 and that isn't supported; and because it wants to add it to
5037169699Skan	 the list of weak decls, which isn't helpful.  */
5038169699Skan      DECL_WEAK (*node) = 1;
5039169699Skan    }
5040169699Skan
5041169699Skan  return NULL_TREE;
5042169699Skan}
5043169699Skan
5044117404Skan/* Handle an "visibility" attribute; arguments as in
5045117404Skan   struct attribute_spec.handler.  */
5046117404Skan
5047117404Skanstatic tree
5048132728Skanhandle_visibility_attribute (tree *node, tree name, tree args,
5049169699Skan			     int ARG_UNUSED (flags),
5050169699Skan			     bool *ARG_UNUSED (no_add_attrs))
5051117404Skan{
5052117404Skan  tree decl = *node;
5053132728Skan  tree id = TREE_VALUE (args);
5054169699Skan  enum symbol_visibility vis;
5055117404Skan
5056169699Skan  if (TYPE_P (*node))
5057117404Skan    {
5058169699Skan      if (TREE_CODE (*node) == ENUMERAL_TYPE)
5059169699Skan	/* OK */;
5060169699Skan      else if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
5061169699Skan	{
5062169699Skan	  warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
5063169699Skan		   name);
5064169699Skan	  return NULL_TREE;
5065169699Skan	}
5066169699Skan      else if (TYPE_FIELDS (*node))
5067169699Skan	{
5068169699Skan	  error ("%qE attribute ignored because %qT is already defined",
5069169699Skan		 name, *node);
5070169699Skan	  return NULL_TREE;
5071169699Skan	}
5072169699Skan    }
5073169699Skan  else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
5074169699Skan    {
5075169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
5076132728Skan      return NULL_TREE;
5077117404Skan    }
5078132728Skan
5079132728Skan  if (TREE_CODE (id) != STRING_CST)
5080117404Skan    {
5081169699Skan      error ("visibility argument not a string");
5082132728Skan      return NULL_TREE;
5083117404Skan    }
5084117404Skan
5085169699Skan  /*  If this is a type, set the visibility on the type decl.  */
5086169699Skan  if (TYPE_P (decl))
5087169699Skan    {
5088169699Skan      decl = TYPE_NAME (decl);
5089169699Skan      if (!decl)
5090169699Skan	return NULL_TREE;
5091169699Skan      if (TREE_CODE (decl) == IDENTIFIER_NODE)
5092169699Skan	{
5093169699Skan	   warning (OPT_Wattributes, "%qE attribute ignored on types",
5094169699Skan		    name);
5095169699Skan	   return NULL_TREE;
5096169699Skan	}
5097169699Skan    }
5098169699Skan
5099132728Skan  if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
5100169699Skan    vis = VISIBILITY_DEFAULT;
5101132728Skan  else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
5102169699Skan    vis = VISIBILITY_INTERNAL;
5103132728Skan  else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
5104169699Skan    vis = VISIBILITY_HIDDEN;
5105132728Skan  else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
5106169699Skan    vis = VISIBILITY_PROTECTED;
5107132728Skan  else
5108169699Skan    {
5109169699Skan      error ("visibility argument must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
5110169699Skan      vis = VISIBILITY_DEFAULT;
5111169699Skan    }
5112132728Skan
5113169699Skan  if (DECL_VISIBILITY_SPECIFIED (decl)
5114169699Skan      && vis != DECL_VISIBILITY (decl)
5115169699Skan      && lookup_attribute ("visibility", (TYPE_P (*node)
5116169699Skan					  ? TYPE_ATTRIBUTES (*node)
5117169699Skan					  : DECL_ATTRIBUTES (decl))))
5118169699Skan    error ("%qD redeclared with different visibility", decl);
5119169699Skan
5120169699Skan  DECL_VISIBILITY (decl) = vis;
5121169699Skan  DECL_VISIBILITY_SPECIFIED (decl) = 1;
5122169699Skan
5123169699Skan  /* Go ahead and attach the attribute to the node as well.  This is needed
5124169699Skan     so we can determine whether we have VISIBILITY_DEFAULT because the
5125169699Skan     visibility was not specified, or because it was explicitly overridden
5126169699Skan     from the containing scope.  */
5127169699Skan
5128117404Skan  return NULL_TREE;
5129117404Skan}
5130117404Skan
5131169699Skan/* Determine the ELF symbol visibility for DECL, which is either a
5132169699Skan   variable or a function.  It is an error to use this function if a
5133169699Skan   definition of DECL is not available in this translation unit.
5134169699Skan   Returns true if the final visibility has been determined by this
5135169699Skan   function; false if the caller is free to make additional
5136169699Skan   modifications.  */
5137169699Skan
5138169699Skanbool
5139169699Skanc_determine_visibility (tree decl)
5140169699Skan{
5141169699Skan  gcc_assert (TREE_CODE (decl) == VAR_DECL
5142169699Skan	      || TREE_CODE (decl) == FUNCTION_DECL);
5143169699Skan
5144169699Skan  /* If the user explicitly specified the visibility with an
5145169699Skan     attribute, honor that.  DECL_VISIBILITY will have been set during
5146169699Skan     the processing of the attribute.  We check for an explicit
5147169699Skan     attribute, rather than just checking DECL_VISIBILITY_SPECIFIED,
5148169699Skan     to distinguish the use of an attribute from the use of a "#pragma
5149169699Skan     GCC visibility push(...)"; in the latter case we still want other
5150169699Skan     considerations to be able to overrule the #pragma.  */
5151169699Skan  if (lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)))
5152169699Skan    return true;
5153169699Skan
5154169699Skan  /* Anything that is exported must have default visibility.  */
5155169699Skan  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
5156169699Skan      && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
5157169699Skan    {
5158169699Skan      DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5159169699Skan      DECL_VISIBILITY_SPECIFIED (decl) = 1;
5160169699Skan      return true;
5161169699Skan    }
5162169699Skan
5163169699Skan  /* Set default visibility to whatever the user supplied with
5164169699Skan     visibility_specified depending on #pragma GCC visibility.  */
5165169699Skan  if (!DECL_VISIBILITY_SPECIFIED (decl))
5166169699Skan    {
5167169699Skan      DECL_VISIBILITY (decl) = default_visibility;
5168169699Skan      DECL_VISIBILITY_SPECIFIED (decl) = visibility_options.inpragma;
5169169699Skan    }
5170169699Skan  return false;
5171169699Skan}
5172169699Skan
5173117404Skan/* Handle an "tls_model" attribute; arguments as in
5174117404Skan   struct attribute_spec.handler.  */
5175117404Skan
5176117404Skanstatic tree
5177132728Skanhandle_tls_model_attribute (tree *node, tree name, tree args,
5178169699Skan			    int ARG_UNUSED (flags), bool *no_add_attrs)
5179117404Skan{
5180169699Skan  tree id;
5181117404Skan  tree decl = *node;
5182169699Skan  enum tls_model kind;
5183117404Skan
5184169699Skan  *no_add_attrs = true;
5185169699Skan
5186169699Skan  if (!DECL_THREAD_LOCAL_P (decl))
5187117404Skan    {
5188169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
5189169699Skan      return NULL_TREE;
5190117404Skan    }
5191169699Skan
5192169699Skan  kind = DECL_TLS_MODEL (decl);
5193169699Skan  id = TREE_VALUE (args);
5194169699Skan  if (TREE_CODE (id) != STRING_CST)
5195117404Skan    {
5196169699Skan      error ("tls_model argument not a string");
5197169699Skan      return NULL_TREE;
5198117404Skan    }
5199117404Skan
5200169699Skan  if (!strcmp (TREE_STRING_POINTER (id), "local-exec"))
5201169699Skan    kind = TLS_MODEL_LOCAL_EXEC;
5202169699Skan  else if (!strcmp (TREE_STRING_POINTER (id), "initial-exec"))
5203169699Skan    kind = TLS_MODEL_INITIAL_EXEC;
5204169699Skan  else if (!strcmp (TREE_STRING_POINTER (id), "local-dynamic"))
5205169699Skan    kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC;
5206169699Skan  else if (!strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
5207169699Skan    kind = TLS_MODEL_GLOBAL_DYNAMIC;
5208169699Skan  else
5209169699Skan    error ("tls_model argument must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\"");
5210169699Skan
5211169699Skan  DECL_TLS_MODEL (decl) = kind;
5212117404Skan  return NULL_TREE;
5213117404Skan}
5214117404Skan
5215117404Skan/* Handle a "no_instrument_function" attribute; arguments as in
5216117404Skan   struct attribute_spec.handler.  */
5217117404Skan
5218117404Skanstatic tree
5219132728Skanhandle_no_instrument_function_attribute (tree *node, tree name,
5220169699Skan					 tree ARG_UNUSED (args),
5221169699Skan					 int ARG_UNUSED (flags),
5222132728Skan					 bool *no_add_attrs)
5223117404Skan{
5224117404Skan  tree decl = *node;
5225117404Skan
5226117404Skan  if (TREE_CODE (decl) != FUNCTION_DECL)
5227117404Skan    {
5228169699Skan      error ("%J%qE attribute applies only to functions", decl, name);
5229117404Skan      *no_add_attrs = true;
5230117404Skan    }
5231117404Skan  else if (DECL_INITIAL (decl))
5232117404Skan    {
5233169699Skan      error ("%Jcan%'t set %qE attribute after definition", decl, name);
5234117404Skan      *no_add_attrs = true;
5235117404Skan    }
5236117404Skan  else
5237117404Skan    DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
5238117404Skan
5239117404Skan  return NULL_TREE;
5240117404Skan}
5241117404Skan
5242117404Skan/* Handle a "malloc" attribute; arguments as in
5243117404Skan   struct attribute_spec.handler.  */
5244117404Skan
5245117404Skanstatic tree
5246169699Skanhandle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args),
5247169699Skan			 int ARG_UNUSED (flags), bool *no_add_attrs)
5248117404Skan{
5249169699Skan  if (TREE_CODE (*node) == FUNCTION_DECL
5250169699Skan      && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
5251117404Skan    DECL_IS_MALLOC (*node) = 1;
5252117404Skan  else
5253117404Skan    {
5254169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
5255117404Skan      *no_add_attrs = true;
5256117404Skan    }
5257117404Skan
5258117404Skan  return NULL_TREE;
5259117404Skan}
5260117404Skan
5261169699Skan/* Handle a "returns_twice" attribute; arguments as in
5262169699Skan   struct attribute_spec.handler.  */
5263169699Skan
5264169699Skanstatic tree
5265169699Skanhandle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args),
5266169699Skan			 int ARG_UNUSED (flags), bool *no_add_attrs)
5267169699Skan{
5268169699Skan  if (TREE_CODE (*node) == FUNCTION_DECL)
5269169699Skan    DECL_IS_RETURNS_TWICE (*node) = 1;
5270169699Skan  else
5271169699Skan    {
5272169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
5273169699Skan      *no_add_attrs = true;
5274169699Skan    }
5275169699Skan
5276169699Skan  return NULL_TREE;
5277169699Skan}
5278169699Skan
5279117404Skan/* Handle a "no_limit_stack" attribute; arguments as in
5280117404Skan   struct attribute_spec.handler.  */
5281117404Skan
5282117404Skanstatic tree
5283132728Skanhandle_no_limit_stack_attribute (tree *node, tree name,
5284169699Skan				 tree ARG_UNUSED (args),
5285169699Skan				 int ARG_UNUSED (flags),
5286132728Skan				 bool *no_add_attrs)
5287117404Skan{
5288117404Skan  tree decl = *node;
5289117404Skan
5290117404Skan  if (TREE_CODE (decl) != FUNCTION_DECL)
5291117404Skan    {
5292169699Skan      error ("%J%qE attribute applies only to functions", decl, name);
5293117404Skan      *no_add_attrs = true;
5294117404Skan    }
5295117404Skan  else if (DECL_INITIAL (decl))
5296117404Skan    {
5297169699Skan      error ("%Jcan%'t set %qE attribute after definition", decl, name);
5298117404Skan      *no_add_attrs = true;
5299117404Skan    }
5300117404Skan  else
5301117404Skan    DECL_NO_LIMIT_STACK (decl) = 1;
5302117404Skan
5303117404Skan  return NULL_TREE;
5304117404Skan}
5305117404Skan
5306117404Skan/* Handle a "pure" attribute; arguments as in
5307117404Skan   struct attribute_spec.handler.  */
5308117404Skan
5309117404Skanstatic tree
5310169699Skanhandle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args),
5311169699Skan		       int ARG_UNUSED (flags), bool *no_add_attrs)
5312117404Skan{
5313117404Skan  if (TREE_CODE (*node) == FUNCTION_DECL)
5314117404Skan    DECL_IS_PURE (*node) = 1;
5315117404Skan  /* ??? TODO: Support types.  */
5316117404Skan  else
5317117404Skan    {
5318169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
5319117404Skan      *no_add_attrs = true;
5320117404Skan    }
5321117404Skan
5322117404Skan  return NULL_TREE;
5323117404Skan}
5324117404Skan
5325169699Skan/* Handle a "no vops" attribute; arguments as in
5326169699Skan   struct attribute_spec.handler.  */
5327169699Skan
5328169699Skanstatic tree
5329169699Skanhandle_novops_attribute (tree *node, tree ARG_UNUSED (name),
5330169699Skan			 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
5331169699Skan			 bool *ARG_UNUSED (no_add_attrs))
5332169699Skan{
5333169699Skan  gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
5334169699Skan  DECL_IS_NOVOPS (*node) = 1;
5335169699Skan  return NULL_TREE;
5336169699Skan}
5337169699Skan
5338132728Skan/* Handle a "deprecated" attribute; arguments as in
5339117404Skan   struct attribute_spec.handler.  */
5340117404Skan
5341117404Skanstatic tree
5342132728Skanhandle_deprecated_attribute (tree *node, tree name,
5343169699Skan			     tree ARG_UNUSED (args), int flags,
5344132728Skan			     bool *no_add_attrs)
5345117404Skan{
5346117404Skan  tree type = NULL_TREE;
5347117404Skan  int warn = 0;
5348169699Skan  tree what = NULL_TREE;
5349132728Skan
5350117404Skan  if (DECL_P (*node))
5351117404Skan    {
5352117404Skan      tree decl = *node;
5353117404Skan      type = TREE_TYPE (decl);
5354132728Skan
5355117404Skan      if (TREE_CODE (decl) == TYPE_DECL
5356117404Skan	  || TREE_CODE (decl) == PARM_DECL
5357117404Skan	  || TREE_CODE (decl) == VAR_DECL
5358117404Skan	  || TREE_CODE (decl) == FUNCTION_DECL
5359117404Skan	  || TREE_CODE (decl) == FIELD_DECL)
5360117404Skan	TREE_DEPRECATED (decl) = 1;
5361117404Skan      else
5362117404Skan	warn = 1;
5363117404Skan    }
5364117404Skan  else if (TYPE_P (*node))
5365117404Skan    {
5366117404Skan      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
5367169699Skan	*node = build_variant_type_copy (*node);
5368117404Skan      TREE_DEPRECATED (*node) = 1;
5369117404Skan      type = *node;
5370117404Skan    }
5371117404Skan  else
5372117404Skan    warn = 1;
5373132728Skan
5374117404Skan  if (warn)
5375117404Skan    {
5376117404Skan      *no_add_attrs = true;
5377117404Skan      if (type && TYPE_NAME (type))
5378117404Skan	{
5379117404Skan	  if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
5380169699Skan	    what = TYPE_NAME (*node);
5381117404Skan	  else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
5382117404Skan		   && DECL_NAME (TYPE_NAME (type)))
5383169699Skan	    what = DECL_NAME (TYPE_NAME (type));
5384117404Skan	}
5385117404Skan      if (what)
5386169699Skan	warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what);
5387117404Skan      else
5388169699Skan	warning (OPT_Wattributes, "%qE attribute ignored", name);
5389117404Skan    }
5390117404Skan
5391117404Skan  return NULL_TREE;
5392117404Skan}
5393117404Skan
5394260918Spfg/* APPLE LOCAL begin "unavailable" attribute (Radar 2809697) --ilr */
5395260918Spfg/* Handle a "unavailable" attribute; arguments as in
5396260918Spfg   struct attribute_spec.handler.  */
5397260918Spfg
5398260918Spfgstatic tree
5399260918Spfghandle_unavailable_attribute (tree *node, tree name,
5400260918Spfg			      tree args ATTRIBUTE_UNUSED,
5401260918Spfg			      int flags ATTRIBUTE_UNUSED,
5402260918Spfg			      bool *no_add_attrs)
5403260918Spfg{
5404260918Spfg  tree type = NULL_TREE;
5405260918Spfg  int warn = 0;
5406260918Spfg  const char *what = NULL;
5407260918Spfg
5408260918Spfg  if (DECL_P (*node))
5409260918Spfg    {
5410260918Spfg      tree decl = *node;
5411260918Spfg      type = TREE_TYPE (decl);
5412260918Spfg
5413260918Spfg      if (TREE_CODE (decl) == TYPE_DECL
5414260918Spfg      	  || TREE_CODE (decl) == PARM_DECL
5415260918Spfg	  || TREE_CODE (decl) == VAR_DECL
5416260918Spfg	  || TREE_CODE (decl) == FUNCTION_DECL
5417261188Spfg	  /* APPLE LOCAL begin radar 3803157 - objc attribute */
5418261188Spfg	  || TREE_CODE (decl) == FIELD_DECL
5419261188Spfg	  || objc_method_decl (TREE_CODE (decl)))
5420261188Spfg	  /* APPLE LOCAL end radar 3803157 - objc attribute */
5421260918Spfg	{
5422260918Spfg	  TREE_UNAVAILABLE (decl) = 1;
5423260918Spfg	}
5424260918Spfg      else
5425260918Spfg	warn = 1;
5426260918Spfg    }
5427260918Spfg  else if (TYPE_P (*node))
5428260918Spfg    {
5429260918Spfg      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
5430260918Spfg	*node = build_variant_type_copy (*node);
5431260918Spfg      TREE_UNAVAILABLE (*node) = 1;
5432260918Spfg      type = *node;
5433260918Spfg    }
5434260918Spfg  else
5435260918Spfg    warn = 1;
5436260918Spfg
5437260918Spfg  if (warn)
5438260918Spfg    {
5439260918Spfg      *no_add_attrs = true;
5440260918Spfg      if (type && TYPE_NAME (type))
5441260918Spfg	{
5442260918Spfg	  if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
5443260918Spfg	    what = IDENTIFIER_POINTER (TYPE_NAME (*node));
5444260918Spfg	  else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
5445260918Spfg		   && DECL_NAME (TYPE_NAME (type)))
5446260918Spfg	    what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
5447260918Spfg	}
5448260918Spfg      if (what)
5449260918Spfg	warning (0, "`%s' attribute ignored for `%s'",
5450260918Spfg		 IDENTIFIER_POINTER (name), what);
5451260918Spfg      else
5452260918Spfg	warning (0, "`%s' attribute ignored", IDENTIFIER_POINTER (name));
5453260918Spfg    }
5454260918Spfg
5455260918Spfg  return NULL_TREE;
5456260918Spfg}
5457260918Spfg/* APPLE LOCAL end "unavailable" attribute --ilr */
5458260918Spfg
5459117404Skan/* Handle a "vector_size" attribute; arguments as in
5460117404Skan   struct attribute_spec.handler.  */
5461117404Skan
5462117404Skanstatic tree
5463132728Skanhandle_vector_size_attribute (tree *node, tree name, tree args,
5464169699Skan			      int ARG_UNUSED (flags),
5465132728Skan			      bool *no_add_attrs)
5466117404Skan{
5467117404Skan  unsigned HOST_WIDE_INT vecsize, nunits;
5468169699Skan  enum machine_mode orig_mode;
5469169699Skan  tree type = *node, new_type, size;
5470117404Skan
5471117404Skan  *no_add_attrs = true;
5472117404Skan
5473169699Skan  size = TREE_VALUE (args);
5474169699Skan
5475169699Skan  if (!host_integerp (size, 1))
5476117404Skan    {
5477169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
5478117404Skan      return NULL_TREE;
5479117404Skan    }
5480117404Skan
5481117404Skan  /* Get the vector size (in bytes).  */
5482169699Skan  vecsize = tree_low_cst (size, 1);
5483117404Skan
5484117404Skan  /* We need to provide for vector pointers, vector arrays, and
5485117404Skan     functions returning vectors.  For example:
5486117404Skan
5487117404Skan       __attribute__((vector_size(16))) short *foo;
5488117404Skan
5489117404Skan     In this case, the mode is SI, but the type being modified is
5490117404Skan     HI, so we need to look further.  */
5491117404Skan
5492117404Skan  while (POINTER_TYPE_P (type)
5493117404Skan	 || TREE_CODE (type) == FUNCTION_TYPE
5494132728Skan	 || TREE_CODE (type) == METHOD_TYPE
5495117404Skan	 || TREE_CODE (type) == ARRAY_TYPE)
5496117404Skan    type = TREE_TYPE (type);
5497117404Skan
5498117404Skan  /* Get the mode of the type being modified.  */
5499117404Skan  orig_mode = TYPE_MODE (type);
5500117404Skan
5501117404Skan  if (TREE_CODE (type) == RECORD_TYPE
5502169699Skan      || TREE_CODE (type) == UNION_TYPE
5503169699Skan      || TREE_CODE (type) == VECTOR_TYPE
5504169699Skan      || (!SCALAR_FLOAT_MODE_P (orig_mode)
5505117404Skan	  && GET_MODE_CLASS (orig_mode) != MODE_INT)
5506169699Skan      || !host_integerp (TYPE_SIZE_UNIT (type), 1))
5507117404Skan    {
5508169699Skan      error ("invalid vector type for attribute %qE", name);
5509117404Skan      return NULL_TREE;
5510117404Skan    }
5511117404Skan
5512169699Skan  if (vecsize % tree_low_cst (TYPE_SIZE_UNIT (type), 1))
5513117404Skan    {
5514169699Skan      error ("vector size not an integral multiple of component size");
5515169699Skan      return NULL;
5516117404Skan    }
5517117404Skan
5518169699Skan  if (vecsize == 0)
5519117404Skan    {
5520169699Skan      error ("zero vector size");
5521169699Skan      return NULL;
5522117404Skan    }
5523117404Skan
5524169699Skan  /* Calculate how many units fit in the vector.  */
5525169699Skan  nunits = vecsize / tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5526169699Skan  if (nunits & (nunits - 1))
5527117404Skan    {
5528169699Skan      error ("number of components of the vector not a power of two");
5529169699Skan      return NULL_TREE;
5530169699Skan    }
5531117404Skan
5532169699Skan  new_type = build_vector_type (type, nunits);
5533117404Skan
5534117404Skan  /* Build back pointers if needed.  */
5535146908Skan  *node = reconstruct_complex_type (*node, new_type);
5536117404Skan
5537117404Skan  return NULL_TREE;
5538117404Skan}
5539117404Skan
5540117404Skan/* Handle the "nonnull" attribute.  */
5541117404Skanstatic tree
5542169699Skanhandle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
5543169699Skan			  tree args, int ARG_UNUSED (flags),
5544132728Skan			  bool *no_add_attrs)
5545117404Skan{
5546117404Skan  tree type = *node;
5547117404Skan  unsigned HOST_WIDE_INT attr_arg_num;
5548117404Skan
5549117404Skan  /* If no arguments are specified, all pointer arguments should be
5550132728Skan     non-null.  Verify a full prototype is given so that the arguments
5551117404Skan     will have the correct types when we actually check them later.  */
5552169699Skan  if (!args)
5553117404Skan    {
5554169699Skan      if (!TYPE_ARG_TYPES (type))
5555117404Skan	{
5556117404Skan	  error ("nonnull attribute without arguments on a non-prototype");
5557169699Skan	  *no_add_attrs = true;
5558117404Skan	}
5559117404Skan      return NULL_TREE;
5560117404Skan    }
5561117404Skan
5562117404Skan  /* Argument list specified.  Verify that each argument number references
5563117404Skan     a pointer argument.  */
5564117404Skan  for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
5565117404Skan    {
5566117404Skan      tree argument;
5567169699Skan      unsigned HOST_WIDE_INT arg_num = 0, ck_num;
5568117404Skan
5569169699Skan      if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
5570117404Skan	{
5571169699Skan	  error ("nonnull argument has invalid operand number (argument %lu)",
5572117404Skan		 (unsigned long) attr_arg_num);
5573117404Skan	  *no_add_attrs = true;
5574117404Skan	  return NULL_TREE;
5575117404Skan	}
5576117404Skan
5577117404Skan      argument = TYPE_ARG_TYPES (type);
5578117404Skan      if (argument)
5579117404Skan	{
5580117404Skan	  for (ck_num = 1; ; ck_num++)
5581117404Skan	    {
5582169699Skan	      if (!argument || ck_num == arg_num)
5583117404Skan		break;
5584117404Skan	      argument = TREE_CHAIN (argument);
5585117404Skan	    }
5586117404Skan
5587169699Skan	  if (!argument
5588117404Skan	      || TREE_CODE (TREE_VALUE (argument)) == VOID_TYPE)
5589117404Skan	    {
5590169699Skan	      error ("nonnull argument with out-of-range operand number (argument %lu, operand %lu)",
5591117404Skan		     (unsigned long) attr_arg_num, (unsigned long) arg_num);
5592117404Skan	      *no_add_attrs = true;
5593117404Skan	      return NULL_TREE;
5594117404Skan	    }
5595117404Skan
5596261188Spfg	  /* APPLE LOCAL begin blocks 5925781 */
5597261188Spfg	  if (TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE &&
5598261188Spfg	      TREE_CODE (TREE_VALUE (argument)) != BLOCK_POINTER_TYPE)
5599261188Spfg	  /* APPLE LOCAL end blocks 5925781 */
5600117404Skan	    {
5601169699Skan	      error ("nonnull argument references non-pointer operand (argument %lu, operand %lu)",
5602117404Skan		   (unsigned long) attr_arg_num, (unsigned long) arg_num);
5603117404Skan	      *no_add_attrs = true;
5604117404Skan	      return NULL_TREE;
5605117404Skan	    }
5606117404Skan	}
5607117404Skan    }
5608117404Skan
5609117404Skan  return NULL_TREE;
5610117404Skan}
5611117404Skan
5612117404Skan/* Check the argument list of a function call for null in argument slots
5613117404Skan   that are marked as requiring a non-null pointer argument.  */
5614117404Skan
5615117404Skanstatic void
5616132728Skancheck_function_nonnull (tree attrs, tree params)
5617117404Skan{
5618117404Skan  tree a, args, param;
5619117404Skan  int param_num;
5620117404Skan
5621117404Skan  for (a = attrs; a; a = TREE_CHAIN (a))
5622117404Skan    {
5623117404Skan      if (is_attribute_p ("nonnull", TREE_PURPOSE (a)))
5624117404Skan	{
5625169699Skan	  args = TREE_VALUE (a);
5626117404Skan
5627169699Skan	  /* Walk the argument list.  If we encounter an argument number we
5628169699Skan	     should check for non-null, do it.  If the attribute has no args,
5629169699Skan	     then every pointer argument is checked (in which case the check
5630117404Skan	     for pointer type is done in check_nonnull_arg).  */
5631169699Skan	  for (param = params, param_num = 1; ;
5632169699Skan	       param_num++, param = TREE_CHAIN (param))
5633169699Skan	    {
5634169699Skan	      if (!param)
5635132728Skan	break;
5636169699Skan	      if (!args || nonnull_check_p (args, param_num))
5637132728Skan	check_function_arguments_recurse (check_nonnull_arg, NULL,
5638132728Skan					  TREE_VALUE (param),
5639132728Skan					  param_num);
5640169699Skan	    }
5641117404Skan	}
5642117404Skan    }
5643117404Skan}
5644117404Skan
5645169699Skan/* Check that the Nth argument of a function call (counting backwards
5646169699Skan   from the end) is a (pointer)0.  */
5647169699Skan
5648169699Skanstatic void
5649169699Skancheck_function_sentinel (tree attrs, tree params, tree typelist)
5650169699Skan{
5651169699Skan  tree attr = lookup_attribute ("sentinel", attrs);
5652169699Skan
5653169699Skan  if (attr)
5654169699Skan    {
5655169699Skan      /* Skip over the named arguments.  */
5656169699Skan      while (typelist && params)
5657169699Skan      {
5658169699Skan	typelist = TREE_CHAIN (typelist);
5659169699Skan	params = TREE_CHAIN (params);
5660169699Skan      }
5661169699Skan
5662169699Skan      if (typelist || !params)
5663169699Skan	warning (OPT_Wformat,
5664169699Skan		 "not enough variable arguments to fit a sentinel");
5665169699Skan      else
5666169699Skan	{
5667169699Skan	  tree sentinel, end;
5668169699Skan	  unsigned pos = 0;
5669169699Skan
5670169699Skan	  if (TREE_VALUE (attr))
5671169699Skan	    {
5672169699Skan	      tree p = TREE_VALUE (TREE_VALUE (attr));
5673169699Skan	      pos = TREE_INT_CST_LOW (p);
5674169699Skan	    }
5675169699Skan
5676169699Skan	  sentinel = end = params;
5677169699Skan
5678169699Skan	  /* Advance `end' ahead of `sentinel' by `pos' positions.  */
5679169699Skan	  while (pos > 0 && TREE_CHAIN (end))
5680169699Skan	    {
5681169699Skan	      pos--;
5682169699Skan	      end = TREE_CHAIN (end);
5683169699Skan	    }
5684169699Skan	  if (pos > 0)
5685169699Skan	    {
5686169699Skan	      warning (OPT_Wformat,
5687169699Skan		       "not enough variable arguments to fit a sentinel");
5688169699Skan	      return;
5689169699Skan	    }
5690169699Skan
5691169699Skan	  /* Now advance both until we find the last parameter.  */
5692169699Skan	  while (TREE_CHAIN (end))
5693169699Skan	    {
5694169699Skan	      end = TREE_CHAIN (end);
5695169699Skan	      sentinel = TREE_CHAIN (sentinel);
5696169699Skan	    }
5697169699Skan
5698169699Skan	  /* Validate the sentinel.  */
5699169699Skan	  if ((!POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (sentinel)))
5700169699Skan	       || !integer_zerop (TREE_VALUE (sentinel)))
5701169699Skan	      /* Although __null (in C++) is only an integer we allow it
5702169699Skan		 nevertheless, as we are guaranteed that it's exactly
5703169699Skan		 as wide as a pointer, and we don't want to force
5704169699Skan		 users to cast the NULL they have written there.
5705169699Skan		 We warn with -Wstrict-null-sentinel, though.  */
5706169699Skan	      && (warn_strict_null_sentinel
5707169699Skan		  || null_node != TREE_VALUE (sentinel)))
5708169699Skan	    warning (OPT_Wformat, "missing sentinel in function call");
5709169699Skan	}
5710169699Skan    }
5711169699Skan}
5712169699Skan
5713117404Skan/* Helper for check_function_nonnull; given a list of operands which
5714117404Skan   must be non-null in ARGS, determine if operand PARAM_NUM should be
5715117404Skan   checked.  */
5716117404Skan
5717117404Skanstatic bool
5718132728Skannonnull_check_p (tree args, unsigned HOST_WIDE_INT param_num)
5719117404Skan{
5720169699Skan  unsigned HOST_WIDE_INT arg_num = 0;
5721117404Skan
5722117404Skan  for (; args; args = TREE_CHAIN (args))
5723117404Skan    {
5724169699Skan      bool found = get_nonnull_operand (TREE_VALUE (args), &arg_num);
5725117404Skan
5726169699Skan      gcc_assert (found);
5727169699Skan
5728117404Skan      if (arg_num == param_num)
5729117404Skan	return true;
5730117404Skan    }
5731117404Skan  return false;
5732117404Skan}
5733117404Skan
5734117404Skan/* Check that the function argument PARAM (which is operand number
5735117404Skan   PARAM_NUM) is non-null.  This is called by check_function_nonnull
5736117404Skan   via check_function_arguments_recurse.  */
5737117404Skan
5738117404Skanstatic void
5739169699Skancheck_nonnull_arg (void * ARG_UNUSED (ctx), tree param,
5740132728Skan		   unsigned HOST_WIDE_INT param_num)
5741117404Skan{
5742117404Skan  /* Just skip checking the argument if it's not a pointer.  This can
5743117404Skan     happen if the "nonnull" attribute was given without an operand
5744117404Skan     list (which means to check every pointer argument).  */
5745117404Skan
5746261188Spfg  /* APPLE LOCAL begin blocks 5925781 */
5747261188Spfg  if (TREE_CODE (TREE_TYPE (param)) != POINTER_TYPE &&
5748261188Spfg      TREE_CODE (TREE_TYPE (param)) != BLOCK_POINTER_TYPE)
5749261188Spfg  /* APPLE LOCAL end blocks 5925781 */
5750261188Spfg   return;
5751117404Skan
5752117404Skan  if (integer_zerop (param))
5753169699Skan    warning (OPT_Wnonnull, "null argument where non-null required "
5754169699Skan	     "(argument %lu)", (unsigned long) param_num);
5755117404Skan}
5756117404Skan
5757117404Skan/* Helper for nonnull attribute handling; fetch the operand number
5758117404Skan   from the attribute argument list.  */
5759117404Skan
5760117404Skanstatic bool
5761132728Skanget_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
5762117404Skan{
5763169699Skan  /* Verify the arg number is a constant.  */
5764117404Skan  if (TREE_CODE (arg_num_expr) != INTEGER_CST
5765117404Skan      || TREE_INT_CST_HIGH (arg_num_expr) != 0)
5766117404Skan    return false;
5767117404Skan
5768117404Skan  *valp = TREE_INT_CST_LOW (arg_num_expr);
5769117404Skan  return true;
5770117404Skan}
5771117404Skan
5772117404Skan/* Handle a "nothrow" attribute; arguments as in
5773117404Skan   struct attribute_spec.handler.  */
5774117404Skan
5775117404Skanstatic tree
5776169699Skanhandle_nothrow_attribute (tree *node, tree name, tree ARG_UNUSED (args),
5777169699Skan			  int ARG_UNUSED (flags), bool *no_add_attrs)
5778117404Skan{
5779117404Skan  if (TREE_CODE (*node) == FUNCTION_DECL)
5780117404Skan    TREE_NOTHROW (*node) = 1;
5781117404Skan  /* ??? TODO: Support types.  */
5782117404Skan  else
5783117404Skan    {
5784169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
5785117404Skan      *no_add_attrs = true;
5786117404Skan    }
5787117404Skan
5788117404Skan  return NULL_TREE;
5789117404Skan}
5790132728Skan
5791132728Skan/* Handle a "cleanup" attribute; arguments as in
5792132728Skan   struct attribute_spec.handler.  */
5793132728Skan
5794132728Skanstatic tree
5795132728Skanhandle_cleanup_attribute (tree *node, tree name, tree args,
5796169699Skan			  int ARG_UNUSED (flags), bool *no_add_attrs)
5797132728Skan{
5798132728Skan  tree decl = *node;
5799132728Skan  tree cleanup_id, cleanup_decl;
5800132728Skan
5801132728Skan  /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do
5802132728Skan     for global destructors in C++.  This requires infrastructure that
5803132728Skan     we don't have generically at the moment.  It's also not a feature
5804132728Skan     we'd be missing too much, since we do have attribute constructor.  */
5805132728Skan  if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl))
5806132728Skan    {
5807169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
5808132728Skan      *no_add_attrs = true;
5809132728Skan      return NULL_TREE;
5810132728Skan    }
5811132728Skan
5812132728Skan  /* Verify that the argument is a function in scope.  */
5813132728Skan  /* ??? We could support pointers to functions here as well, if
5814132728Skan     that was considered desirable.  */
5815132728Skan  cleanup_id = TREE_VALUE (args);
5816132728Skan  if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE)
5817132728Skan    {
5818169699Skan      error ("cleanup argument not an identifier");
5819132728Skan      *no_add_attrs = true;
5820132728Skan      return NULL_TREE;
5821132728Skan    }
5822132728Skan  cleanup_decl = lookup_name (cleanup_id);
5823132728Skan  if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL)
5824132728Skan    {
5825169699Skan      error ("cleanup argument not a function");
5826132728Skan      *no_add_attrs = true;
5827132728Skan      return NULL_TREE;
5828132728Skan    }
5829132728Skan
5830132728Skan  /* That the function has proper type is checked with the
5831132728Skan     eventual call to build_function_call.  */
5832132728Skan
5833132728Skan  return NULL_TREE;
5834132728Skan}
5835132728Skan
5836132728Skan/* Handle a "warn_unused_result" attribute.  No special handling.  */
5837132728Skan
5838132728Skanstatic tree
5839132728Skanhandle_warn_unused_result_attribute (tree *node, tree name,
5840169699Skan			       tree ARG_UNUSED (args),
5841169699Skan			       int ARG_UNUSED (flags), bool *no_add_attrs)
5842132728Skan{
5843132728Skan  /* Ignore the attribute for functions not returning any value.  */
5844132728Skan  if (VOID_TYPE_P (TREE_TYPE (*node)))
5845132728Skan    {
5846169699Skan      warning (OPT_Wattributes, "%qE attribute ignored", name);
5847132728Skan      *no_add_attrs = true;
5848132728Skan    }
5849132728Skan
5850132728Skan  return NULL_TREE;
5851132728Skan}
5852169699Skan
5853261188Spfg/* APPLE LOCAL begin radar 5932809 - copyable byref blocks */
5854261188Spfg/* Handle "blocks" attribute. */
5855261188Spfgstatic tree
5856261188Spfghandle_blocks_attribute (tree *node, tree name,
5857261188Spfg			  tree args,
5858261188Spfg			  int ARG_UNUSED (flags), bool *no_add_attrs)
5859261188Spfg{
5860261188Spfg  tree arg_ident;
5861261188Spfg  /* APPLE LOCAL radar 6217257 */
5862261188Spfg  tree type;
5863261188Spfg  *no_add_attrs = true;
5864261188Spfg  if (!(*node) || TREE_CODE (*node) != VAR_DECL)
5865261188Spfg    {
5866261188Spfg      error ("__block attribute can be specified on variables only");
5867261188Spfg      return NULL_TREE;
5868261188Spfg    }
5869261188Spfg  arg_ident = TREE_VALUE (args);
5870261188Spfg  gcc_assert (TREE_CODE (arg_ident) == IDENTIFIER_NODE);
5871261188Spfg  /* APPLE LOCAL radar 6096219 */
5872261188Spfg  if (strcmp (IDENTIFIER_POINTER (arg_ident), "byref"))
5873261188Spfg    {
5874261188Spfg      /* APPLE LOCAL radar 6096219 */
5875261188Spfg      warning (OPT_Wattributes, "Only \"byref\" is allowed - %qE attribute ignored",
5876261188Spfg	        name);
5877261188Spfg      return NULL_TREE;
5878261188Spfg    }
5879261188Spfg  /* APPLE LOCAL begin radar 6217257 */
5880261188Spfg  type = TREE_TYPE (*node);
5881261188Spfg  if (TREE_CODE (type) == ERROR_MARK)
5882261188Spfg    return NULL_TREE;
5883261188Spfg  if (TREE_CODE (type) == ARRAY_TYPE)
5884261188Spfg  {
5885261188Spfg    if (!TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
5886261188Spfg    {
5887261188Spfg      error ("__block not allowed on a variable length array declaration");
5888261188Spfg      return NULL_TREE;
5889261188Spfg    }
5890261188Spfg  }
5891261188Spfg  /* APPLE LOCAL end radar 6217257 */
5892261188Spfg  COPYABLE_BYREF_LOCAL_VAR (*node) = 1;
5893261188Spfg  COPYABLE_BYREF_LOCAL_NONPOD (*node) = block_requires_copying (*node);
5894261188Spfg  return NULL_TREE;
5895261188Spfg}
5896261188Spfg/* APPLE LOCAL end radar 5932809 - copyable byref blocks */
5897261188Spfg
5898261188Spfg/* APPLE LOCAL begin blocks 6040305 */
5899261188Spfg
5900261188Spfg/* This routine builds:
5901261188Spfg   *(void **)(EXP+20) expression which references the object pointer.
5902261188Spfg*/
5903261188Spfgtree
5904261188Spfgbuild_indirect_object_id_exp (tree exp)
5905261188Spfg{
5906261188Spfg  tree dst_obj;
5907261188Spfg  int  int_size = int_cst_value (TYPE_SIZE_UNIT (unsigned_type_node));
5908261188Spfg  int offset;
5909261188Spfg  /* dst->object In thid case 'object' is the field
5910261188Spfg   of the object passed offset by: void * + void* + int + int + void* + void *
5911261188Spfg   This must match definition of Block_byref structs. */
5912261188Spfg  /* APPLE LOCAL radar 6244520 */
5913261188Spfg  offset = GET_MODE_SIZE (Pmode) + GET_MODE_SIZE (Pmode)
5914261188Spfg	    + int_size + int_size + GET_MODE_SIZE (Pmode) +
5915261188Spfg	    GET_MODE_SIZE (Pmode);
5916261188Spfg  dst_obj = build2 (PLUS_EXPR, ptr_type_node, exp,
5917261188Spfg		     build_int_cst (NULL_TREE, offset));
5918261188Spfg  /* APPLE LOCAL begin radar 6180456 */
5919261188Spfg  /* Type case to: 'void **' */
5920261188Spfg  dst_obj = build_c_cast (build_pointer_type (ptr_type_node), dst_obj);
5921261188Spfg  dst_obj = build_indirect_ref (dst_obj, "unary *");
5922261188Spfg  /* APPLE LOCAL end radar 6180456 */
5923261188Spfg  return dst_obj;
5924261188Spfg}
5925261188Spfg
5926261188Spfg/* This routine builds call to:
5927261188Spfg _Block_object_dispose(VAR_DECL.__forwarding, BLOCK_FIELD_IS_BYREF);
5928261188Spfg and adds it to the statement list.
5929261188Spfg */
5930261188Spfgtree
5931261188Spfgbuild_block_byref_release_exp (tree var_decl)
5932261188Spfg{
5933261188Spfg  tree exp = var_decl, call_exp;
5934261188Spfg  tree type = TREE_TYPE (var_decl);
5935261188Spfg  /* __block variables imported into Blocks are not _Block_object_dispose()
5936261188Spfg   from within the Block statement itself; otherwise, each envokation of
5937261188Spfg   the block causes a release. Make sure to release __block variables declared
5938261188Spfg   and used locally in the block though. */
5939261188Spfg  if (cur_block
5940261188Spfg      && (BLOCK_DECL_COPIED (var_decl) || BLOCK_DECL_BYREF (var_decl)))
5941261188Spfg    return NULL_TREE;
5942261188Spfg  if (BLOCK_DECL_BYREF (var_decl)) {
5943261188Spfg    /* This is a "struct Block_byref_X *" type. Get its pointee. */
5944261188Spfg    gcc_assert (POINTER_TYPE_P (type));
5945261188Spfg    type = TREE_TYPE (type);
5946261188Spfg    exp = build_indirect_ref (exp, "unary *");
5947261188Spfg  }
5948261188Spfg  TREE_USED (var_decl) = 1;
5949261188Spfg
5950261188Spfg  /* Declare: _Block_object_dispose(void*, BLOCK_FIELD_IS_BYREF) if not done already. */
5951261188Spfg  exp = build_component_ref (exp, get_identifier ("__forwarding"));
5952261188Spfg  call_exp = build_block_object_dispose_call_exp (exp, BLOCK_FIELD_IS_BYREF);
5953261188Spfg  return call_exp;
5954261188Spfg}
5955261188Spfg/* APPLE LOCAL end blocks 6040305 */
5956261188Spfg/* APPLE LOCAL begin radar 5803600 */
5957261188Spfg/** add_block_global_byref_list - Adds global variable decl to the list of
5958261188Spfg    byref global declarations in the current block.
5959261188Spfg*/
5960261188Spfgvoid add_block_global_byref_list (tree decl)
5961261188Spfg{
5962261188Spfg  cur_block->block_byref_global_decl_list =
5963261188Spfg    tree_cons (NULL_TREE, decl, cur_block->block_byref_global_decl_list);
5964261188Spfg}
5965261188Spfg
5966261188Spfg/** in_block_global_byref_list - returns TRUE if global variable is
5967261188Spfg    in the list of 'byref' declarations.
5968261188Spfg*/
5969261188Spfgbool in_block_global_byref_list (tree decl)
5970261188Spfg{
5971261188Spfg  tree chain;
5972261188Spfg  if (TREE_STATIC (decl)) {
5973261188Spfg    for (chain = cur_block->block_byref_global_decl_list; chain;
5974261188Spfg	  chain = TREE_CHAIN (chain))
5975261188Spfg      if (TREE_VALUE (chain) == decl)
5976261188Spfg	 return true;
5977261188Spfg  }
5978261188Spfg  return false;
5979261188Spfg}
5980261188Spfg/* APPLE LOCAL end radar 5803600 */
5981261188Spfg
5982261188Spfg/* APPLE LOCAL begin radar 6160536 */
5983261188Spfgtree
5984261188Spfgbuild_block_helper_name (int unique_count)
5985261188Spfg{
5986261188Spfg  char *buf;
5987261188Spfg  if (!current_function_decl)
5988261188Spfg    {
5989261188Spfg      /* APPLE LOCAL begin radar 6411649 */
5990261188Spfg      static int global_count;
5991261188Spfg      buf = (char *)alloca (32);
5992261188Spfg      sprintf (buf, "__block_global_%d", ++global_count);
5993261188Spfg      /* APPLE LOCAL end radar 6411649 */
5994261188Spfg    }
5995261188Spfg  else
5996261188Spfg    {
5997261188Spfg      tree outer_decl = current_function_decl;
5998261188Spfg      /* APPLE LOCAL begin radar 6169580 */
5999261188Spfg      while (outer_decl &&
6000261188Spfg	      DECL_CONTEXT (outer_decl) && TREE_CODE (DECL_CONTEXT (outer_decl)) == FUNCTION_DECL)
6001261188Spfg      /* APPLE LOCAL end radar 6169580 */
6002261188Spfg	 outer_decl = DECL_CONTEXT (outer_decl);
6003261188Spfg      /* APPLE LOCAL begin radar 6411649 */
6004261188Spfg      if (!unique_count)
6005261188Spfg	 unique_count = ++DECL_STRUCT_FUNCTION(outer_decl)->unqiue_block_number;
6006261188Spfg      /* APPLE LOCAL end radar 6411649 */
6007261188Spfg      buf = (char *)alloca (IDENTIFIER_LENGTH (DECL_NAME (outer_decl)) + 32);
6008261188Spfg      sprintf (buf, "__%s_block_invoke_%d",
6009261188Spfg	       IDENTIFIER_POINTER (DECL_NAME (outer_decl)), unique_count);
6010261188Spfg    }
6011261188Spfg   return get_identifier (buf);
6012261188Spfg}
6013261188Spfg/* APPLE LOCAL end radar 6160536 */
6014261188Spfg
6015169699Skan/* Handle a "sentinel" attribute.  */
6016169699Skan
6017169699Skanstatic tree
6018169699Skanhandle_sentinel_attribute (tree *node, tree name, tree args,
6019169699Skan			   int ARG_UNUSED (flags), bool *no_add_attrs)
6020169699Skan{
6021169699Skan  tree params = TYPE_ARG_TYPES (*node);
6022169699Skan
6023169699Skan  if (!params)
6024169699Skan    {
6025169699Skan      warning (OPT_Wattributes,
6026169699Skan	       "%qE attribute requires prototypes with named arguments", name);
6027169699Skan      *no_add_attrs = true;
6028169699Skan    }
6029169699Skan  else
6030169699Skan    {
6031169699Skan      while (TREE_CHAIN (params))
6032169699Skan	params = TREE_CHAIN (params);
6033169699Skan
6034169699Skan      if (VOID_TYPE_P (TREE_VALUE (params)))
6035169699Skan	{
6036169699Skan	  warning (OPT_Wattributes,
6037169699Skan		   "%qE attribute only applies to variadic functions", name);
6038169699Skan	  *no_add_attrs = true;
6039169699Skan	}
6040169699Skan    }
6041169699Skan
6042169699Skan  if (args)
6043169699Skan    {
6044169699Skan      tree position = TREE_VALUE (args);
6045169699Skan
6046169699Skan      if (TREE_CODE (position) != INTEGER_CST)
6047169699Skan	{
6048169699Skan	  warning (0, "requested position is not an integer constant");
6049169699Skan	  *no_add_attrs = true;
6050169699Skan	}
6051169699Skan      else
6052169699Skan	{
6053169699Skan	  if (tree_int_cst_lt (position, integer_zero_node))
6054169699Skan	    {
6055169699Skan	      warning (0, "requested position is less than zero");
6056169699Skan	      *no_add_attrs = true;
6057169699Skan	    }
6058169699Skan	}
6059169699Skan    }
6060169699Skan
6061169699Skan  return NULL_TREE;
6062169699Skan}
6063117404Skan
6064117404Skan/* Check for valid arguments being passed to a function.  */
6065117404Skanvoid
6066169699Skancheck_function_arguments (tree attrs, tree params, tree typelist)
6067117404Skan{
6068117404Skan  /* Check for null being passed in a pointer argument that must be
6069117404Skan     non-null.  We also need to do this if format checking is enabled.  */
6070117404Skan
6071117404Skan  if (warn_nonnull)
6072117404Skan    check_function_nonnull (attrs, params);
6073117404Skan
6074117404Skan  /* Check for errors in format strings.  */
6075117404Skan
6076169699Skan  if (warn_format || warn_missing_format_attribute)
6077169699Skan      check_function_format (attrs, params);
6078169699Skan
6079117404Skan  if (warn_format)
6080169699Skan    check_function_sentinel (attrs, params, typelist);
6081117404Skan}
6082117404Skan
6083117404Skan/* Generic argument checking recursion routine.  PARAM is the argument to
6084117404Skan   be checked.  PARAM_NUM is the number of the argument.  CALLBACK is invoked
6085117404Skan   once the argument is resolved.  CTX is context for the callback.  */
6086117404Skanvoid
6087132728Skancheck_function_arguments_recurse (void (*callback)
6088132728Skan				  (void *, tree, unsigned HOST_WIDE_INT),
6089132728Skan				  void *ctx, tree param,
6090132728Skan				  unsigned HOST_WIDE_INT param_num)
6091117404Skan{
6092169699Skan  if ((TREE_CODE (param) == NOP_EXPR || TREE_CODE (param) == CONVERT_EXPR)
6093169699Skan      && (TYPE_PRECISION (TREE_TYPE (param))
6094169699Skan	  == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (param, 0)))))
6095117404Skan    {
6096117404Skan      /* Strip coercion.  */
6097117404Skan      check_function_arguments_recurse (callback, ctx,
6098169699Skan					TREE_OPERAND (param, 0), param_num);
6099117404Skan      return;
6100117404Skan    }
6101117404Skan
6102117404Skan  if (TREE_CODE (param) == CALL_EXPR)
6103117404Skan    {
6104117404Skan      tree type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (param, 0)));
6105117404Skan      tree attrs;
6106117404Skan      bool found_format_arg = false;
6107117404Skan
6108117404Skan      /* See if this is a call to a known internationalization function
6109117404Skan	 that modifies a format arg.  Such a function may have multiple
6110117404Skan	 format_arg attributes (for example, ngettext).  */
6111117404Skan
6112117404Skan      for (attrs = TYPE_ATTRIBUTES (type);
6113117404Skan	   attrs;
6114117404Skan	   attrs = TREE_CHAIN (attrs))
6115117404Skan	if (is_attribute_p ("format_arg", TREE_PURPOSE (attrs)))
6116117404Skan	  {
6117117404Skan	    tree inner_args;
6118117404Skan	    tree format_num_expr;
6119117404Skan	    int format_num;
6120117404Skan	    int i;
6121117404Skan
6122117404Skan	    /* Extract the argument number, which was previously checked
6123117404Skan	       to be valid.  */
6124117404Skan	    format_num_expr = TREE_VALUE (TREE_VALUE (attrs));
6125117404Skan
6126169699Skan	    gcc_assert (TREE_CODE (format_num_expr) == INTEGER_CST
6127169699Skan			&& !TREE_INT_CST_HIGH (format_num_expr));
6128117404Skan
6129117404Skan	    format_num = TREE_INT_CST_LOW (format_num_expr);
6130117404Skan
6131117404Skan	    for (inner_args = TREE_OPERAND (param, 1), i = 1;
6132117404Skan		 inner_args != 0;
6133117404Skan		 inner_args = TREE_CHAIN (inner_args), i++)
6134117404Skan	      if (i == format_num)
6135117404Skan		{
6136117404Skan		  check_function_arguments_recurse (callback, ctx,
6137117404Skan						    TREE_VALUE (inner_args),
6138117404Skan						    param_num);
6139117404Skan		  found_format_arg = true;
6140117404Skan		  break;
6141117404Skan		}
6142117404Skan	  }
6143117404Skan
6144117404Skan      /* If we found a format_arg attribute and did a recursive check,
6145117404Skan	 we are done with checking this argument.  Otherwise, we continue
6146117404Skan	 and this will be considered a non-literal.  */
6147117404Skan      if (found_format_arg)
6148117404Skan	return;
6149117404Skan    }
6150117404Skan
6151117404Skan  if (TREE_CODE (param) == COND_EXPR)
6152117404Skan    {
6153117404Skan      /* Check both halves of the conditional expression.  */
6154117404Skan      check_function_arguments_recurse (callback, ctx,
6155169699Skan					TREE_OPERAND (param, 1), param_num);
6156117404Skan      check_function_arguments_recurse (callback, ctx,
6157169699Skan					TREE_OPERAND (param, 2), param_num);
6158117404Skan      return;
6159117404Skan    }
6160117404Skan
6161117404Skan  (*callback) (ctx, param, param_num);
6162117404Skan}
6163117404Skan
6164132728Skan/* Function to help qsort sort FIELD_DECLs by name order.  */
6165132728Skan
6166132728Skanint
6167132728Skanfield_decl_cmp (const void *x_p, const void *y_p)
6168132728Skan{
6169169699Skan  const tree *const x = (const tree *const) x_p;
6170169699Skan  const tree *const y = (const tree *const) y_p;
6171169699Skan
6172132728Skan  if (DECL_NAME (*x) == DECL_NAME (*y))
6173132728Skan    /* A nontype is "greater" than a type.  */
6174132728Skan    return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL);
6175132728Skan  if (DECL_NAME (*x) == NULL_TREE)
6176132728Skan    return -1;
6177132728Skan  if (DECL_NAME (*y) == NULL_TREE)
6178132728Skan    return 1;
6179132728Skan  if (DECL_NAME (*x) < DECL_NAME (*y))
6180132728Skan    return -1;
6181132728Skan  return 1;
6182132728Skan}
6183132728Skan
6184132728Skanstatic struct {
6185132728Skan  gt_pointer_operator new_value;
6186132728Skan  void *cookie;
6187132728Skan} resort_data;
6188132728Skan
6189132728Skan/* This routine compares two fields like field_decl_cmp but using the
6190132728Skanpointer operator in resort_data.  */
6191132728Skan
6192132728Skanstatic int
6193132728Skanresort_field_decl_cmp (const void *x_p, const void *y_p)
6194132728Skan{
6195169699Skan  const tree *const x = (const tree *const) x_p;
6196169699Skan  const tree *const y = (const tree *const) y_p;
6197132728Skan
6198132728Skan  if (DECL_NAME (*x) == DECL_NAME (*y))
6199132728Skan    /* A nontype is "greater" than a type.  */
6200132728Skan    return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL);
6201132728Skan  if (DECL_NAME (*x) == NULL_TREE)
6202132728Skan    return -1;
6203132728Skan  if (DECL_NAME (*y) == NULL_TREE)
6204132728Skan    return 1;
6205132728Skan  {
6206132728Skan    tree d1 = DECL_NAME (*x);
6207132728Skan    tree d2 = DECL_NAME (*y);
6208132728Skan    resort_data.new_value (&d1, resort_data.cookie);
6209132728Skan    resort_data.new_value (&d2, resort_data.cookie);
6210132728Skan    if (d1 < d2)
6211132728Skan      return -1;
6212132728Skan  }
6213132728Skan  return 1;
6214132728Skan}
6215132728Skan
6216132728Skan/* Resort DECL_SORTED_FIELDS because pointers have been reordered.  */
6217132728Skan
6218132728Skanvoid
6219132728Skanresort_sorted_fields (void *obj,
6220169699Skan		      void * ARG_UNUSED (orig_obj),
6221169699Skan		      gt_pointer_operator new_value,
6222169699Skan		      void *cookie)
6223132728Skan{
6224169699Skan  struct sorted_fields_type *sf = (struct sorted_fields_type *) obj;
6225132728Skan  resort_data.new_value = new_value;
6226132728Skan  resort_data.cookie = cookie;
6227132728Skan  qsort (&sf->elts[0], sf->len, sizeof (tree),
6228169699Skan	 resort_field_decl_cmp);
6229132728Skan}
6230132728Skan
6231169699Skan/* Subroutine of c_parse_error.
6232169699Skan   Return the result of concatenating LHS and RHS. RHS is really
6233169699Skan   a string literal, its first character is indicated by RHS_START and
6234169699Skan   RHS_SIZE is its length (including the terminating NUL character).
6235169699Skan
6236169699Skan   The caller is responsible for deleting the returned pointer.  */
6237169699Skan
6238169699Skanstatic char *
6239169699Skancatenate_strings (const char *lhs, const char *rhs_start, int rhs_size)
6240132728Skan{
6241169699Skan  const int lhs_size = strlen (lhs);
6242169699Skan  char *result = XNEWVEC (char, lhs_size + rhs_size);
6243169699Skan  strncpy (result, lhs, lhs_size);
6244169699Skan  strncpy (result + lhs_size, rhs_start, rhs_size);
6245169699Skan  return result;
6246169699Skan}
6247132728Skan
6248169699Skan/* Issue the error given by GMSGID, indicating that it occurred before
6249169699Skan   TOKEN, which had the associated VALUE.  */
6250169699Skan
6251169699Skanvoid
6252169699Skanc_parse_error (const char *gmsgid, enum cpp_ttype token, tree value)
6253169699Skan{
6254169699Skan#define catenate_messages(M1, M2) catenate_strings ((M1), (M2), sizeof (M2))
6255169699Skan
6256169699Skan  char *message = NULL;
6257169699Skan
6258169699Skan  if (token == CPP_EOF)
6259169699Skan    message = catenate_messages (gmsgid, " at end of input");
6260169699Skan  else if (token == CPP_CHAR || token == CPP_WCHAR)
6261132728Skan    {
6262169699Skan      unsigned int val = TREE_INT_CST_LOW (value);
6263169699Skan      const char *const ell = (token == CPP_CHAR) ? "" : "L";
6264169699Skan      if (val <= UCHAR_MAX && ISGRAPH (val))
6265169699Skan	message = catenate_messages (gmsgid, " before %s'%c'");
6266169699Skan      else
6267169699Skan	message = catenate_messages (gmsgid, " before %s'\\x%x'");
6268169699Skan
6269169699Skan      error (message, ell, val);
6270169699Skan      free (message);
6271169699Skan      message = NULL;
6272132728Skan    }
6273169699Skan  else if (token == CPP_STRING || token == CPP_WSTRING)
6274169699Skan    message = catenate_messages (gmsgid, " before string constant");
6275169699Skan  else if (token == CPP_NUMBER)
6276169699Skan    message = catenate_messages (gmsgid, " before numeric constant");
6277169699Skan  else if (token == CPP_NAME)
6278169699Skan    {
6279169699Skan      message = catenate_messages (gmsgid, " before %qE");
6280169699Skan      error (message, value);
6281169699Skan      free (message);
6282169699Skan      message = NULL;
6283169699Skan    }
6284169699Skan  else if (token == CPP_PRAGMA)
6285169699Skan    message = catenate_messages (gmsgid, " before %<#pragma%>");
6286169699Skan  else if (token == CPP_PRAGMA_EOL)
6287169699Skan    message = catenate_messages (gmsgid, " before end of line");
6288169699Skan  else if (token < N_TTYPES)
6289169699Skan    {
6290169699Skan      message = catenate_messages (gmsgid, " before %qs token");
6291169699Skan      error (message, cpp_type2name (token));
6292169699Skan      free (message);
6293169699Skan      message = NULL;
6294169699Skan    }
6295169699Skan  else
6296260011Spfg    error (gmsgid, "");
6297132728Skan
6298169699Skan  if (message)
6299169699Skan    {
6300260011Spfg      error (message, "");
6301169699Skan      free (message);
6302169699Skan    }
6303169699Skan#undef catenate_messages
6304169699Skan}
6305132728Skan
6306169699Skan/* Walk a gimplified function and warn for functions whose return value is
6307169699Skan   ignored and attribute((warn_unused_result)) is set.  This is done before
6308169699Skan   inlining, so we don't have to worry about that.  */
6309169699Skan
6310169699Skanvoid
6311169699Skanc_warn_unused_result (tree *top_p)
6312169699Skan{
6313169699Skan  tree t = *top_p;
6314169699Skan  tree_stmt_iterator i;
6315169699Skan  tree fdecl, ftype;
6316169699Skan
6317169699Skan  switch (TREE_CODE (t))
6318169699Skan    {
6319169699Skan    case STATEMENT_LIST:
6320169699Skan      for (i = tsi_start (*top_p); !tsi_end_p (i); tsi_next (&i))
6321169699Skan	c_warn_unused_result (tsi_stmt_ptr (i));
6322132728Skan      break;
6323132728Skan
6324169699Skan    case COND_EXPR:
6325169699Skan      c_warn_unused_result (&COND_EXPR_THEN (t));
6326169699Skan      c_warn_unused_result (&COND_EXPR_ELSE (t));
6327132728Skan      break;
6328132728Skan    case BIND_EXPR:
6329169699Skan      c_warn_unused_result (&BIND_EXPR_BODY (t));
6330169699Skan      break;
6331169699Skan    case TRY_FINALLY_EXPR:
6332132728Skan    case TRY_CATCH_EXPR:
6333169699Skan      c_warn_unused_result (&TREE_OPERAND (t, 0));
6334169699Skan      c_warn_unused_result (&TREE_OPERAND (t, 1));
6335169699Skan      break;
6336169699Skan    case CATCH_EXPR:
6337169699Skan      c_warn_unused_result (&CATCH_BODY (t));
6338169699Skan      break;
6339169699Skan    case EH_FILTER_EXPR:
6340169699Skan      c_warn_unused_result (&EH_FILTER_FAILURE (t));
6341169699Skan      break;
6342132728Skan
6343169699Skan    case CALL_EXPR:
6344169699Skan      if (TREE_USED (t))
6345169699Skan	break;
6346132728Skan
6347169699Skan      /* This is a naked call, as opposed to a CALL_EXPR nested inside
6348169699Skan	 a MODIFY_EXPR.  All calls whose value is ignored should be
6349169699Skan	 represented like this.  Look for the attribute.  */
6350169699Skan      fdecl = get_callee_fndecl (t);
6351169699Skan      if (fdecl)
6352169699Skan	ftype = TREE_TYPE (fdecl);
6353169699Skan      else
6354169699Skan	{
6355169699Skan	  ftype = TREE_TYPE (TREE_OPERAND (t, 0));
6356169699Skan	  /* Look past pointer-to-function to the function type itself.  */
6357169699Skan	  ftype = TREE_TYPE (ftype);
6358169699Skan	}
6359169699Skan
6360169699Skan      if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
6361169699Skan	{
6362169699Skan	  if (fdecl)
6363169699Skan	    warning (0, "%Hignoring return value of %qD, "
6364169699Skan		     "declared with attribute warn_unused_result",
6365169699Skan		     EXPR_LOCUS (t), fdecl);
6366169699Skan	  else
6367169699Skan	    warning (0, "%Hignoring return value of function "
6368169699Skan		     "declared with attribute warn_unused_result",
6369169699Skan		     EXPR_LOCUS (t));
6370169699Skan	}
6371132728Skan      break;
6372169699Skan
6373169699Skan    default:
6374169699Skan      /* Not a container, not a call, or a call whose value is used.  */
6375132728Skan      break;
6376169699Skan    }
6377169699Skan}
6378169699Skan
6379169699Skan/* Convert a character from the host to the target execution character
6380169699Skan   set.  cpplib handles this, mostly.  */
6381169699Skan
6382169699SkanHOST_WIDE_INT
6383169699Skanc_common_to_target_charset (HOST_WIDE_INT c)
6384169699Skan{
6385169699Skan  /* Character constants in GCC proper are sign-extended under -fsigned-char,
6386169699Skan     zero-extended under -fno-signed-char.  cpplib insists that characters
6387169699Skan     and character constants are always unsigned.  Hence we must convert
6388169699Skan     back and forth.  */
6389169699Skan  cppchar_t uc = ((cppchar_t)c) & ((((cppchar_t)1) << CHAR_BIT)-1);
6390169699Skan
6391169699Skan  uc = cpp_host_to_exec_charset (parse_in, uc);
6392169699Skan
6393169699Skan  if (flag_signed_char)
6394169699Skan    return ((HOST_WIDE_INT)uc) << (HOST_BITS_PER_WIDE_INT - CHAR_TYPE_SIZE)
6395169699Skan			       >> (HOST_BITS_PER_WIDE_INT - CHAR_TYPE_SIZE);
6396169699Skan  else
6397169699Skan    return uc;
6398169699Skan}
6399169699Skan
6400169699Skan/* Build the result of __builtin_offsetof.  EXPR is a nested sequence of
6401169699Skan   component references, with STOP_REF, or alternatively an INDIRECT_REF of
6402169699Skan   NULL, at the bottom; much like the traditional rendering of offsetof as a
6403169699Skan   macro.  Returns the folded and properly cast result.  */
6404169699Skan
6405169699Skanstatic tree
6406169699Skanfold_offsetof_1 (tree expr, tree stop_ref)
6407169699Skan{
6408169699Skan  enum tree_code code = PLUS_EXPR;
6409169699Skan  tree base, off, t;
6410169699Skan
6411169699Skan  if (expr == stop_ref && TREE_CODE (expr) != ERROR_MARK)
6412169699Skan    return size_zero_node;
6413169699Skan
6414169699Skan  switch (TREE_CODE (expr))
6415169699Skan    {
6416169699Skan    case ERROR_MARK:
6417169699Skan      return expr;
6418169699Skan
6419169699Skan    case VAR_DECL:
6420169699Skan      error ("cannot apply %<offsetof%> to static data member %qD", expr);
6421169699Skan      return error_mark_node;
6422169699Skan
6423169699Skan    case CALL_EXPR:
6424169699Skan      error ("cannot apply %<offsetof%> when %<operator[]%> is overloaded");
6425169699Skan      return error_mark_node;
6426169699Skan
6427169699Skan    case INTEGER_CST:
6428169699Skan      gcc_assert (integer_zerop (expr));
6429169699Skan      return size_zero_node;
6430169699Skan
6431169699Skan    case NOP_EXPR:
6432169699Skan    case INDIRECT_REF:
6433169699Skan      base = fold_offsetof_1 (TREE_OPERAND (expr, 0), stop_ref);
6434169699Skan      gcc_assert (base == error_mark_node || base == size_zero_node);
6435169699Skan      return base;
6436169699Skan
6437169699Skan    case COMPONENT_REF:
6438169699Skan      base = fold_offsetof_1 (TREE_OPERAND (expr, 0), stop_ref);
6439169699Skan      if (base == error_mark_node)
6440169699Skan	return base;
6441169699Skan
6442169699Skan      t = TREE_OPERAND (expr, 1);
6443169699Skan      if (DECL_C_BIT_FIELD (t))
6444169699Skan	{
6445169699Skan	  error ("attempt to take address of bit-field structure "
6446169699Skan		 "member %qD", t);
6447169699Skan	  return error_mark_node;
6448169699Skan	}
6449169699Skan      off = size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (t),
6450169699Skan			size_int (tree_low_cst (DECL_FIELD_BIT_OFFSET (t), 1)
6451169699Skan				  / BITS_PER_UNIT));
6452169699Skan      break;
6453169699Skan
6454169699Skan    case ARRAY_REF:
6455169699Skan      base = fold_offsetof_1 (TREE_OPERAND (expr, 0), stop_ref);
6456169699Skan      if (base == error_mark_node)
6457169699Skan	return base;
6458169699Skan
6459169699Skan      t = TREE_OPERAND (expr, 1);
6460169699Skan      if (TREE_CODE (t) == INTEGER_CST && tree_int_cst_sgn (t) < 0)
6461169699Skan	{
6462169699Skan	  code = MINUS_EXPR;
6463169699Skan	  t = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
6464169699Skan	}
6465169699Skan      t = convert (sizetype, t);
6466169699Skan      off = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (TREE_TYPE (expr)), t);
6467169699Skan      break;
6468169699Skan
6469169699Skan    case COMPOUND_EXPR:
6470169699Skan      /* Handle static members of volatile structs.  */
6471169699Skan      t = TREE_OPERAND (expr, 1);
6472169699Skan      gcc_assert (TREE_CODE (t) == VAR_DECL);
6473169699Skan      return fold_offsetof_1 (t, stop_ref);
6474169699Skan
6475132728Skan    default:
6476169699Skan      gcc_unreachable ();
6477132728Skan    }
6478169699Skan
6479169699Skan  return size_binop (code, base, off);
6480132728Skan}
6481132728Skan
6482169699Skantree
6483169699Skanfold_offsetof (tree expr, tree stop_ref)
6484169699Skan{
6485169699Skan  /* Convert back from the internal sizetype to size_t.  */
6486169699Skan  return convert (size_type_node, fold_offsetof_1 (expr, stop_ref));
6487169699Skan}
6488169699Skan
6489169699Skan/* Print an error message for an invalid lvalue.  USE says
6490169699Skan   how the lvalue is being used and so selects the error message.  */
6491169699Skan
6492169699Skanvoid
6493169699Skanlvalue_error (enum lvalue_use use)
6494169699Skan{
6495169699Skan  switch (use)
6496169699Skan    {
6497169699Skan    case lv_assign:
6498169699Skan      error ("lvalue required as left operand of assignment");
6499169699Skan      break;
6500169699Skan    case lv_increment:
6501169699Skan      error ("lvalue required as increment operand");
6502169699Skan      break;
6503169699Skan    case lv_decrement:
6504169699Skan      error ("lvalue required as decrement operand");
6505169699Skan      break;
6506169699Skan    case lv_addressof:
6507169699Skan      error ("lvalue required as unary %<&%> operand");
6508169699Skan      break;
6509169699Skan    case lv_asm:
6510169699Skan      error ("lvalue required in asm statement");
6511169699Skan      break;
6512169699Skan    default:
6513169699Skan      gcc_unreachable ();
6514169699Skan    }
6515169699Skan}
6516169699Skan
6517169699Skan/* *PTYPE is an incomplete array.  Complete it with a domain based on
6518169699Skan   INITIAL_VALUE.  If INITIAL_VALUE is not present, use 1 if DO_DEFAULT
6519169699Skan   is true.  Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
6520169699Skan   2 if INITIAL_VALUE was NULL, and 3 if INITIAL_VALUE was empty.  */
6521169699Skan
6522132728Skanint
6523169699Skancomplete_array_type (tree *ptype, tree initial_value, bool do_default)
6524132728Skan{
6525169699Skan  tree maxindex, type, main_type, elt, unqual_elt;
6526169699Skan  int failure = 0, quals;
6527169699Skan
6528169699Skan  maxindex = size_zero_node;
6529169699Skan  if (initial_value)
6530169699Skan    {
6531169699Skan      if (TREE_CODE (initial_value) == STRING_CST)
6532169699Skan	{
6533169699Skan	  int eltsize
6534169699Skan	    = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
6535169699Skan	  maxindex = size_int (TREE_STRING_LENGTH (initial_value)/eltsize - 1);
6536169699Skan	}
6537169699Skan      else if (TREE_CODE (initial_value) == CONSTRUCTOR)
6538169699Skan	{
6539169699Skan	  VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initial_value);
6540169699Skan
6541169699Skan	  if (VEC_empty (constructor_elt, v))
6542169699Skan	    {
6543169699Skan	      if (pedantic)
6544169699Skan		failure = 3;
6545169699Skan	      maxindex = integer_minus_one_node;
6546169699Skan	    }
6547169699Skan	  else
6548169699Skan	    {
6549169699Skan	      tree curindex;
6550169699Skan	      unsigned HOST_WIDE_INT cnt;
6551169699Skan	      constructor_elt *ce;
6552169699Skan
6553169699Skan	      if (VEC_index (constructor_elt, v, 0)->index)
6554169699Skan		maxindex = fold_convert (sizetype,
6555169699Skan					 VEC_index (constructor_elt,
6556169699Skan						    v, 0)->index);
6557169699Skan	      curindex = maxindex;
6558169699Skan
6559169699Skan	      for (cnt = 1;
6560169699Skan		   VEC_iterate (constructor_elt, v, cnt, ce);
6561169699Skan		   cnt++)
6562169699Skan		{
6563169699Skan		  if (ce->index)
6564169699Skan		    curindex = fold_convert (sizetype, ce->index);
6565169699Skan		  else
6566169699Skan		    curindex = size_binop (PLUS_EXPR, curindex, size_one_node);
6567169699Skan
6568169699Skan		  if (tree_int_cst_lt (maxindex, curindex))
6569169699Skan		    maxindex = curindex;
6570169699Skan		}
6571169699Skan	    }
6572169699Skan	}
6573169699Skan      else
6574169699Skan	{
6575169699Skan	  /* Make an error message unless that happened already.  */
6576169699Skan	  if (initial_value != error_mark_node)
6577169699Skan	    failure = 1;
6578169699Skan	}
6579169699Skan    }
6580169699Skan  else
6581169699Skan    {
6582169699Skan      failure = 2;
6583169699Skan      if (!do_default)
6584169699Skan	return failure;
6585169699Skan    }
6586169699Skan
6587169699Skan  type = *ptype;
6588169699Skan  elt = TREE_TYPE (type);
6589169699Skan  quals = TYPE_QUALS (strip_array_types (elt));
6590169699Skan  if (quals == 0)
6591169699Skan    unqual_elt = elt;
6592169699Skan  else
6593169699Skan    unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED);
6594169699Skan
6595169699Skan  /* Using build_distinct_type_copy and modifying things afterward instead
6596169699Skan     of using build_array_type to create a new type preserves all of the
6597169699Skan     TYPE_LANG_FLAG_? bits that the front end may have set.  */
6598169699Skan  main_type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
6599169699Skan  TREE_TYPE (main_type) = unqual_elt;
6600169699Skan  TYPE_DOMAIN (main_type) = build_index_type (maxindex);
6601169699Skan  layout_type (main_type);
6602169699Skan
6603169699Skan  if (quals == 0)
6604169699Skan    type = main_type;
6605169699Skan  else
6606169699Skan    type = c_build_qualified_type (main_type, quals);
6607169699Skan
6608169699Skan  *ptype = type;
6609169699Skan  return failure;
6610132728Skan}
6611132728Skan
6612169699Skan
6613169699Skan/* Used to help initialize the builtin-types.def table.  When a type of
6614169699Skan   the correct size doesn't exist, use error_mark_node instead of NULL.
6615169699Skan   The later results in segfaults even when a decl using the type doesn't
6616169699Skan   get invoked.  */
6617132728Skan
6618169699Skantree
6619169699Skanbuiltin_type_for_size (int size, bool unsignedp)
6620169699Skan{
6621169699Skan  tree type = lang_hooks.types.type_for_size (size, unsignedp);
6622169699Skan  return type ? type : error_mark_node;
6623169699Skan}
6624169699Skan
6625169699Skan/* A helper function for resolve_overloaded_builtin in resolving the
6626169699Skan   overloaded __sync_ builtins.  Returns a positive power of 2 if the
6627169699Skan   first operand of PARAMS is a pointer to a supported data type.
6628169699Skan   Returns 0 if an error is encountered.  */
6629169699Skan
6630169699Skanstatic int
6631169699Skansync_resolve_size (tree function, tree params)
6632169699Skan{
6633169699Skan  tree type;
6634169699Skan  int size;
6635169699Skan
6636169699Skan  if (params == NULL)
6637169699Skan    {
6638169699Skan      error ("too few arguments to function %qE", function);
6639169699Skan      return 0;
6640169699Skan    }
6641169699Skan
6642169699Skan  type = TREE_TYPE (TREE_VALUE (params));
6643169699Skan  if (TREE_CODE (type) != POINTER_TYPE)
6644169699Skan    goto incompatible;
6645169699Skan
6646169699Skan  type = TREE_TYPE (type);
6647169699Skan  if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
6648169699Skan    goto incompatible;
6649169699Skan
6650169699Skan  size = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
6651169699Skan  if (size == 1 || size == 2 || size == 4 || size == 8 || size == 16)
6652169699Skan    return size;
6653169699Skan
6654169699Skan incompatible:
6655169699Skan  error ("incompatible type for argument %d of %qE", 1, function);
6656169699Skan  return 0;
6657169699Skan}
6658169699Skan
6659169699Skan/* A helper function for resolve_overloaded_builtin.  Adds casts to
6660169699Skan   PARAMS to make arguments match up with those of FUNCTION.  Drops
6661169699Skan   the variadic arguments at the end.  Returns false if some error
6662169699Skan   was encountered; true on success.  */
6663169699Skan
6664169699Skanstatic bool
6665169699Skansync_resolve_params (tree orig_function, tree function, tree params)
6666169699Skan{
6667169699Skan  tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (function));
6668169699Skan  tree ptype;
6669169699Skan  int number;
6670169699Skan
6671169699Skan  /* We've declared the implementation functions to use "volatile void *"
6672169699Skan     as the pointer parameter, so we shouldn't get any complaints from the
6673169699Skan     call to check_function_arguments what ever type the user used.  */
6674169699Skan  arg_types = TREE_CHAIN (arg_types);
6675169699Skan  ptype = TREE_TYPE (TREE_TYPE (TREE_VALUE (params)));
6676169699Skan  number = 2;
6677169699Skan
6678169699Skan  /* For the rest of the values, we need to cast these to FTYPE, so that we
6679169699Skan     don't get warnings for passing pointer types, etc.  */
6680169699Skan  while (arg_types != void_list_node)
6681169699Skan    {
6682169699Skan      tree val;
6683169699Skan
6684169699Skan      params = TREE_CHAIN (params);
6685169699Skan      if (params == NULL)
6686169699Skan	{
6687169699Skan	  error ("too few arguments to function %qE", orig_function);
6688169699Skan	  return false;
6689169699Skan	}
6690169699Skan
6691169699Skan      /* ??? Ideally for the first conversion we'd use convert_for_assignment
6692169699Skan	 so that we get warnings for anything that doesn't match the pointer
6693169699Skan	 type.  This isn't portable across the C and C++ front ends atm.  */
6694169699Skan      val = TREE_VALUE (params);
6695169699Skan      val = convert (ptype, val);
6696169699Skan      val = convert (TREE_VALUE (arg_types), val);
6697169699Skan      TREE_VALUE (params) = val;
6698169699Skan
6699169699Skan      arg_types = TREE_CHAIN (arg_types);
6700169699Skan      number++;
6701169699Skan    }
6702169699Skan
6703169699Skan  /* The definition of these primitives is variadic, with the remaining
6704169699Skan     being "an optional list of variables protected by the memory barrier".
6705169699Skan     No clue what that's supposed to mean, precisely, but we consider all
6706169699Skan     call-clobbered variables to be protected so we're safe.  */
6707169699Skan  TREE_CHAIN (params) = NULL;
6708169699Skan
6709169699Skan  return true;
6710169699Skan}
6711169699Skan
6712169699Skan/* A helper function for resolve_overloaded_builtin.  Adds a cast to
6713169699Skan   RESULT to make it match the type of the first pointer argument in
6714169699Skan   PARAMS.  */
6715169699Skan
6716132728Skanstatic tree
6717169699Skansync_resolve_return (tree params, tree result)
6718132728Skan{
6719169699Skan  tree ptype = TREE_TYPE (TREE_TYPE (TREE_VALUE (params)));
6720169699Skan  ptype = TYPE_MAIN_VARIANT (ptype);
6721169699Skan  return convert (ptype, result);
6722169699Skan}
6723169699Skan
6724169699Skan/* Some builtin functions are placeholders for other expressions.  This
6725169699Skan   function should be called immediately after parsing the call expression
6726169699Skan   before surrounding code has committed to the type of the expression.
6727169699Skan
6728169699Skan   FUNCTION is the DECL that has been invoked; it is known to be a builtin.
6729169699Skan   PARAMS is the argument list for the call.  The return value is non-null
6730169699Skan   when expansion is complete, and null if normal processing should
6731169699Skan   continue.  */
6732169699Skan
6733169699Skantree
6734169699Skanresolve_overloaded_builtin (tree function, tree params)
6735169699Skan{
6736169699Skan  enum built_in_function orig_code = DECL_FUNCTION_CODE (function);
6737169699Skan  switch (DECL_BUILT_IN_CLASS (function))
6738132728Skan    {
6739169699Skan    case BUILT_IN_NORMAL:
6740169699Skan      break;
6741169699Skan    case BUILT_IN_MD:
6742169699Skan      if (targetm.resolve_overloaded_builtin)
6743169699Skan	return targetm.resolve_overloaded_builtin (function, params);
6744169699Skan      else
6745169699Skan	return NULL_TREE;
6746169699Skan    default:
6747132728Skan      return NULL_TREE;
6748132728Skan    }
6749169699Skan
6750169699Skan  /* Handle BUILT_IN_NORMAL here.  */
6751169699Skan  switch (orig_code)
6752169699Skan    {
6753169699Skan    case BUILT_IN_FETCH_AND_ADD_N:
6754169699Skan    case BUILT_IN_FETCH_AND_SUB_N:
6755169699Skan    case BUILT_IN_FETCH_AND_OR_N:
6756169699Skan    case BUILT_IN_FETCH_AND_AND_N:
6757169699Skan    case BUILT_IN_FETCH_AND_XOR_N:
6758169699Skan    case BUILT_IN_FETCH_AND_NAND_N:
6759169699Skan    case BUILT_IN_ADD_AND_FETCH_N:
6760169699Skan    case BUILT_IN_SUB_AND_FETCH_N:
6761169699Skan    case BUILT_IN_OR_AND_FETCH_N:
6762169699Skan    case BUILT_IN_AND_AND_FETCH_N:
6763169699Skan    case BUILT_IN_XOR_AND_FETCH_N:
6764169699Skan    case BUILT_IN_NAND_AND_FETCH_N:
6765169699Skan    case BUILT_IN_BOOL_COMPARE_AND_SWAP_N:
6766169699Skan    case BUILT_IN_VAL_COMPARE_AND_SWAP_N:
6767169699Skan    case BUILT_IN_LOCK_TEST_AND_SET_N:
6768169699Skan    case BUILT_IN_LOCK_RELEASE_N:
6769169699Skan      {
6770169699Skan	int n = sync_resolve_size (function, params);
6771169699Skan	tree new_function, result;
6772169699Skan
6773169699Skan	if (n == 0)
6774169699Skan	  return error_mark_node;
6775169699Skan
6776169699Skan	new_function = built_in_decls[orig_code + exact_log2 (n) + 1];
6777169699Skan	if (!sync_resolve_params (function, new_function, params))
6778169699Skan	  return error_mark_node;
6779169699Skan
6780169699Skan	result = build_function_call (new_function, params);
6781169699Skan	if (orig_code != BUILT_IN_BOOL_COMPARE_AND_SWAP_N
6782169699Skan	    && orig_code != BUILT_IN_LOCK_RELEASE_N)
6783169699Skan	  result = sync_resolve_return (params, result);
6784169699Skan
6785169699Skan	return result;
6786169699Skan      }
6787169699Skan
6788169699Skan    default:
6789169699Skan      return NULL_TREE;
6790169699Skan    }
6791132728Skan}
6792132728Skan
6793169699Skan/* Ignoring their sign, return true if two scalar types are the same.  */
6794132728Skanbool
6795169699Skansame_scalar_type_ignoring_signedness (tree t1, tree t2)
6796132728Skan{
6797169699Skan  enum tree_code c1 = TREE_CODE (t1), c2 = TREE_CODE (t2);
6798132728Skan
6799169699Skan  gcc_assert ((c1 == INTEGER_TYPE || c1 == REAL_TYPE)
6800169699Skan	      && (c2 == INTEGER_TYPE || c2 == REAL_TYPE));
6801169699Skan
6802169699Skan  /* Equality works here because c_common_signed_type uses
6803169699Skan     TYPE_MAIN_VARIANT.  */
6804169699Skan  return lang_hooks.types.signed_type (t1)
6805169699Skan    == lang_hooks.types.signed_type (t2);
6806132728Skan}
6807132728Skan
6808169699Skan/* Check for missing format attributes on function pointers.  LTYPE is
6809169699Skan   the new type or left-hand side type.  RTYPE is the old type or
6810169699Skan   right-hand side type.  Returns TRUE if LTYPE is missing the desired
6811169699Skan   attribute.  */
6812132728Skan
6813169699Skanbool
6814169699Skancheck_missing_format_attribute (tree ltype, tree rtype)
6815132728Skan{
6816169699Skan  tree const ttr = TREE_TYPE (rtype), ttl = TREE_TYPE (ltype);
6817169699Skan  tree ra;
6818132728Skan
6819169699Skan  for (ra = TYPE_ATTRIBUTES (ttr); ra; ra = TREE_CHAIN (ra))
6820169699Skan    if (is_attribute_p ("format", TREE_PURPOSE (ra)))
6821169699Skan      break;
6822169699Skan  if (ra)
6823132728Skan    {
6824169699Skan      tree la;
6825169699Skan      for (la = TYPE_ATTRIBUTES (ttl); la; la = TREE_CHAIN (la))
6826169699Skan	if (is_attribute_p ("format", TREE_PURPOSE (la)))
6827169699Skan	  break;
6828169699Skan      return !la;
6829132728Skan    }
6830132728Skan  else
6831169699Skan    return false;
6832132728Skan}
6833132728Skan
6834169699Skan/* Subscripting with type char is likely to lose on a machine where
6835169699Skan   chars are signed.  So warn on any machine, but optionally.  Don't
6836169699Skan   warn for unsigned char since that type is safe.  Don't warn for
6837169699Skan   signed char because anyone who uses that must have done so
6838169699Skan   deliberately. Furthermore, we reduce the false positive load by
6839169699Skan   warning only for non-constant value of type char.  */
6840169699Skan
6841169699Skanvoid
6842169699Skanwarn_array_subscript_with_type_char (tree index)
6843169699Skan{
6844169699Skan  if (TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node
6845169699Skan      && TREE_CODE (index) != INTEGER_CST)
6846169699Skan    warning (OPT_Wchar_subscripts, "array subscript has type %<char%>");
6847169699Skan}
6848169699Skan
6849259268Spfg/* Implement -Wparentheses for the unexpected C precedence rules, to
6850259268Spfg   cover cases like x + y << z which readers are likely to
6851259268Spfg   misinterpret.  We have seen an expression in which CODE is a binary
6852259268Spfg   operator used to combine expressions headed by CODE_LEFT and
6853259268Spfg   CODE_RIGHT.  CODE_LEFT and CODE_RIGHT may be ERROR_MARK, which
6854259268Spfg   means that that side of the expression was not formed using a
6855259268Spfg   binary operator, or it was enclosed in parentheses.  */
6856169699Skan
6857259268Spfgvoid
6858259268Spfgwarn_about_parentheses (enum tree_code code, enum tree_code code_left,
6859259268Spfg			enum tree_code code_right)
6860259268Spfg{
6861259268Spfg  if (!warn_parentheses)
6862259268Spfg    return;
6863259268Spfg
6864259268Spfg  if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
6865259268Spfg    {
6866259268Spfg      if (code_left == PLUS_EXPR || code_left == MINUS_EXPR
6867259268Spfg	  || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
6868259268Spfg	warning (OPT_Wparentheses,
6869259268Spfg		 "suggest parentheses around + or - inside shift");
6870259268Spfg    }
6871259268Spfg
6872259268Spfg  if (code == TRUTH_ORIF_EXPR)
6873259268Spfg    {
6874259268Spfg      if (code_left == TRUTH_ANDIF_EXPR
6875259268Spfg	  || code_right == TRUTH_ANDIF_EXPR)
6876259268Spfg	warning (OPT_Wparentheses,
6877259268Spfg		 "suggest parentheses around && within ||");
6878259268Spfg    }
6879259268Spfg
6880259268Spfg  if (code == BIT_IOR_EXPR)
6881259268Spfg    {
6882259268Spfg      if (code_left == BIT_AND_EXPR || code_left == BIT_XOR_EXPR
6883259268Spfg	  || code_left == PLUS_EXPR || code_left == MINUS_EXPR
6884259268Spfg	  || code_right == BIT_AND_EXPR || code_right == BIT_XOR_EXPR
6885259268Spfg	  || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
6886259268Spfg	warning (OPT_Wparentheses,
6887259268Spfg		 "suggest parentheses around arithmetic in operand of |");
6888259268Spfg      /* Check cases like x|y==z */
6889259268Spfg      if (TREE_CODE_CLASS (code_left) == tcc_comparison
6890259268Spfg	  || TREE_CODE_CLASS (code_right) == tcc_comparison)
6891259268Spfg	warning (OPT_Wparentheses,
6892259268Spfg		 "suggest parentheses around comparison in operand of |");
6893259268Spfg    }
6894259268Spfg
6895259268Spfg  if (code == BIT_XOR_EXPR)
6896259268Spfg    {
6897259268Spfg      if (code_left == BIT_AND_EXPR
6898259268Spfg	  || code_left == PLUS_EXPR || code_left == MINUS_EXPR
6899259268Spfg	  || code_right == BIT_AND_EXPR
6900259268Spfg	  || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
6901259268Spfg	warning (OPT_Wparentheses,
6902259268Spfg		 "suggest parentheses around arithmetic in operand of ^");
6903259268Spfg      /* Check cases like x^y==z */
6904259268Spfg      if (TREE_CODE_CLASS (code_left) == tcc_comparison
6905259268Spfg	  || TREE_CODE_CLASS (code_right) == tcc_comparison)
6906259268Spfg	warning (OPT_Wparentheses,
6907259268Spfg		 "suggest parentheses around comparison in operand of ^");
6908259268Spfg    }
6909259268Spfg
6910259268Spfg  if (code == BIT_AND_EXPR)
6911259268Spfg    {
6912259268Spfg      if (code_left == PLUS_EXPR || code_left == MINUS_EXPR
6913259268Spfg	  || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
6914259268Spfg	warning (OPT_Wparentheses,
6915259268Spfg		 "suggest parentheses around + or - in operand of &");
6916259268Spfg      /* Check cases like x&y==z */
6917259268Spfg      if (TREE_CODE_CLASS (code_left) == tcc_comparison
6918259268Spfg	  || TREE_CODE_CLASS (code_right) == tcc_comparison)
6919259268Spfg	warning (OPT_Wparentheses,
6920259268Spfg		 "suggest parentheses around comparison in operand of &");
6921259268Spfg    }
6922259268Spfg
6923259268Spfg  /* Similarly, check for cases like 1<=i<=10 that are probably errors.  */
6924259268Spfg  if (TREE_CODE_CLASS (code) == tcc_comparison
6925259268Spfg      && (TREE_CODE_CLASS (code_left) == tcc_comparison
6926259268Spfg	  || TREE_CODE_CLASS (code_right) == tcc_comparison))
6927259268Spfg    warning (OPT_Wparentheses, "comparisons like X<=Y<=Z do not "
6928259268Spfg	     "have their mathematical meaning");
6929259268Spfg}
6930259268Spfg
6931261188Spfg/* APPLE LOCAL begin radar 6246527 */
6932261188Spfg/* This routine is called for a "format" attribute. It adds the number of
6933261188Spfg hidden argument ('1') to the format's 2nd and 3rd argument to compensate
6934261188Spfg for these two arguments. This is to make rest of the "format" attribute
6935261188Spfg processing done in the middle-end to work seemlessly. */
6936259268Spfg
6937261188Spfgstatic void
6938261188Spfgblock_delta_format_args (tree format)
6939261188Spfg{
6940261188Spfg  tree format_num_expr, first_arg_num_expr;
6941261188Spfg  int val;
6942261188Spfg  tree args = TREE_VALUE (format);
6943261188Spfg  gcc_assert (TREE_CHAIN (args) && TREE_CHAIN (TREE_CHAIN (args)));
6944261188Spfg  format_num_expr = TREE_VALUE (TREE_CHAIN (args));
6945261188Spfg  first_arg_num_expr = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
6946261188Spfg  if (format_num_expr && TREE_CODE (format_num_expr) == INTEGER_CST)
6947261188Spfg  {
6948261188Spfg      val = TREE_INT_CST_LOW (format_num_expr);
6949261188Spfg      TREE_VALUE (TREE_CHAIN (args)) = build_int_cst (NULL_TREE, val+1);
6950261188Spfg  }
6951261188Spfg  if (first_arg_num_expr && TREE_CODE (first_arg_num_expr) == INTEGER_CST)
6952261188Spfg  {
6953261188Spfg      val = TREE_INT_CST_LOW (first_arg_num_expr);
6954261188Spfg      if (val != 0)
6955261188Spfg	TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args))) =
6956261188Spfg	build_int_cst (NULL_TREE, val+1);
6957261188Spfg  }
6958261188Spfg}
6959261188Spfg
6960261188Spfg/* This routine recognizes legal block attributes. In case of block's "format"
6961261188Spfg attribute, it calls block_delta_format_args to compensate for hidden
6962261188Spfg argument _self getting passed to block's helper function. */
6963261188Spfgbool
6964261188Spfgany_recognized_block_attribute (tree attributes)
6965261188Spfg{
6966261188Spfg  tree chain;
6967261188Spfg  bool res = false;
6968261188Spfg  for (chain = attributes; chain; chain = TREE_CHAIN (chain))
6969261188Spfg  {
6970261188Spfg      if (is_attribute_p ("format", TREE_PURPOSE (chain)))
6971261188Spfg      {
6972261188Spfg	block_delta_format_args (chain);
6973261188Spfg	res = true;
6974261188Spfg      }
6975261188Spfg      else if (is_attribute_p ("sentinel", TREE_PURPOSE (chain)))
6976261188Spfg	res = true;
6977261188Spfg  }
6978261188Spfg  return res;
6979261188Spfg}
6980261188Spfg/* APPLE LOCAL end radar 6246527 */
6981261188Spfg/* APPLE LOCAL begin radar 5847976 */
6982261188Spfgstatic GTY(()) tree block_object_assign_decl;
6983261188Spfgstatic GTY(()) tree block_object_dispose_func_decl;
6984261188Spfg/* This routine declares:
6985261188Spfg   void _Block_object_assign (void *, void *, int) or uses an
6986261188Spfg   existing one.
6987261188Spfg*/
6988261188Spfgstatic tree
6989261188Spfgbuild_block_object_assign_decl (void)
6990261188Spfg{
6991261188Spfg  tree func_type;
6992261188Spfg  if (block_object_assign_decl)
6993261188Spfg    return block_object_assign_decl;
6994261188Spfg  block_object_assign_decl = lookup_name (get_identifier ("_Block_object_assign"));
6995261188Spfg  if (block_object_assign_decl)
6996261188Spfg    return block_object_assign_decl;
6997261188Spfg  func_type =
6998261188Spfg	     build_function_type (void_type_node,
6999261188Spfg	       tree_cons (NULL_TREE, ptr_type_node,
7000261188Spfg			  tree_cons (NULL_TREE, ptr_type_node,
7001261188Spfg			             tree_cons (NULL_TREE, integer_type_node, void_list_node))));
7002261188Spfg
7003261188Spfg  block_object_assign_decl = builtin_function ("_Block_object_assign", func_type,
7004261188Spfg					        0, NOT_BUILT_IN, 0, NULL_TREE);
7005261188Spfg  TREE_NOTHROW (block_object_assign_decl) = 0;
7006261188Spfg  return block_object_assign_decl;
7007261188Spfg}
7008261188Spfg
7009261188Spfg/* This routine builds:
7010261188Spfg   _Block_object_assign(dest, src, flag)
7011261188Spfg*/
7012261188Spfgtree build_block_object_assign_call_exp (tree dst, tree src, int flag)
7013261188Spfg{
7014261188Spfg  tree func_params = tree_cons (NULL_TREE, dst,
7015261188Spfg			        tree_cons (NULL_TREE, src,
7016261188Spfg				           tree_cons (NULL_TREE,
7017261188Spfg						      build_int_cst (integer_type_node, flag),
7018261188Spfg						      NULL_TREE)));
7019261188Spfg  return build_function_call (build_block_object_assign_decl (), func_params);
7020261188Spfg}
7021261188Spfg
7022261188Spfg/* This routine declares:
7023261188Spfg   void _Block_object_dispose (void *, int) or uses an
7024261188Spfg   existing one.
7025261188Spfg*/
7026261188Spfgstatic tree
7027261188Spfgbuild_block_object_dispose_decl (void)
7028261188Spfg{
7029261188Spfg  tree func_type;
7030261188Spfg  if (block_object_dispose_func_decl)
7031261188Spfg    return block_object_dispose_func_decl;
7032261188Spfg  block_object_dispose_func_decl = lookup_name (get_identifier ("_Block_object_dispose"));
7033261188Spfg  if (block_object_dispose_func_decl)
7034261188Spfg    return block_object_dispose_func_decl;
7035261188Spfg  func_type =
7036261188Spfg      build_function_type (void_type_node,
7037261188Spfg			    tree_cons (NULL_TREE, ptr_type_node,
7038261188Spfg				       tree_cons (NULL_TREE, integer_type_node, void_list_node)));
7039261188Spfg
7040261188Spfg  block_object_dispose_func_decl = builtin_function ("_Block_object_dispose", func_type,
7041261188Spfg						      0, NOT_BUILT_IN, 0, NULL_TREE);
7042261188Spfg  TREE_NOTHROW (block_object_dispose_func_decl) = 0;
7043261188Spfg  return block_object_dispose_func_decl;
7044261188Spfg}
7045261188Spfg
7046261188Spfg/* This routine builds the call tree:
7047261188Spfg   _Block_object_dispose(src, flag)
7048261188Spfg*/
7049261188Spfgtree build_block_object_dispose_call_exp (tree src, int flag)
7050261188Spfg{
7051261188Spfg  tree func_params = tree_cons (NULL_TREE, src,
7052261188Spfg			        tree_cons (NULL_TREE,
7053261188Spfg					    build_int_cst (integer_type_node, flag),
7054261188Spfg					   NULL_TREE));
7055261188Spfg  return build_function_call (build_block_object_dispose_decl (), func_params);
7056261188Spfg}
7057261188Spfg/* APPLE LOCAL end radar 5847976 */
7058261188Spfg/* APPLE LOCAL begin radar 7760213 */
7059261188Spfgint HasByrefArray(tree byrefType)
7060261188Spfg{
7061261188Spfg  tree s1;
7062261188Spfg  /* Check for possibility of an error condition. */
7063261188Spfg  if (TREE_CODE(byrefType) != RECORD_TYPE)
7064261188Spfg    return 0;
7065261188Spfg
7066261188Spfg  for (s1 = TYPE_FIELDS (byrefType); s1; s1 = TREE_CHAIN (s1))
7067261188Spfg    {
7068261188Spfg      if (TREE_CODE(TREE_TYPE(s1)) == ARRAY_TYPE)
7069261188Spfg	 return 1;
7070261188Spfg    }
7071261188Spfg  return 0;
7072261188Spfg}
7073261188Spfg/* APPLE LOCAL end radar 7760213 */
7074117404Skan#include "gt-c-common.h"
7075