summaryrefslogtreecommitdiff
path: root/gcc/c/c-decl.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2015-04-22 10:21:45 +0000
committer <>2015-04-25 21:44:09 +0000
commitf80b5ea1605c9f9408c5aa386ba71c16d918ebbf (patch)
treebb7eafaa81fc4b8c5c215bc08d517fd158db234a /gcc/c/c-decl.c
parentc27a97d04853380f1e80525391b3f0d156ed4c84 (diff)
downloadgcc-tarball-f80b5ea1605c9f9408c5aa386ba71c16d918ebbf.tar.gz
Imported from /home/lorry/working-area/delta_gcc-tarball/gcc-5.1.0.tar.bz2.gcc-5.1.0
Diffstat (limited to 'gcc/c/c-decl.c')
-rw-r--r--gcc/c/c-decl.c900
1 files changed, 648 insertions, 252 deletions
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 47907d5ec7..e28a294dcc 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -1,5 +1,5 @@
/* Process declarations and variables for C compiler.
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2015 Free Software Foundation, Inc.
This file is part of GCC.
@@ -30,7 +30,16 @@ along with GCC; see the file COPYING3. If not see
#include "input.h"
#include "tm.h"
#include "intl.h"
+#include "hash-set.h"
+#include "vec.h"
+#include "symtab.h"
+#include "input.h"
+#include "alias.h"
+#include "double-int.h"
+#include "machmode.h"
+#include "inchash.h"
#include "tree.h"
+#include "fold-const.h"
#include "print-tree.h"
#include "stor-layout.h"
#include "varasm.h"
@@ -38,6 +47,11 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "tree-inline.h"
#include "flags.h"
+#include "hashtab.h"
+#include "hash-set.h"
+#include "vec.h"
+#include "machmode.h"
+#include "hard-reg-set.h"
#include "function.h"
#include "c-tree.h"
#include "toplev.h"
@@ -56,13 +70,17 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "diagnostic-core.h"
#include "dumpfile.h"
+#include "hash-map.h"
+#include "is-a.h"
+#include "plugin-api.h"
+#include "ipa-ref.h"
#include "cgraph.h"
#include "hash-table.h"
#include "langhooks-def.h"
-#include "pointer-set.h"
#include "plugin.h"
#include "c-family/c-ada-spec.h"
#include "cilk.h"
+#include "builtins.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
@@ -150,10 +168,6 @@ static int warn_about_return_type;
static bool undef_nested_function;
-/* Mode used to build pointers (VOIDmode means ptr_mode). */
-
-enum machine_mode c_default_pointer_mode = VOIDmode;
-
/* If non-zero, implicit "omp declare target" attribute is added into the
attribute lists. */
int current_omp_declare_target_attribute;
@@ -215,21 +229,6 @@ struct GTY((chain_next ("%h.prev"))) c_binding {
#define B_IN_FILE_SCOPE(b) ((b)->depth == 1 /*file_scope->depth*/)
#define B_IN_EXTERNAL_SCOPE(b) ((b)->depth == 0 /*external_scope->depth*/)
-#define I_SYMBOL_BINDING(node) \
- (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->symbol_binding)
-#define I_SYMBOL_DECL(node) \
- (I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
-
-#define I_TAG_BINDING(node) \
- (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->tag_binding)
-#define I_TAG_DECL(node) \
- (I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
-
-#define I_LABEL_BINDING(node) \
- (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->label_binding)
-#define I_LABEL_DECL(node) \
- (I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
-
/* Each C symbol points to three linked lists of c_binding structures.
These describe the values of the identifier in the three different
namespaces defined by the language. */
@@ -245,6 +244,96 @@ struct GTY(()) lang_identifier {
extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
[(sizeof(struct lang_identifier) == C_SIZEOF_STRUCT_LANG_IDENTIFIER) ? 1 : -1];
+/* The binding oracle; see c-tree.h. */
+void (*c_binding_oracle) (enum c_oracle_request, tree identifier);
+
+/* This flag is set on an identifier if we have previously asked the
+ binding oracle for this identifier's symbol binding. */
+#define I_SYMBOL_CHECKED(node) \
+ (TREE_LANG_FLAG_4 (IDENTIFIER_NODE_CHECK (node)))
+
+static inline struct c_binding* *
+i_symbol_binding (tree node)
+{
+ struct lang_identifier *lid
+ = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
+
+ if (lid->symbol_binding == NULL
+ && c_binding_oracle != NULL
+ && !I_SYMBOL_CHECKED (node))
+ {
+ /* Set the "checked" flag first, to avoid infinite recursion
+ when the binding oracle calls back into gcc. */
+ I_SYMBOL_CHECKED (node) = 1;
+ c_binding_oracle (C_ORACLE_SYMBOL, node);
+ }
+
+ return &lid->symbol_binding;
+}
+
+#define I_SYMBOL_BINDING(node) (*i_symbol_binding (node))
+
+#define I_SYMBOL_DECL(node) \
+ (I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
+
+/* This flag is set on an identifier if we have previously asked the
+ binding oracle for this identifier's tag binding. */
+#define I_TAG_CHECKED(node) \
+ (TREE_LANG_FLAG_5 (IDENTIFIER_NODE_CHECK (node)))
+
+static inline struct c_binding **
+i_tag_binding (tree node)
+{
+ struct lang_identifier *lid
+ = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
+
+ if (lid->tag_binding == NULL
+ && c_binding_oracle != NULL
+ && !I_TAG_CHECKED (node))
+ {
+ /* Set the "checked" flag first, to avoid infinite recursion
+ when the binding oracle calls back into gcc. */
+ I_TAG_CHECKED (node) = 1;
+ c_binding_oracle (C_ORACLE_TAG, node);
+ }
+
+ return &lid->tag_binding;
+}
+
+#define I_TAG_BINDING(node) (*i_tag_binding (node))
+
+#define I_TAG_DECL(node) \
+ (I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
+
+/* This flag is set on an identifier if we have previously asked the
+ binding oracle for this identifier's label binding. */
+#define I_LABEL_CHECKED(node) \
+ (TREE_LANG_FLAG_6 (IDENTIFIER_NODE_CHECK (node)))
+
+static inline struct c_binding **
+i_label_binding (tree node)
+{
+ struct lang_identifier *lid
+ = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
+
+ if (lid->label_binding == NULL
+ && c_binding_oracle != NULL
+ && !I_LABEL_CHECKED (node))
+ {
+ /* Set the "checked" flag first, to avoid infinite recursion
+ when the binding oracle calls back into gcc. */
+ I_LABEL_CHECKED (node) = 1;
+ c_binding_oracle (C_ORACLE_LABEL, node);
+ }
+
+ return &lid->label_binding;
+}
+
+#define I_LABEL_BINDING(node) (*i_label_binding (node))
+
+#define I_LABEL_DECL(node) \
+ (I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
+
/* The resulting tree type. */
union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
@@ -537,6 +626,8 @@ static tree grokdeclarator (const struct c_declarator *,
bool *, enum deprecated_states);
static tree grokparms (struct c_arg_info *, bool);
static void layout_array_type (tree);
+static void warn_defaults_to (location_t, int, const char *, ...)
+ ATTRIBUTE_GCC_DIAG(3,4);
/* T is a statement. Add it to the statement-tree. This is the
C/ObjC version--C++ has a slightly different version of this
@@ -572,7 +663,7 @@ c_build_pointer_type (tree to_type)
{
addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
: TYPE_ADDR_SPACE (to_type);
- enum machine_mode pointer_mode;
+ machine_mode pointer_mode;
if (as != ADDR_SPACE_GENERIC || c_default_pointer_mode == VOIDmode)
pointer_mode = targetm.addr_space.pointer_mode (as);
@@ -611,6 +702,15 @@ decl_jump_unsafe (tree decl)
void
c_print_identifier (FILE *file, tree node, int indent)
{
+ void (*save) (enum c_oracle_request, tree identifier);
+
+ /* Temporarily hide any binding oracle. Without this, calls to
+ debug_tree from the debugger will end up calling into the oracle,
+ making for a confusing debug session. As the oracle isn't needed
+ here for normal operation, it's simplest to suppress it. */
+ save = c_binding_oracle;
+ c_binding_oracle = NULL;
+
print_node (file, "symbol", I_SYMBOL_DECL (node), indent + 4);
print_node (file, "tag", I_TAG_DECL (node), indent + 4);
print_node (file, "label", I_LABEL_DECL (node), indent + 4);
@@ -621,6 +721,8 @@ c_print_identifier (FILE *file, tree node, int indent)
fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"",
(void *) rid, IDENTIFIER_POINTER (rid));
}
+
+ c_binding_oracle = save;
}
/* Establish a binding between NAME, an IDENTIFIER_NODE, and DECL,
@@ -638,7 +740,7 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible,
binding_freelist = b->prev;
}
else
- b = ggc_alloc_c_binding ();
+ b = ggc_alloc<c_binding> ();
b->shadowed = 0;
b->decl = decl;
@@ -755,7 +857,7 @@ void
record_inline_static (location_t loc, tree func, tree decl,
enum c_inline_static_type type)
{
- struct c_inline_static *csi = ggc_alloc_c_inline_static ();
+ c_inline_static *csi = ggc_alloc<c_inline_static> ();
csi->location = loc;
csi->function = func;
csi->static_decl = decl;
@@ -952,7 +1054,7 @@ push_scope (void)
scope_freelist = scope->outer;
}
else
- scope = ggc_alloc_cleared_c_scope ();
+ scope = ggc_cleared_alloc<c_scope> ();
/* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */
if (current_scope)
@@ -1174,7 +1276,9 @@ pop_scope (void)
/* C99 6.7.4p6: "a function with external linkage... declared
with an inline function specifier ... shall also be defined
in the same translation unit." */
- if (!flag_gnu89_inline)
+ if (!flag_gnu89_inline
+ && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (p))
+ && scope != external_scope)
pedwarn (input_location, 0,
"inline function %q+D declared but never defined", p);
DECL_EXTERNAL (p) = 1;
@@ -1485,6 +1589,54 @@ pushtag (location_t loc, tree name, tree type)
}
}
}
+
+/* An exported interface to pushtag. This is used by the gdb plugin's
+ binding oracle to introduce a new tag binding. */
+
+void
+c_pushtag (location_t loc, tree name, tree type)
+{
+ pushtag (loc, name, type);
+}
+
+/* An exported interface to bind a declaration. LOC is the location
+ to use. DECL is the declaration to bind. The decl's name is used
+ to determine how it is bound. If DECL is a VAR_DECL, then
+ IS_GLOBAL determines whether the decl is put into the global (file
+ and external) scope or the current function's scope; if DECL is not
+ a VAR_DECL then it is always put into the file scope. */
+
+void
+c_bind (location_t loc, tree decl, bool is_global)
+{
+ struct c_scope *scope;
+ bool nested = false;
+
+ if (TREE_CODE (decl) != VAR_DECL || current_function_scope == NULL)
+ {
+ /* Types and functions are always considered to be global. */
+ scope = file_scope;
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ }
+ else if (is_global)
+ {
+ /* Also bind it into the external scope. */
+ bind (DECL_NAME (decl), decl, external_scope, true, false, loc);
+ nested = true;
+ scope = file_scope;
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ }
+ else
+ {
+ DECL_CONTEXT (decl) = current_function_decl;
+ TREE_PUBLIC (decl) = 0;
+ scope = current_function_scope;
+ }
+
+ bind (DECL_NAME (decl), decl, scope, false, nested, loc);
+}
/* Subroutine of compare_decls. Allow harmless mismatches in return
and argument types provided that the type modes match. This function
@@ -1843,12 +1995,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
newdecl);
locate_old_decl (olddecl);
}
- else if (pedantic && !flag_isoc11)
- {
- pedwarn (input_location, OPT_Wpedantic,
- "redefinition of typedef %q+D", newdecl);
- locate_old_decl (olddecl);
- }
+ else if (pedwarn_c99 (input_location, OPT_Wpedantic,
+ "redefinition of typedef %q+D", newdecl))
+ locate_old_decl (olddecl);
return true;
}
@@ -2099,18 +2248,38 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
/* Diagnose inline __attribute__ ((noinline)) which is silly. */
if (DECL_DECLARED_INLINE_P (newdecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
- {
- warned |= warning (OPT_Wattributes,
- "inline declaration of %qD follows "
- "declaration with attribute noinline", newdecl);
- }
+ warned |= warning (OPT_Wattributes,
+ "inline declaration of %qD follows "
+ "declaration with attribute noinline", newdecl);
else if (DECL_DECLARED_INLINE_P (olddecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
- {
- warned |= warning (OPT_Wattributes,
- "declaration of %q+D with attribute "
- "noinline follows inline declaration ", newdecl);
- }
+ warned |= warning (OPT_Wattributes,
+ "declaration of %q+D with attribute "
+ "noinline follows inline declaration ", newdecl);
+ else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("always_inline", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes,
+ "declaration of %q+D with attribute "
+ "%qs follows declaration with attribute %qs",
+ newdecl, "noinline", "always_inline");
+ else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes,
+ "declaration of %q+D with attribute "
+ "%qs follows declaration with attribute %qs",
+ newdecl, "always_inline", "noinline");
+ else if (lookup_attribute ("cold", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("hot", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes,
+ "declaration of %q+D with attribute %qs follows "
+ "declaration with attribute %qs", newdecl, "cold",
+ "hot");
+ else if (lookup_attribute ("hot", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("cold", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes,
+ "declaration of %q+D with attribute %qs follows "
+ "declaration with attribute %qs", newdecl, "hot",
+ "cold");
}
else /* PARM_DECL, VAR_DECL */
{
@@ -2272,20 +2441,10 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
/* Merge the threadprivate attribute. */
if (TREE_CODE (olddecl) == VAR_DECL && C_DECL_THREADPRIVATE_P (olddecl))
- {
- DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl);
- C_DECL_THREADPRIVATE_P (newdecl) = 1;
- }
+ C_DECL_THREADPRIVATE_P (newdecl) = 1;
if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS))
{
- /* Merge the section attribute.
- We want to issue an error if the sections conflict but that
- must be done later in decl_attributes since we are called
- before attributes are assigned. */
- if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
- DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
-
/* Copy the assembler name.
Currently, it can only be defined in the prototype. */
COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
@@ -2419,6 +2578,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
set_builtin_decl_implicit_p (fncode, true);
break;
default:
+ if (builtin_decl_explicit_p (fncode))
+ set_builtin_decl_declared_p (fncode, true);
break;
}
}
@@ -2487,8 +2648,32 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
switch (TREE_CODE (olddecl))
{
case FUNCTION_DECL:
- case FIELD_DECL:
case VAR_DECL:
+ {
+ struct symtab_node *snode = olddecl->decl_with_vis.symtab_node;
+
+ memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
+ (char *) newdecl + sizeof (struct tree_decl_common),
+ tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common));
+ olddecl->decl_with_vis.symtab_node = snode;
+
+ if ((DECL_EXTERNAL (olddecl)
+ || TREE_PUBLIC (olddecl)
+ || TREE_STATIC (olddecl))
+ && DECL_SECTION_NAME (newdecl) != NULL)
+ set_decl_section_name (olddecl, DECL_SECTION_NAME (newdecl));
+
+ /* This isn't quite correct for something like
+ int __thread x attribute ((tls_model ("local-exec")));
+ extern int __thread x;
+ as we'll lose the "local-exec" model. */
+ if (TREE_CODE (olddecl) == VAR_DECL
+ && DECL_THREAD_LOCAL_P (newdecl))
+ set_decl_tls_model (olddecl, DECL_TLS_MODEL (newdecl));
+ break;
+ }
+
+ case FIELD_DECL:
case PARM_DECL:
case LABEL_DECL:
case RESULT_DECL:
@@ -2541,6 +2726,23 @@ duplicate_decls (tree newdecl, tree olddecl)
}
merge_decls (newdecl, olddecl, newtype, oldtype);
+
+ /* The NEWDECL will no longer be needed.
+
+ Before releasing the node, be sure to remove function from symbol
+ table that might have been inserted there to record comdat group.
+ Be sure to however do not free DECL_STRUCT_FUNCTION because this
+ structure is shared in between NEWDECL and OLDECL. */
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ DECL_STRUCT_FUNCTION (newdecl) = NULL;
+ if (TREE_CODE (newdecl) == FUNCTION_DECL
+ || TREE_CODE (newdecl) == VAR_DECL)
+ {
+ struct symtab_node *snode = symtab_node::get (newdecl);
+ if (snode)
+ snode->remove ();
+ }
+ ggc_free (newdecl);
return true;
}
@@ -2567,6 +2769,7 @@ warn_if_shadowing (tree new_decl)
DECL_SOURCE_LOCATION (b->decl))))
{
tree old_decl = b->decl;
+ bool warned = false;
if (old_decl == error_mark_node)
{
@@ -2575,8 +2778,9 @@ warn_if_shadowing (tree new_decl)
break;
}
else if (TREE_CODE (old_decl) == PARM_DECL)
- warning (OPT_Wshadow, "declaration of %q+D shadows a parameter",
- new_decl);
+ warned = warning (OPT_Wshadow,
+ "declaration of %q+D shadows a parameter",
+ new_decl);
else if (DECL_FILE_SCOPE_P (old_decl))
{
/* Do not warn if a variable shadows a function, unless
@@ -2586,9 +2790,10 @@ warn_if_shadowing (tree new_decl)
&& !FUNCTION_POINTER_TYPE_P (TREE_TYPE (new_decl)))
continue;
- warning_at (DECL_SOURCE_LOCATION (new_decl), OPT_Wshadow,
- "declaration of %qD shadows a global declaration",
- new_decl);
+ warned = warning_at (DECL_SOURCE_LOCATION (new_decl), OPT_Wshadow,
+ "declaration of %qD shadows a global "
+ "declaration",
+ new_decl);
}
else if (TREE_CODE (old_decl) == FUNCTION_DECL
&& DECL_BUILT_IN (old_decl))
@@ -2598,11 +2803,12 @@ warn_if_shadowing (tree new_decl)
break;
}
else
- warning (OPT_Wshadow, "declaration of %q+D shadows a previous local",
- new_decl);
+ warned = warning (OPT_Wshadow, "declaration of %q+D shadows a "
+ "previous local", new_decl);
- warning_at (DECL_SOURCE_LOCATION (old_decl), OPT_Wshadow,
- "shadowed declaration is here");
+ if (warned)
+ inform (DECL_SOURCE_LOCATION (old_decl),
+ "shadowed declaration is here");
break;
}
@@ -2897,23 +3103,206 @@ pushdecl_top_level (tree x)
}
static void
-implicit_decl_warning (tree id, tree olddecl)
+implicit_decl_warning (location_t loc, tree id, tree olddecl)
{
if (warn_implicit_function_declaration)
{
bool warned;
if (flag_isoc99)
- warned = pedwarn (input_location, OPT_Wimplicit_function_declaration,
+ warned = pedwarn (loc, OPT_Wimplicit_function_declaration,
"implicit declaration of function %qE", id);
else
- warned = warning (OPT_Wimplicit_function_declaration,
- G_("implicit declaration of function %qE"), id);
+ warned = warning_at (loc, OPT_Wimplicit_function_declaration,
+ G_("implicit declaration of function %qE"), id);
if (olddecl && warned)
locate_old_decl (olddecl);
}
}
+/* This function represents mapping of a function code FCODE
+ to its respective header. */
+
+static const char *
+header_for_builtin_fn (enum built_in_function fcode)
+{
+ switch (fcode)
+ {
+ CASE_FLT_FN (BUILT_IN_ACOS):
+ CASE_FLT_FN (BUILT_IN_ACOSH):
+ CASE_FLT_FN (BUILT_IN_ASIN):
+ CASE_FLT_FN (BUILT_IN_ASINH):
+ CASE_FLT_FN (BUILT_IN_ATAN):
+ CASE_FLT_FN (BUILT_IN_ATANH):
+ CASE_FLT_FN (BUILT_IN_ATAN2):
+ CASE_FLT_FN (BUILT_IN_CBRT):
+ CASE_FLT_FN (BUILT_IN_CEIL):
+ CASE_FLT_FN (BUILT_IN_COPYSIGN):
+ CASE_FLT_FN (BUILT_IN_COS):
+ CASE_FLT_FN (BUILT_IN_COSH):
+ CASE_FLT_FN (BUILT_IN_ERF):
+ CASE_FLT_FN (BUILT_IN_ERFC):
+ CASE_FLT_FN (BUILT_IN_EXP):
+ CASE_FLT_FN (BUILT_IN_EXP2):
+ CASE_FLT_FN (BUILT_IN_EXPM1):
+ CASE_FLT_FN (BUILT_IN_FABS):
+ CASE_FLT_FN (BUILT_IN_FDIM):
+ CASE_FLT_FN (BUILT_IN_FLOOR):
+ CASE_FLT_FN (BUILT_IN_FMA):
+ CASE_FLT_FN (BUILT_IN_FMAX):
+ CASE_FLT_FN (BUILT_IN_FMIN):
+ CASE_FLT_FN (BUILT_IN_FMOD):
+ CASE_FLT_FN (BUILT_IN_FREXP):
+ CASE_FLT_FN (BUILT_IN_HYPOT):
+ CASE_FLT_FN (BUILT_IN_ILOGB):
+ CASE_FLT_FN (BUILT_IN_LDEXP):
+ CASE_FLT_FN (BUILT_IN_LGAMMA):
+ CASE_FLT_FN (BUILT_IN_LLRINT):
+ CASE_FLT_FN (BUILT_IN_LLROUND):
+ CASE_FLT_FN (BUILT_IN_LOG):
+ CASE_FLT_FN (BUILT_IN_LOG10):
+ CASE_FLT_FN (BUILT_IN_LOG1P):
+ CASE_FLT_FN (BUILT_IN_LOG2):
+ CASE_FLT_FN (BUILT_IN_LOGB):
+ CASE_FLT_FN (BUILT_IN_LRINT):
+ CASE_FLT_FN (BUILT_IN_LROUND):
+ CASE_FLT_FN (BUILT_IN_MODF):
+ CASE_FLT_FN (BUILT_IN_NAN):
+ CASE_FLT_FN (BUILT_IN_NEARBYINT):
+ CASE_FLT_FN (BUILT_IN_NEXTAFTER):
+ CASE_FLT_FN (BUILT_IN_NEXTTOWARD):
+ CASE_FLT_FN (BUILT_IN_POW):
+ CASE_FLT_FN (BUILT_IN_REMAINDER):
+ CASE_FLT_FN (BUILT_IN_REMQUO):
+ CASE_FLT_FN (BUILT_IN_RINT):
+ CASE_FLT_FN (BUILT_IN_ROUND):
+ CASE_FLT_FN (BUILT_IN_SCALBLN):
+ CASE_FLT_FN (BUILT_IN_SCALBN):
+ CASE_FLT_FN (BUILT_IN_SIN):
+ CASE_FLT_FN (BUILT_IN_SINH):
+ CASE_FLT_FN (BUILT_IN_SINCOS):
+ CASE_FLT_FN (BUILT_IN_SQRT):
+ CASE_FLT_FN (BUILT_IN_TAN):
+ CASE_FLT_FN (BUILT_IN_TANH):
+ CASE_FLT_FN (BUILT_IN_TGAMMA):
+ CASE_FLT_FN (BUILT_IN_TRUNC):
+ case BUILT_IN_ISINF:
+ case BUILT_IN_ISNAN:
+ return "<math.h>";
+ CASE_FLT_FN (BUILT_IN_CABS):
+ CASE_FLT_FN (BUILT_IN_CACOS):
+ CASE_FLT_FN (BUILT_IN_CACOSH):
+ CASE_FLT_FN (BUILT_IN_CARG):
+ CASE_FLT_FN (BUILT_IN_CASIN):
+ CASE_FLT_FN (BUILT_IN_CASINH):
+ CASE_FLT_FN (BUILT_IN_CATAN):
+ CASE_FLT_FN (BUILT_IN_CATANH):
+ CASE_FLT_FN (BUILT_IN_CCOS):
+ CASE_FLT_FN (BUILT_IN_CCOSH):
+ CASE_FLT_FN (BUILT_IN_CEXP):
+ CASE_FLT_FN (BUILT_IN_CIMAG):
+ CASE_FLT_FN (BUILT_IN_CLOG):
+ CASE_FLT_FN (BUILT_IN_CONJ):
+ CASE_FLT_FN (BUILT_IN_CPOW):
+ CASE_FLT_FN (BUILT_IN_CPROJ):
+ CASE_FLT_FN (BUILT_IN_CREAL):
+ CASE_FLT_FN (BUILT_IN_CSIN):
+ CASE_FLT_FN (BUILT_IN_CSINH):
+ CASE_FLT_FN (BUILT_IN_CSQRT):
+ CASE_FLT_FN (BUILT_IN_CTAN):
+ CASE_FLT_FN (BUILT_IN_CTANH):
+ return "<complex.h>";
+ case BUILT_IN_MEMCHR:
+ case BUILT_IN_MEMCMP:
+ case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMMOVE:
+ case BUILT_IN_MEMSET:
+ case BUILT_IN_STRCAT:
+ case BUILT_IN_STRCHR:
+ case BUILT_IN_STRCMP:
+ case BUILT_IN_STRCPY:
+ case BUILT_IN_STRCSPN:
+ case BUILT_IN_STRLEN:
+ case BUILT_IN_STRNCAT:
+ case BUILT_IN_STRNCMP:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_STRPBRK:
+ case BUILT_IN_STRRCHR:
+ case BUILT_IN_STRSPN:
+ case BUILT_IN_STRSTR:
+ return "<string.h>";
+ case BUILT_IN_FPRINTF:
+ case BUILT_IN_PUTC:
+ case BUILT_IN_FPUTC:
+ case BUILT_IN_FPUTS:
+ case BUILT_IN_FSCANF:
+ case BUILT_IN_FWRITE:
+ case BUILT_IN_PRINTF:
+ case BUILT_IN_PUTCHAR:
+ case BUILT_IN_PUTS:
+ case BUILT_IN_SCANF:
+ case BUILT_IN_SNPRINTF:
+ case BUILT_IN_SPRINTF:
+ case BUILT_IN_SSCANF:
+ case BUILT_IN_VFPRINTF:
+ case BUILT_IN_VFSCANF:
+ case BUILT_IN_VPRINTF:
+ case BUILT_IN_VSCANF:
+ case BUILT_IN_VSNPRINTF:
+ case BUILT_IN_VSPRINTF:
+ case BUILT_IN_VSSCANF:
+ return "<stdio.h>";
+ case BUILT_IN_ISALNUM:
+ case BUILT_IN_ISALPHA:
+ case BUILT_IN_ISBLANK:
+ case BUILT_IN_ISCNTRL:
+ case BUILT_IN_ISDIGIT:
+ case BUILT_IN_ISGRAPH:
+ case BUILT_IN_ISLOWER:
+ case BUILT_IN_ISPRINT:
+ case BUILT_IN_ISPUNCT:
+ case BUILT_IN_ISSPACE:
+ case BUILT_IN_ISUPPER:
+ case BUILT_IN_ISXDIGIT:
+ case BUILT_IN_TOLOWER:
+ case BUILT_IN_TOUPPER:
+ return "<ctype.h>";
+ case BUILT_IN_ISWALNUM:
+ case BUILT_IN_ISWALPHA:
+ case BUILT_IN_ISWBLANK:
+ case BUILT_IN_ISWCNTRL:
+ case BUILT_IN_ISWDIGIT:
+ case BUILT_IN_ISWGRAPH:
+ case BUILT_IN_ISWLOWER:
+ case BUILT_IN_ISWPRINT:
+ case BUILT_IN_ISWPUNCT:
+ case BUILT_IN_ISWSPACE:
+ case BUILT_IN_ISWUPPER:
+ case BUILT_IN_ISWXDIGIT:
+ case BUILT_IN_TOWLOWER:
+ case BUILT_IN_TOWUPPER:
+ return "<wctype.h>";
+ case BUILT_IN_ABORT:
+ case BUILT_IN_ABS:
+ case BUILT_IN_CALLOC:
+ case BUILT_IN_EXIT:
+ case BUILT_IN_FREE:
+ case BUILT_IN_LABS:
+ case BUILT_IN_LLABS:
+ case BUILT_IN_MALLOC:
+ case BUILT_IN_REALLOC:
+ case BUILT_IN__EXIT2:
+ case BUILT_IN_ALIGNED_ALLOC:
+ return "<stdlib.h>";
+ case BUILT_IN_IMAXABS:
+ return "<inttypes.h>";
+ case BUILT_IN_STRFTIME:
+ return "<time.h>";
+ default:
+ return NULL;
+ }
+}
+
/* Generate an implicit declaration for identifier FUNCTIONID at LOC as a
function of type int (). */
@@ -2961,7 +3350,7 @@ implicitly_declare (location_t loc, tree functionid)
then recycle the old declaration but with the new type. */
if (!C_DECL_IMPLICIT (decl))
{
- implicit_decl_warning (functionid, decl);
+ implicit_decl_warning (loc, functionid, decl);
C_DECL_IMPLICIT (decl) = 1;
}
if (DECL_BUILT_IN (decl))
@@ -2971,8 +3360,15 @@ implicitly_declare (location_t loc, tree functionid)
(TREE_TYPE (decl)));
if (!comptypes (newtype, TREE_TYPE (decl)))
{
- warning_at (loc, 0, "incompatible implicit declaration of "
- "built-in function %qD", decl);
+ bool warned = warning_at (loc, 0, "incompatible implicit "
+ "declaration of built-in "
+ "function %qD", decl);
+ /* See if we can hint which header to include. */
+ const char *header
+ = header_for_builtin_fn (DECL_FUNCTION_CODE (decl));
+ if (header != NULL && warned)
+ inform (loc, "include %qs or provide a declaration of %qD",
+ header, decl);
newtype = TREE_TYPE (decl);
}
}
@@ -2980,7 +3376,8 @@ implicitly_declare (location_t loc, tree functionid)
{
if (!comptypes (newtype, TREE_TYPE (decl)))
{
- error_at (loc, "incompatible implicit declaration of function %qD", decl);
+ error_at (loc, "incompatible implicit declaration of "
+ "function %qD", decl);
locate_old_decl (decl);
}
}
@@ -2998,7 +3395,7 @@ implicitly_declare (location_t loc, tree functionid)
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
C_DECL_IMPLICIT (decl) = 1;
- implicit_decl_warning (functionid, 0);
+ implicit_decl_warning (loc, functionid, 0);
asmspec_tree = maybe_apply_renaming_pragma (decl, /*asmname=*/NULL);
if (asmspec_tree)
set_user_assembler_name (decl, TREE_STRING_POINTER (asmspec_tree));
@@ -3064,12 +3461,10 @@ make_label (location_t location, tree name, bool defining,
struct c_label_vars **p_label_vars)
{
tree label = build_decl (location, LABEL_DECL, name, void_type_node);
- struct c_label_vars *label_vars;
-
DECL_CONTEXT (label) = current_function_decl;
DECL_MODE (label) = VOIDmode;
- label_vars = ggc_alloc_c_label_vars ();
+ c_label_vars *label_vars = ggc_alloc<c_label_vars> ();
label_vars->shadowed = NULL;
set_spot_bindings (&label_vars->label_bindings, defining);
label_vars->decls_in_scope = make_tree_vector ();
@@ -3165,9 +3560,8 @@ lookup_label_for_goto (location_t loc, tree name)
list for possible later warnings. */
if (label_vars->label_bindings.scope == NULL)
{
- struct c_goto_bindings *g;
+ c_goto_bindings *g = ggc_alloc<c_goto_bindings> ();
- g = ggc_alloc_c_goto_bindings ();
g->loc = loc;
set_spot_bindings (&g->goto_bindings, true);
vec_safe_push (label_vars->gotos, g);
@@ -3560,8 +3954,6 @@ c_init_decl_processing (void)
input_location = save_loc;
- pedantic_lvalues = true;
-
make_fname_decl = c_make_fname_decl;
start_fname_decls ();
}
@@ -3917,16 +4309,13 @@ build_array_declarator (location_t loc,
}
declarator->u.array.static_p = static_p;
declarator->u.array.vla_unspec_p = vla_unspec_p;
- if (!flag_isoc99)
- {
- if (static_p || quals != NULL)
- pedwarn (loc, OPT_Wpedantic,
+ if (static_p || quals != NULL)
+ pedwarn_c90 (loc, OPT_Wpedantic,
"ISO C90 does not support %<static%> or type "
"qualifiers in parameter array declarators");
- if (vla_unspec_p)
- pedwarn (loc, OPT_Wpedantic,
+ if (vla_unspec_p)
+ pedwarn_c90 (loc, OPT_Wpedantic,
"ISO C90 does not support %<[*]%> array declarators");
- }
if (vla_unspec_p)
{
if (!current_scope->parm_flag)
@@ -4014,7 +4403,8 @@ c_decl_attributes (tree *node, tree attributes, int flags)
{
/* Add implicit "omp declare target" attribute if requested. */
if (current_omp_declare_target_attribute
- && ((TREE_CODE (*node) == VAR_DECL && TREE_STATIC (*node))
+ && ((TREE_CODE (*node) == VAR_DECL
+ && (TREE_STATIC (*node) || DECL_EXTERNAL (*node)))
|| TREE_CODE (*node) == FUNCTION_DECL))
{
if (TREE_CODE (*node) == VAR_DECL
@@ -4067,8 +4457,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
decl = grokdeclarator (declarator, declspecs,
NORMAL, initialized, NULL, &attributes, &expr, NULL,
deprecated_state);
- if (!decl)
- return 0;
+ if (!decl || decl == error_mark_node)
+ return NULL_TREE;
if (expr)
add_stmt (fold_convert (void_type_node, expr));
@@ -4840,10 +5230,9 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
if (!in_system_header_at (input_location)
&& type_mv != integer_type_node
&& type_mv != unsigned_type_node
- && type_mv != boolean_type_node
- && !flag_isoc99)
- pedwarn (input_location, OPT_Wpedantic,
- "type of bit-field %qs is a GCC extension", name);
+ && type_mv != boolean_type_node)
+ pedwarn_c90 (input_location, OPT_Wpedantic,
+ "type of bit-field %qs is a GCC extension", name);
max_width = TYPE_PRECISION (*type);
@@ -4860,8 +5249,8 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
{
struct lang_type *lt = TYPE_LANG_SPECIFIC (*type);
if (!lt
- || w < tree_int_cst_min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
- || w < tree_int_cst_min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
+ || w < tree_int_cst_min_precision (lt->enum_min, TYPE_SIGN (*type))
+ || w < tree_int_cst_min_precision (lt->enum_max, TYPE_SIGN (*type)))
warning (0, "%qs is narrower than values of its type", name);
}
}
@@ -4873,56 +5262,43 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
static void
warn_variable_length_array (tree name, tree size)
{
- int const_size = TREE_CONSTANT (size);
-
- if (!flag_isoc99 && pedantic && warn_vla != 0)
+ if (TREE_CONSTANT (size))
{
- if (const_size)
- {
- if (name)
- pedwarn (input_location, OPT_Wvla,
+ if (name)
+ pedwarn_c90 (input_location, OPT_Wvla,
"ISO C90 forbids array %qE whose size "
- "can%'t be evaluated",
- name);
- else
- pedwarn (input_location, OPT_Wvla, "ISO C90 forbids array whose size "
- "can%'t be evaluated");
- }
+ "can%'t be evaluated", name);
else
- {
- if (name)
- pedwarn (input_location, OPT_Wvla,
- "ISO C90 forbids variable length array %qE",
- name);
- else
- pedwarn (input_location, OPT_Wvla, "ISO C90 forbids variable length array");
- }
+ pedwarn_c90 (input_location, OPT_Wvla, "ISO C90 forbids array "
+ "whose size can%'t be evaluated");
}
- else if (warn_vla > 0)
+ else
{
- if (const_size)
- {
- if (name)
- warning (OPT_Wvla,
- "the size of array %qE can"
- "%'t be evaluated", name);
- else
- warning (OPT_Wvla,
- "the size of array can %'t be evaluated");
- }
+ if (name)
+ pedwarn_c90 (input_location, OPT_Wvla,
+ "ISO C90 forbids variable length array %qE", name);
else
- {
- if (name)
- warning (OPT_Wvla,
- "variable length array %qE is used",
- name);
- else
- warning (OPT_Wvla,
- "variable length array is used");
- }
+ pedwarn_c90 (input_location, OPT_Wvla, "ISO C90 forbids variable "
+ "length array");
}
}
+/* Print warning about defaulting to int if necessary. */
+
+static void
+warn_defaults_to (location_t location, int opt, const char *gmsgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, gmsgid);
+ diagnostic_set_info (&diagnostic, gmsgid, &ap, location,
+ flag_isoc99 ? DK_PEDWARN : DK_WARNING);
+ diagnostic.option_index = opt;
+ report_diagnostic (&diagnostic);
+ va_end (ap);
+}
+
/* Given declspecs and a declarator,
determine the name and type of the object declared
and construct a ..._DECL node for it.
@@ -5099,12 +5475,12 @@ grokdeclarator (const struct c_declarator *declarator,
else
{
if (name)
- pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wimplicit_int,
- "type defaults to %<int%> in declaration of %qE",
- name);
+ warn_defaults_to (loc, OPT_Wimplicit_int,
+ "type defaults to %<int%> in declaration "
+ "of %qE", name);
else
- pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int,
- "type defaults to %<int%> in type name");
+ warn_defaults_to (loc, OPT_Wimplicit_int,
+ "type defaults to %<int%> in type name");
}
}
@@ -5135,18 +5511,14 @@ grokdeclarator (const struct c_declarator *declarator,
as2 = TYPE_ADDR_SPACE (element_type);
address_space = ADDR_SPACE_GENERIC_P (as1)? as2 : as1;
- if (pedantic && !flag_isoc99)
- {
- if (constp > 1)
- pedwarn (loc, OPT_Wpedantic, "duplicate %<const%>");
- if (restrictp > 1)
- pedwarn (loc, OPT_Wpedantic, "duplicate %<restrict%>");
- if (volatilep > 1)
- pedwarn (loc, OPT_Wpedantic, "duplicate %<volatile%>");
- if (atomicp > 1)
- pedwarn (loc, OPT_Wpedantic, "duplicate %<_Atomic%>");
-
- }
+ if (constp > 1)
+ pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<const%>");
+ if (restrictp > 1)
+ pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<restrict%>");
+ if (volatilep > 1)
+ pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<volatile%>");
+ if (atomicp > 1)
+ pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<_Atomic%>");
if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2)
error_at (loc, "conflicting named address spaces (%s vs %s)",
@@ -5461,7 +5833,8 @@ grokdeclarator (const struct c_declarator *declarator,
this_size_varies = size_varies = true;
warn_variable_length_array (name, size);
if (flag_sanitize & SANITIZE_VLA
- && decl_context == NORMAL)
+ && decl_context == NORMAL
+ && do_ubsan_in_current_function ())
{
/* Evaluate the array size only once. */
size = c_save_expr (size);
@@ -5547,10 +5920,9 @@ grokdeclarator (const struct c_declarator *declarator,
flexible_array_member = (t->kind == cdk_id);
}
if (flexible_array_member
- && pedantic && !flag_isoc99
&& !in_system_header_at (input_location))
- pedwarn (loc, OPT_Wpedantic,
- "ISO C90 does not support flexible array members");
+ pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not "
+ "support flexible array members");
/* ISO C99 Flexible array members are effectively
identical to GCC's zero-length array extension. */
@@ -5584,7 +5956,8 @@ grokdeclarator (const struct c_declarator *declarator,
/* Complain about arrays of incomplete types. */
if (!COMPLETE_TYPE_P (type))
{
- error_at (loc, "array type has incomplete element type");
+ error_at (loc, "array type has incomplete element type %qT",
+ type);
type = error_mark_node;
}
else
@@ -6048,6 +6421,7 @@ grokdeclarator (const struct c_declarator *declarator,
if (decl_context == PARM)
{
tree promoted_type;
+ bool array_parameter_p = false;
/* A parameter declared as an array of T is really a pointer to T.
One declared as a function is really a pointer to a function. */
@@ -6069,6 +6443,7 @@ grokdeclarator (const struct c_declarator *declarator,
"attributes in parameter array declarator ignored");
size_varies = false;
+ array_parameter_p = true;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
@@ -6093,6 +6468,7 @@ grokdeclarator (const struct c_declarator *declarator,
PARM_DECL, declarator->u.id, type);
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
+ C_ARRAY_PARAMETER (decl) = array_parameter_p;
/* Compute the type actually passed in the parmlist,
for the case where there is no prototype.
@@ -6133,6 +6509,19 @@ grokdeclarator (const struct c_declarator *declarator,
error_at (loc, "unnamed field has incomplete type");
type = error_mark_node;
}
+ else if (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_DOMAIN (type) == NULL_TREE)
+ {
+ /* We have a flexible array member through a typedef.
+ Set suitable range. Whether this is a correct position
+ for a flexible array member will be determined elsewhere. */
+ if (!in_system_header_at (input_location))
+ pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not "
+ "support flexible array members");
+ type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
+ TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node,
+ NULL_TREE);
+ }
type = c_build_qualified_type (type, type_quals);
decl = build_decl (declarator->id_loc,
FIELD_DECL, declarator->u.id, type);
@@ -6229,15 +6618,12 @@ grokdeclarator (const struct c_declarator *declarator,
DECL_DECLARED_INLINE_P (decl) = 1;
if (declspecs->noreturn_p)
{
- if (!flag_isoc11)
- {
- if (flag_isoc99)
- pedwarn (loc, OPT_Wpedantic,
+ if (flag_isoc99)
+ pedwarn_c99 (loc, OPT_Wpedantic,
"ISO C99 does not support %<_Noreturn%>");
- else
- pedwarn (loc, OPT_Wpedantic,
+ else
+ pedwarn_c99 (loc, OPT_Wpedantic,
"ISO C90 does not support %<_Noreturn%>");
- }
TREE_THIS_VOLATILE (decl) = 1;
}
}
@@ -6301,7 +6687,7 @@ grokdeclarator (const struct c_declarator *declarator,
}
if (threadp)
- DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+ set_decl_tls_model (decl, decl_default_tls_model (decl));
}
if ((storage_class == csc_extern
@@ -6944,15 +7330,12 @@ grokfield (location_t loc,
pedwarn (loc, 0, "declaration does not declare anything");
return NULL_TREE;
}
- if (!flag_isoc11)
- {
- if (flag_isoc99)
- pedwarn (loc, OPT_Wpedantic,
+ if (flag_isoc99)
+ pedwarn_c99 (loc, OPT_Wpedantic,
"ISO C99 doesn%'t support unnamed structs/unions");
- else
- pedwarn (loc, OPT_Wpedantic,
+ else
+ pedwarn_c99 (loc, OPT_Wpedantic,
"ISO C90 doesn%'t support unnamed structs/unions");
- }
}
value = grokdeclarator (declarator, declspecs, FIELD, false,
@@ -7032,7 +7415,7 @@ is_duplicate_field (tree x, tree y)
static void
detect_field_duplicates_hash (tree fieldlist,
- hash_table <pointer_hash <tree_node> > htab)
+ hash_table<pointer_hash <tree_node> > *htab)
{
tree x, y;
tree_node **slot;
@@ -7040,7 +7423,7 @@ detect_field_duplicates_hash (tree fieldlist,
for (x = fieldlist; x ; x = DECL_CHAIN (x))
if ((y = DECL_NAME (x)) != 0)
{
- slot = htab.find_slot (y, INSERT);
+ slot = htab->find_slot (y, INSERT);
if (*slot)
{
error ("duplicate member %q+D", x);
@@ -7060,7 +7443,7 @@ detect_field_duplicates_hash (tree fieldlist,
&& TREE_CODE (TYPE_NAME (TREE_TYPE (x))) == TYPE_DECL)
{
tree xn = DECL_NAME (TYPE_NAME (TREE_TYPE (x)));
- slot = htab.find_slot (xn, INSERT);
+ slot = htab->find_slot (xn, INSERT);
if (*slot)
error ("duplicate member %q+D", TYPE_NAME (TREE_TYPE (x)));
*slot = xn;
@@ -7132,11 +7515,8 @@ detect_field_duplicates (tree fieldlist)
}
else
{
- hash_table <pointer_hash <tree_node> > htab;
- htab.create (37);
-
- detect_field_duplicates_hash (fieldlist, htab);
- htab.dispose ();
+ hash_table<pointer_hash <tree_node> > htab (37);
+ detect_field_duplicates_hash (fieldlist, &htab);
}
}
@@ -7166,17 +7546,17 @@ warn_cxx_compat_finish_struct (tree fieldlist)
if (!struct_parse_info->typedefs_seen.is_empty ()
&& fieldlist != NULL_TREE)
{
- /* Use a pointer_set using the name of the typedef. We can use
- a pointer_set because identifiers are interned. */
- struct pointer_set_t *tset = pointer_set_create ();
+ /* Use a hash_set<tree> using the name of the typedef. We can use
+ a hash_set<tree> because identifiers are interned. */
+ hash_set<tree> tset;
FOR_EACH_VEC_ELT (struct_parse_info->typedefs_seen, ix, x)
- pointer_set_insert (tset, DECL_NAME (x));
+ tset.add (DECL_NAME (x));
for (x = fieldlist; x != NULL_TREE; x = DECL_CHAIN (x))
{
if (DECL_NAME (x) != NULL_TREE
- && pointer_set_contains (tset, DECL_NAME (x)))
+ && tset.contains (DECL_NAME (x)))
{
warning_at (DECL_SOURCE_LOCATION (x), OPT_Wc___compat,
("using %qD as both field and typedef name is "
@@ -7186,8 +7566,6 @@ warn_cxx_compat_finish_struct (tree fieldlist)
the typedef name is used. */
}
}
-
- pointer_set_destroy (tset);
}
/* For each field which has a binding and which was not defined in
@@ -7403,8 +7781,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
ensure that this lives as long as the rest of the struct decl.
All decls in an inline function need to be saved. */
- space = ggc_alloc_cleared_lang_type (sizeof (struct lang_type));
- space2 = ggc_alloc_sorted_fields_type
+ space = ggc_cleared_alloc<struct lang_type> ();
+ space2 = (sorted_fields_type *) ggc_internal_alloc
(sizeof (struct sorted_fields_type) + len * sizeof (tree));
len = 0;
@@ -7585,7 +7963,8 @@ finish_enum (tree enumtype, tree values, tree attributes)
{
tree pair, tem;
tree minnode = 0, maxnode = 0;
- int precision, unsign;
+ int precision;
+ signop sign;
bool toplevel = (file_scope == current_scope);
struct lang_type *lt;
@@ -7612,13 +7991,13 @@ finish_enum (tree enumtype, tree values, tree attributes)
as one of the integral types - the narrowest one that fits, except
that normally we only go as narrow as int - and signed iff any of
the values are negative. */
- unsign = (tree_int_cst_sgn (minnode) >= 0);
- precision = MAX (tree_int_cst_min_precision (minnode, unsign),
- tree_int_cst_min_precision (maxnode, unsign));
+ sign = (tree_int_cst_sgn (minnode) >= 0) ? UNSIGNED : SIGNED;
+ precision = MAX (tree_int_cst_min_precision (minnode, sign),
+ tree_int_cst_min_precision (maxnode, sign));
if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
{
- tem = c_common_type_for_size (precision, unsign);
+ tem = c_common_type_for_size (precision, sign == UNSIGNED ? 1 : 0);
if (tem == NULL)
{
warning (0, "enumeration values exceed range of largest integer");
@@ -7626,7 +8005,7 @@ finish_enum (tree enumtype, tree values, tree attributes)
}
}
else
- tem = unsign ? unsigned_type_node : integer_type_node;
+ tem = sign == UNSIGNED ? unsigned_type_node : integer_type_node;
TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (tem);
TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
@@ -7684,7 +8063,7 @@ finish_enum (tree enumtype, tree values, tree attributes)
/* Record the min/max values so that we can warn about bit-field
enumerations that are too small for the values. */
- lt = ggc_alloc_cleared_lang_type (sizeof (struct lang_type));
+ lt = ggc_cleared_alloc<struct lang_type> ();
lt->enum_min = minnode;
lt->enum_max = maxnode;
TYPE_LANG_SPECIFIC (enumtype) = lt;
@@ -7897,9 +8276,10 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
}
if (warn_about_return_type)
- pedwarn_c99 (loc, flag_isoc99 ? 0
- : (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int),
- "return type defaults to %<int%>");
+ warn_defaults_to (loc, flag_isoc99 ? OPT_Wimplicit_int
+ : (warn_return_type ? OPT_Wreturn_type
+ : OPT_Wimplicit_int),
+ "return type defaults to %<int%>");
/* Make the init_value nonzero so pushdecl knows this is not tentative.
error_mark_node is replaced below (in pop_scope) with the BLOCK. */
@@ -7992,7 +8372,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
else if (warn_missing_declarations
&& TREE_PUBLIC (decl1)
&& old_decl == 0
- && !MAIN_NAME_P (DECL_NAME (decl1)))
+ && !MAIN_NAME_P (DECL_NAME (decl1))
+ && !DECL_DECLARED_INLINE_P (decl1))
warning_at (loc, OPT_Wmissing_declarations,
"no previous declaration for %qD",
decl1);
@@ -8024,6 +8405,9 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
!= integer_type_node)
pedwarn (loc, OPT_Wmain, "return type of %qD is not %<int%>", decl1);
+ else if (TYPE_ATOMIC (TREE_TYPE (TREE_TYPE (decl1))))
+ pedwarn (loc, OPT_Wmain, "%<_Atomic%>-qualified return type of %qD",
+ decl1);
check_main_parameter_types (decl1);
@@ -8130,7 +8514,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
struct c_binding *b;
tree parm, decl, last;
tree parmids = arg_info->parms;
- struct pointer_set_t *seen_args = pointer_set_create ();
+ hash_set<tree> seen_args;
if (!in_system_header_at (input_location))
warning_at (DECL_SOURCE_LOCATION (fndecl),
@@ -8161,7 +8545,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
"%qD declared as a non-parameter", decl);
/* If the declaration is already marked, we have a duplicate
name. Complain and ignore the duplicate. */
- else if (pointer_set_contains (seen_args, decl))
+ else if (seen_args.contains (decl))
{
error_at (DECL_SOURCE_LOCATION (decl),
"multiple parameters named %qD", decl);
@@ -8202,7 +8586,8 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
if (flag_isoc99)
pedwarn (DECL_SOURCE_LOCATION (decl),
- 0, "type of %qD defaults to %<int%>", decl);
+ OPT_Wimplicit_int, "type of %qD defaults to %<int%>",
+ decl);
else
warning_at (DECL_SOURCE_LOCATION (decl),
OPT_Wmissing_parameter_type,
@@ -8210,7 +8595,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
}
TREE_PURPOSE (parm) = decl;
- pointer_set_insert (seen_args, decl);
+ seen_args.add (decl);
}
/* Now examine the parms chain for incomplete declarations
@@ -8230,7 +8615,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
TREE_TYPE (parm) = error_mark_node;
}
- if (!pointer_set_contains (seen_args, parm))
+ if (!seen_args.contains (parm))
{
error_at (DECL_SOURCE_LOCATION (parm),
"declaration for parameter %qD but no such parameter",
@@ -8265,8 +8650,6 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
DECL_CHAIN (last) = 0;
}
- pointer_set_destroy (seen_args);
-
/* If there was a previous prototype,
set the DECL_ARG_TYPE of each argument according to
the type previously specified, and report any mismatches. */
@@ -8455,7 +8838,7 @@ store_parm_decls (void)
allocate_struct_function (fndecl, false);
if (warn_unused_local_typedefs)
- cfun->language = ggc_alloc_cleared_language_function ();
+ cfun->language = ggc_cleared_alloc<language_function> ();
/* Begin the statement tree for this function. */
DECL_SAVED_TREE (fndecl) = push_stmt_list ();
@@ -8638,19 +9021,19 @@ finish_function (void)
/* ??? Objc emits functions after finalizing the compilation unit.
This should be cleaned up later and this conditional removed. */
- if (cgraph_global_info_ready)
+ if (symtab->global_info_ready)
{
- cgraph_add_new_function (fndecl, false);
+ cgraph_node::add_new_function (fndecl, false);
return;
}
- cgraph_finalize_function (fndecl, false);
+ cgraph_node::finalize_function (fndecl, false);
}
else
{
/* Register this function with cgraph just far enough to get it
added to our parent's nested function list. Handy, since the
C front end doesn't have such a list. */
- (void) cgraph_get_create_node (fndecl);
+ (void) cgraph_node::get_create (fndecl);
}
}
@@ -8779,7 +9162,7 @@ c_push_function_context (void)
/* cfun->language might have been already allocated by the use of
-Wunused-local-typedefs. In that case, just re-use it. */
if (p == NULL)
- cfun->language = p = ggc_alloc_cleared_language_function ();
+ cfun->language = p = ggc_cleared_alloc<language_function> ();
p->base.x_stmt_tree = c_stmt_tree;
c_stmt_tree.x_cur_stmt_list = vec_safe_copy (c_stmt_tree.x_cur_stmt_list);
@@ -9081,8 +9464,8 @@ declspecs_add_qual (source_location loc,
default:
gcc_unreachable ();
}
- if (dupe && !flag_isoc99)
- pedwarn (loc, OPT_Wpedantic, "duplicate %qE", qual);
+ if (dupe)
+ pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %qE", qual);
return specs;
}
@@ -9150,10 +9533,11 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<long%> and %<void%> in "
"declaration specifiers"));
- else if (specs->typespec_word == cts_int128)
+ else if (specs->typespec_word == cts_int_n)
error_at (loc,
- ("both %<long%> and %<__int128%> in "
- "declaration specifiers"));
+ ("both %<long%> and %<__int%d%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
else if (specs->typespec_word == cts_bool)
error_at (loc,
("both %<long%> and %<_Bool%> in "
@@ -9198,10 +9582,11 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<short%> and %<void%> in "
"declaration specifiers"));
- else if (specs->typespec_word == cts_int128)
+ else if (specs->typespec_word == cts_int_n)
error_at (loc,
- ("both %<short%> and %<__int128%> in "
- "declaration specifiers"));
+ ("both %<short%> and %<__int%d%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
else if (specs->typespec_word == cts_bool)
error_at (loc,
("both %<short%> and %<_Bool%> in "
@@ -9326,9 +9711,9 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
break;
case RID_COMPLEX:
dupe = specs->complex_p;
- if (!flag_isoc99 && !in_system_header_at (loc))
- pedwarn (loc, OPT_Wpedantic,
- "ISO C90 does not support complex types");
+ if (!in_system_header_at (loc))
+ pedwarn_c90 (loc, OPT_Wpedantic,
+ "ISO C90 does not support complex types");
if (specs->typespec_word == cts_auto_type)
error_at (loc,
("both %<complex%> and %<__auto_type%> in "
@@ -9375,11 +9760,12 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
dupe = specs->saturating_p;
pedwarn (loc, OPT_Wpedantic,
"ISO C does not support saturating types");
- if (specs->typespec_word == cts_int128)
+ if (specs->typespec_word == cts_int_n)
{
error_at (loc,
- ("both %<_Sat%> and %<__int128%> in "
- "declaration specifiers"));
+ ("both %<_Sat%> and %<__int%d%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
}
else if (specs->typespec_word == cts_auto_type)
error_at (loc,
@@ -9443,7 +9829,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
else
{
/* "void", "_Bool", "char", "int", "float", "double", "_Decimal32",
- "__int128", "_Decimal64", "_Decimal128", "_Fract", "_Accum" or
+ "__intN", "_Decimal64", "_Decimal128", "_Fract", "_Accum" or
"__auto_type". */
if (specs->typespec_word != cts_none)
{
@@ -9484,31 +9870,38 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
specs->locations[cdw_typespec] = loc;
}
return specs;
- case RID_INT128:
- if (int128_integer_type_node == NULL_TREE)
- {
- error_at (loc, "%<__int128%> is not supported for this target");
- return specs;
- }
+ case RID_INT_N_0:
+ case RID_INT_N_1:
+ case RID_INT_N_2:
+ case RID_INT_N_3:
+ specs->int_n_idx = i - RID_INT_N_0;
if (!in_system_header_at (input_location))
pedwarn (loc, OPT_Wpedantic,
- "ISO C does not support %<__int128%> type");
+ "ISO C does not support %<__int%d%> types",
+ int_n_data[specs->int_n_idx].bitsize);
if (specs->long_p)
error_at (loc,
- ("both %<__int128%> and %<long%> in "
- "declaration specifiers"));
+ ("both %<__int%d%> and %<long%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
else if (specs->saturating_p)
error_at (loc,
- ("both %<_Sat%> and %<__int128%> in "
- "declaration specifiers"));
+ ("both %<_Sat%> and %<__int%d%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
else if (specs->short_p)
error_at (loc,
- ("both %<__int128%> and %<short%> in "
- "declaration specifiers"));
+ ("both %<__int%d%> and %<short%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
+ else if (! int_n_enabled_p [specs->int_n_idx])
+ error_at (loc,
+ "%<__int%d%> is not supported on this target",
+ int_n_data[specs->int_n_idx].bitsize);
else
{
- specs->typespec_word = cts_int128;
+ specs->typespec_word = cts_int_n;
specs->locations[cdw_typespec] = loc;
}
return specs;
@@ -9544,6 +9937,9 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
}
return specs;
case RID_BOOL:
+ if (!in_system_header_at (loc))
+ pedwarn_c90 (loc, OPT_Wpedantic,
+ "ISO C90 does not support boolean types");
if (specs->long_p)
error_at (loc,
("both %<long%> and %<_Bool%> in "
@@ -9873,14 +10269,14 @@ declspecs_add_scspec (source_location loc,
identifier in the implementation namespace; only diagnose
it for the C11 spelling because of existing code using
the other spelling. */
- if (!flag_isoc11 && !specs->thread_gnu_p)
+ if (!specs->thread_gnu_p)
{
if (flag_isoc99)
- pedwarn (loc, OPT_Wpedantic,
- "ISO C99 does not support %qE", scspec);
+ pedwarn_c99 (loc, OPT_Wpedantic,
+ "ISO C99 does not support %qE", scspec);
else
- pedwarn (loc, OPT_Wpedantic,
- "ISO C90 does not support %qE", scspec);
+ pedwarn_c99 (loc, OPT_Wpedantic,
+ "ISO C90 does not support %qE", scspec);
}
specs->locations[cdw_thread] = loc;
}
@@ -10073,12 +10469,12 @@ finish_declspecs (struct c_declspecs *specs)
specs->type = build_complex_type (specs->type);
}
break;
- case cts_int128:
+ case cts_int_n:
gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p);
gcc_assert (!(specs->signed_p && specs->unsigned_p));
specs->type = (specs->unsigned_p
- ? int128_unsigned_type_node
- : int128_integer_type_node);
+ ? int_n_trees[specs->int_n_idx].unsigned_type
+ : int_n_trees[specs->int_n_idx].signed_type);
if (specs->complex_p)
{
pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
@@ -10398,7 +10794,7 @@ c_write_global_declarations (void)
/* We're done parsing; proceed to optimize and emit assembly.
FIXME: shouldn't be the front end's responsibility to call this. */
- finalize_compilation_unit ();
+ symtab->finalize_compilation_unit ();
timevar_stop (TV_PHASE_OPT_GEN);
timevar_start (TV_PHASE_DBGINFO);