#include "obstack.h"
#include "cpplib.h"
#include "target.h"
+#include "common/common-target.h"
#include "langhooks.h"
#include "tree-inline.h"
#include "toplev.h"
enum cxx_dialect cxx_dialect = cxx98;
/* Maximum template instantiation depth. This limit exists to limit the
- time it takes to notice excessively recursive template instantiations;
- the default value of 1024 is likely to be in the next C++ standard. */
+ time it takes to notice excessively recursive template instantiations.
-int max_tinst_depth = 1024;
+ The default is lower than the 1024 recommended by the C++0x standard
+ because G++ runs out of stack before 1024 with highly recursive template
+ argument deduction substitution (g++.dg/cpp0x/enum11.C). */
+
+int max_tinst_depth = 900;
/* The elements of `ridpointers' are identifier nodes for the reserved
type names and storage classes. It is indexed by a RID_... value. */
{ "__has_trivial_copy", RID_HAS_TRIVIAL_COPY, D_CXXONLY },
{ "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, D_CXXONLY },
{ "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, D_CXXONLY },
+ { "__imag", RID_IMAGPART, 0 },
+ { "__imag__", RID_IMAGPART, 0 },
+ { "__inline", RID_INLINE, 0 },
+ { "__inline__", RID_INLINE, 0 },
{ "__int128", RID_INT128, 0 },
{ "__is_abstract", RID_IS_ABSTRACT, D_CXXONLY },
{ "__is_base_of", RID_IS_BASE_OF, D_CXXONLY },
{ "__is_convertible_to", RID_IS_CONVERTIBLE_TO, D_CXXONLY },
{ "__is_empty", RID_IS_EMPTY, D_CXXONLY },
{ "__is_enum", RID_IS_ENUM, D_CXXONLY },
+ { "__is_literal_type", RID_IS_LITERAL_TYPE, D_CXXONLY },
{ "__is_pod", RID_IS_POD, D_CXXONLY },
{ "__is_polymorphic", RID_IS_POLYMORPHIC, D_CXXONLY },
{ "__is_standard_layout", RID_IS_STD_LAYOUT, D_CXXONLY },
{ "__is_trivial", RID_IS_TRIVIAL, D_CXXONLY },
{ "__is_union", RID_IS_UNION, D_CXXONLY },
- { "__is_literal_type", RID_IS_LITERAL_TYPE, D_CXXONLY },
- { "__imag", RID_IMAGPART, 0 },
- { "__imag__", RID_IMAGPART, 0 },
- { "__inline", RID_INLINE, 0 },
- { "__inline__", RID_INLINE, 0 },
{ "__label__", RID_LABEL, 0 },
{ "__null", RID_NULL, 0 },
{ "__real", RID_REALPART, 0 },
{ "__thread", RID_THREAD, 0 },
{ "__typeof", RID_TYPEOF, 0 },
{ "__typeof__", RID_TYPEOF, 0 },
+ { "__underlying_type", RID_UNDERLYING_TYPE, D_CXXONLY },
{ "__volatile", RID_VOLATILE, 0 },
{ "__volatile__", RID_VOLATILE, 0 },
{ "alignof", RID_ALIGNOF, D_CXXONLY | D_CXX0X | D_CXXWARN },
if (decl)
{
- saved = tree_cons (decl, build_int_cst (NULL_TREE, ix), saved);
+ saved = tree_cons (decl, build_int_cst (integer_type_node, ix),
+ saved);
*fname_vars[ix].decl = NULL_TREE;
}
}
construct the matching unqualified array type first. The C front
end does not require this, but it does no harm, so we do it
unconditionally. */
- i_type = build_index_type (build_int_cst (NULL_TREE, nchars - 1));
+ i_type = build_index_type (size_int (nchars - 1));
a_type = build_array_type (e_type, i_type);
if (c_dialect_cxx() || warn_write_strings)
a_type = c_build_qualified_type (a_type, TYPE_QUAL_CONST);
return value;
}
\f
+/* If DISABLE is true, stop issuing warnings. This is used when
+ parsing code that we know will not be executed. This function may
+ be called multiple times, and works as a stack. */
+
+static void
+c_disable_warnings (bool disable)
+{
+ if (disable)
+ {
+ ++c_inhibit_evaluation_warnings;
+ fold_defer_overflow_warnings ();
+ }
+}
+
+/* If ENABLE is true, reenable issuing warnings. */
+
+static void
+c_enable_warnings (bool enable)
+{
+ if (enable)
+ {
+ --c_inhibit_evaluation_warnings;
+ fold_undefer_and_ignore_overflow_warnings ();
+ }
+}
+
/* Fully fold EXPR, an expression that was not folded (beyond integer
constant expressions and null pointer constants) when being built
up. If IN_INIT, this is in a static initializer and certain
bool op0_const = true, op1_const = true, op2_const = true;
bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
bool nowarning = TREE_NO_WARNING (expr);
- int unused_p;
+ bool unused_p;
/* This function is not relevant to C++ because C++ folds while
parsing, and may need changes to be correct for C++ when C++
unused_p = (op0 == (code == TRUTH_ANDIF_EXPR
? truthvalue_false_node
: truthvalue_true_node));
- c_inhibit_evaluation_warnings += unused_p;
+ c_disable_warnings (unused_p);
op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self);
STRIP_TYPE_NOPS (op1);
- c_inhibit_evaluation_warnings -= unused_p;
+ c_enable_warnings (unused_p);
if (op0 != orig_op0 || op1 != orig_op1 || in_init)
ret = in_init
op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self);
STRIP_TYPE_NOPS (op0);
- c_inhibit_evaluation_warnings += (op0 == truthvalue_false_node);
+ c_disable_warnings (op0 == truthvalue_false_node);
op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self);
STRIP_TYPE_NOPS (op1);
- c_inhibit_evaluation_warnings -= (op0 == truthvalue_false_node);
+ c_enable_warnings (op0 == truthvalue_false_node);
- c_inhibit_evaluation_warnings += (op0 == truthvalue_true_node);
+ c_disable_warnings (op0 == truthvalue_true_node);
op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self);
STRIP_TYPE_NOPS (op2);
- c_inhibit_evaluation_warnings -= (op0 == truthvalue_true_node);
+ c_enable_warnings (op0 == truthvalue_true_node);
if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
void
check_main_parameter_types (tree decl)
{
- tree args;
+ function_args_iterator iter;
+ tree type;
int argct = 0;
- for (args = TYPE_ARG_TYPES (TREE_TYPE (decl)); args;
- args = TREE_CHAIN (args))
- {
- tree type = args ? TREE_VALUE (args) : 0;
-
- if (type == void_type_node || type == error_mark_node )
- break;
-
- ++argct;
- switch (argct)
- {
- case 1:
- if (TYPE_MAIN_VARIANT (type) != integer_type_node)
- pedwarn (input_location, OPT_Wmain, "first argument of %q+D should be %<int%>",
- decl);
- break;
-
- case 2:
- if (TREE_CODE (type) != POINTER_TYPE
- || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
- != char_type_node))
- pedwarn (input_location, OPT_Wmain, "second argument of %q+D should be %<char **%>",
- decl);
- break;
-
- case 3:
- if (TREE_CODE (type) != POINTER_TYPE
- || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
- != char_type_node))
- pedwarn (input_location, OPT_Wmain, "third argument of %q+D should probably be "
- "%<char **%>", decl);
- break;
- }
- }
+ FOREACH_FUNCTION_ARGS (TREE_TYPE (decl), type, iter)
+ {
+ /* XXX void_type_node belies the abstraction. */
+ if (type == void_type_node || type == error_mark_node )
+ break;
+
+ ++argct;
+ switch (argct)
+ {
+ case 1:
+ if (TYPE_MAIN_VARIANT (type) != integer_type_node)
+ pedwarn (input_location, OPT_Wmain,
+ "first argument of %q+D should be %<int%>", decl);
+ break;
+
+ case 2:
+ if (TREE_CODE (type) != POINTER_TYPE
+ || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
+ || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
+ != char_type_node))
+ pedwarn (input_location, OPT_Wmain,
+ "second argument of %q+D should be %<char **%>", decl);
+ break;
+
+ case 3:
+ if (TREE_CODE (type) != POINTER_TYPE
+ || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
+ || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
+ != char_type_node))
+ pedwarn (input_location, OPT_Wmain,
+ "third argument of %q+D should probably be "
+ "%<char **%>", decl);
+ break;
+ }
+ }
/* It is intentional that this message does not mention the third
argument because it's only mentioned in an appendix of the
standard. */
if (argct > 0 && (argct < 2 || argct > 3))
- pedwarn (input_location, OPT_Wmain, "%q+D takes only zero or two arguments", decl);
+ pedwarn (input_location, OPT_Wmain,
+ "%q+D takes only zero or two arguments", decl);
}
/* True if pointers to distinct types T1 and T2 can be converted to
return false;
}
+/* Like tree.c:get_narrower, but retain conversion from C++0x scoped enum
+ to integral type. */
+
+static tree
+c_common_get_narrower (tree op, int *unsignedp_ptr)
+{
+ op = get_narrower (op, unsignedp_ptr);
+
+ if (TREE_CODE (TREE_TYPE (op)) == ENUMERAL_TYPE
+ && ENUM_IS_SCOPED (TREE_TYPE (op)))
+ {
+ /* C++0x scoped enumerations don't implicitly convert to integral
+ type; if we stripped an explicit conversion to a larger type we
+ need to replace it so common_type will still work. */
+ tree type = (lang_hooks.types.type_for_size
+ (TYPE_PRECISION (TREE_TYPE (op)),
+ TYPE_UNSIGNED (TREE_TYPE (op))));
+ op = fold_convert (type, op);
+ }
+ return op;
+}
+
/* This is a helper function of build_binary_op.
For certain operations if both args were extended from the same
Eg, (short)-1 | (unsigned short)-1 is (int)-1
but calculated in (unsigned short) it would be (unsigned short)-1.
*/
-tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
+tree
+shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
{
int unsigned0, unsigned1;
tree arg0, arg1;
op0 = convert (result_type, op0);
op1 = convert (result_type, op1);
- arg0 = get_narrower (op0, &unsigned0);
- arg1 = get_narrower (op1, &unsigned1);
+ arg0 = c_common_get_narrower (op0, &unsigned0);
+ arg1 = c_common_get_narrower (op1, &unsigned1);
/* UNS is 1 if the operation to be done is an unsigned one. */
uns = TYPE_UNSIGNED (result_type);
if (DECL_P (x) && DECL_ARTIFICIAL (x))
return 0;
+ if (TREE_CODE (x) == BLOCK)
+ return 0;
+
/* VOID_TYPE_P (TREE_TYPE (x)) is workaround for cp/tree.c
(lvalue_p) crash on TRY/CATCH. */
if (TREE_TYPE (x) == NULL_TREE || VOID_TYPE_P (TREE_TYPE (x)))
/* Throw away any conversions to wider types
already present in the operands. */
- primop0 = get_narrower (op0, &unsignedp0);
- primop1 = get_narrower (op1, &unsignedp1);
+ primop0 = c_common_get_narrower (op0, &unsignedp0);
+ primop1 = c_common_get_narrower (op1, &unsignedp1);
/* If primopN is first sign-extended from primopN's precision to opN's
precision, then zero-extended from opN's precision to
if (resultcode == MINUS_EXPR)
intop = fold_build1_loc (loc, NEGATE_EXPR, sizetype, intop);
- ret = fold_build2_loc (loc, POINTER_PLUS_EXPR, result_type, ptrop, intop);
+ ret = fold_build_pointer_plus_loc (loc, ptrop, intop);
fold_undefer_and_ignore_overflow_warnings ();
/* Distribute the conversion into the arms of a COND_EXPR. */
if (c_dialect_cxx ())
{
+ tree op1 = TREE_OPERAND (expr, 1);
+ tree op2 = TREE_OPERAND (expr, 2);
+ /* In C++ one of the arms might have void type if it is throw. */
+ if (!VOID_TYPE_P (TREE_TYPE (op1)))
+ op1 = c_common_truthvalue_conversion (location, op1);
+ if (!VOID_TYPE_P (TREE_TYPE (op2)))
+ op2 = c_common_truthvalue_conversion (location, op2);
expr = fold_build3_loc (location, COND_EXPR, truthvalue_type_node,
- TREE_OPERAND (expr, 0),
- c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr,
- 1)),
- c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr,
- 2)));
+ TREE_OPERAND (expr, 0), op1, op2);
goto ret;
}
else
}
CASE_CONVERT:
- /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
- since that affects how `default_conversion' will behave. */
- if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
- || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
- break;
- /* If this is widening the argument, we can ignore it. */
- if (TYPE_PRECISION (TREE_TYPE (expr))
- >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
- return c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr, 0));
+ {
+ tree totype = TREE_TYPE (expr);
+ tree fromtype = TREE_TYPE (TREE_OPERAND (expr, 0));
+
+ /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
+ since that affects how `default_conversion' will behave. */
+ if (TREE_CODE (totype) == REFERENCE_TYPE
+ || TREE_CODE (fromtype) == REFERENCE_TYPE)
+ break;
+ /* Don't strip a conversion from C++0x scoped enum, since they
+ don't implicitly convert to other types. */
+ if (TREE_CODE (fromtype) == ENUMERAL_TYPE
+ && ENUM_IS_SCOPED (fromtype))
+ break;
+ /* If this isn't narrowing the argument, we can ignore it. */
+ if (TYPE_PRECISION (totype) >= TYPE_PRECISION (fromtype))
+ return c_common_truthvalue_conversion (location,
+ TREE_OPERAND (expr, 0));
+ }
break;
case MODIFY_EXPR:
if (type == error_mark_node)
return;
- if (((type_quals & TYPE_QUAL_CONST)
- || (type && TREE_CODE (type) == REFERENCE_TYPE))
- /* An object declared 'const' is only readonly after it is
- initialized. We don't have any way of expressing this currently,
- so we need to be conservative and unset TREE_READONLY for types
- with constructors. Otherwise aliasing code will ignore stores in
- an inline constructor. */
- && !(type && TYPE_NEEDS_CONSTRUCTING (type)))
+ if ((type_quals & TYPE_QUAL_CONST)
+ || (type && TREE_CODE (type) == REFERENCE_TYPE))
+ /* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr
+ constructor can produce constant init, so rely on cp_finish_decl to
+ clear TREE_READONLY if the variable has non-constant init. */
TREE_READONLY (decl) = 1;
if (type_quals & TYPE_QUAL_VOLATILE)
{
static void
def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
{
- tree args = NULL, t;
+ tree t;
+ tree *args = XALLOCAVEC (tree, n);
va_list list;
int i;
t = builtin_types[a];
if (t == error_mark_node)
goto egress;
- args = tree_cons (NULL_TREE, t, args);
+ args[i] = t;
}
- va_end (list);
-
- args = nreverse (args);
- if (!var)
- args = chainon (args, void_list_node);
t = builtin_types[ret];
if (t == error_mark_node)
goto egress;
- t = build_function_type (t, args);
+ if (var)
+ t = build_varargs_function_type_array (t, n, args);
+ else
+ t = build_function_type_array (t, n, args);
egress:
builtin_types[def] = t;
tree va_list_ref_type_node;
tree va_list_arg_type_node;
+ build_common_tree_nodes (flag_signed_char, flag_short_double);
+
/* Define `int' and `char' first so that dbx will output them first. */
record_builtin_type (RID_INT, NULL, integer_type_node);
record_builtin_type (RID_CHAR, "char", char_type_node);
TYPE_DECL, NULL_TREE,
widest_unsigned_literal_type_node));
- /* `unsigned long' is the standard type for sizeof.
- Note that stddef.h uses `unsigned long',
- and this must agree, even if long and int are the same size. */
- size_type_node =
- TREE_TYPE (identifier_global_value (get_identifier (SIZE_TYPE)));
signed_size_type_node = c_common_signed_type (size_type_node);
- set_sizetype (size_type_node);
pid_type_node =
TREE_TYPE (identifier_global_value (get_identifier (PID_TYPE)));
- build_common_tree_nodes_2 (flag_short_double);
-
record_builtin_type (RID_FLOAT, NULL, float_type_node);
record_builtin_type (RID_DOUBLE, NULL, double_type_node);
record_builtin_type (RID_MAX, "long double", long_double_type_node);
uintptr_type_node =
TREE_TYPE (identifier_global_value (c_get_ident (UINTPTR_TYPE)));
- default_function_type = build_function_type (integer_type_node, NULL_TREE);
+ default_function_type
+ = build_varargs_function_type_list (integer_type_node, NULL_TREE);
ptrdiff_type_node
= TREE_TYPE (identifier_global_value (get_identifier (PTRDIFF_TYPE)));
unsigned_ptrdiff_type_node = c_common_unsigned_type (ptrdiff_type_node);
}
/* Add a CASE_LABEL to the statement-tree. */
- case_label = add_stmt (build_case_label (loc, low_value, high_value, label));
+ case_label = add_stmt (build_case_label (low_value, high_value, label));
/* Register this case label in the splay tree. */
splay_tree_insert (cases,
(splay_tree_key) low_value,
#define DEF_ATTR_NULL_TREE(ENUM) \
built_in_attributes[(int) ENUM] = NULL_TREE;
#define DEF_ATTR_INT(ENUM, VALUE) \
- built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
+ built_in_attributes[(int) ENUM] = build_int_cst (integer_type_node, VALUE);
#define DEF_ATTR_IDENT(ENUM, STRING) \
built_in_attributes[(int) ENUM] = get_identifier (STRING);
#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
{
tree decl = *node;
- if (targetm.have_named_sections)
+ if (targetm_common.have_named_sections)
{
user_defined_section_attribute = true;
a pointer argument. */
for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
{
- tree argument;
unsigned HOST_WIDE_INT arg_num = 0, ck_num;
if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
return NULL_TREE;
}
- argument = TYPE_ARG_TYPES (type);
- if (argument)
+ if (prototype_p (type))
{
- for (ck_num = 1; ; ck_num++)
+ function_args_iterator iter;
+ tree argument;
+
+ function_args_iter_init (&iter, type);
+ for (ck_num = 1; ; ck_num++, function_args_iter_next (&iter))
{
- if (!argument || ck_num == arg_num)
+ argument = function_args_iter_cond (&iter);
+ if (argument == NULL_TREE || ck_num == arg_num)
break;
- argument = TREE_CHAIN (argument);
}
if (!argument
- || TREE_CODE (TREE_VALUE (argument)) == VOID_TYPE)
+ || TREE_CODE (argument) == VOID_TYPE)
{
error ("nonnull argument with out-of-range operand number (argument %lu, operand %lu)",
(unsigned long) attr_arg_num, (unsigned long) arg_num);
return NULL_TREE;
}
- if (TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE)
+ if (TREE_CODE (argument) != POINTER_TYPE)
{
error ("nonnull argument references non-pointer operand (argument %lu, operand %lu)",
(unsigned long) attr_arg_num, (unsigned long) arg_num);
array ARGARRAY. */
static void
-check_function_sentinel (tree attrs, int nargs, tree *argarray, tree typelist)
+check_function_sentinel (const_tree fntype, int nargs, tree *argarray)
{
- tree attr = lookup_attribute ("sentinel", attrs);
+ tree attr = lookup_attribute ("sentinel", TYPE_ATTRIBUTES (fntype));
if (attr)
{
int len = 0;
int pos = 0;
tree sentinel;
+ function_args_iterator iter;
+ tree t;
/* Skip over the named arguments. */
- while (typelist && len < nargs)
+ FOREACH_FUNCTION_ARGS (fntype, t, iter)
{
- typelist = TREE_CHAIN (typelist);
+ if (len == nargs)
+ break;
len++;
}
handle_sentinel_attribute (tree *node, tree name, tree args,
int ARG_UNUSED (flags), bool *no_add_attrs)
{
- tree params = TYPE_ARG_TYPES (*node);
-
if (!prototype_p (*node))
{
warning (OPT_Wattributes,
}
else
{
- while (TREE_CHAIN (params))
- params = TREE_CHAIN (params);
-
- if (VOID_TYPE_P (TREE_VALUE (params)))
+ if (!stdarg_p (*node))
{
warning (OPT_Wattributes,
"%qE attribute only applies to variadic functions", name);
tree ARG_UNUSED (args), int ARG_UNUSED (flags),
bool * ARG_UNUSED (no_add_attrs))
{
- tree params;
-
/* Ensure we have a function type. */
gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
- params = TYPE_ARG_TYPES (*node);
- while (params && ! VOID_TYPE_P (TREE_VALUE (params)))
- params = TREE_CHAIN (params);
-
/* Ensure we have a variadic function. */
- gcc_assert (!params);
+ gcc_assert (!prototype_p (*node) || stdarg_p (*node));
return NULL_TREE;
}
return NULL_TREE;
}
\f
-/* Check for valid arguments being passed to a function.
- ATTRS is a list of attributes. There are NARGS arguments in the array
- ARGARRAY. TYPELIST is the list of argument types for the function.
- */
+/* Check for valid arguments being passed to a function with FNTYPE.
+ There are NARGS arguments in the array ARGARRAY. */
void
-check_function_arguments (tree attrs, int nargs, tree *argarray, tree typelist)
+check_function_arguments (const_tree fntype, int nargs, tree *argarray)
{
/* Check for null being passed in a pointer argument that must be
non-null. We also need to do this if format checking is enabled. */
if (warn_nonnull)
- check_function_nonnull (attrs, nargs, argarray);
+ check_function_nonnull (TYPE_ATTRIBUTES (fntype), nargs, argarray);
/* Check for errors in format strings. */
if (warn_format || warn_missing_format_attribute)
- check_function_format (attrs, nargs, argarray);
+ check_function_format (TYPE_ATTRIBUTES (fntype), nargs, argarray);
if (warn_format)
- check_function_sentinel (attrs, nargs, argarray, typelist);
+ check_function_sentinel (fntype, nargs, argarray);
}
/* Generic argument checking recursion routine. PARAM is the argument to
}
return false;
+ case BUILT_IN_ASSUME_ALIGNED:
+ if (builtin_function_validate_nargs (fndecl, nargs, 2 + (nargs > 2)))
+ {
+ if (nargs >= 3 && TREE_CODE (TREE_TYPE (args[2])) != INTEGER_TYPE)
+ {
+ error ("non-integer argument 3 in call to function %qE", fndecl);
+ return false;
+ }
+ return true;
+ }
+ return false;
+
default:
return true;
}
message = catenate_messages (gmsgid, " before %<#pragma%>");
else if (token_type == CPP_PRAGMA_EOL)
message = catenate_messages (gmsgid, " before end of line");
+ else if (token_type == CPP_DECLTYPE)
+ message = catenate_messages (gmsgid, " before %<decltype%>");
else if (token_type < N_TTYPES)
{
message = catenate_messages (gmsgid, " before %qs token");
TYPE_LANG_FLAG_? bits that the front end may have set. */
main_type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
TREE_TYPE (main_type) = unqual_elt;
- TYPE_DOMAIN (main_type) = build_index_type (maxindex);
+ TYPE_DOMAIN (main_type)
+ = build_range_type (TREE_TYPE (maxindex),
+ build_int_cst (TREE_TYPE (maxindex), 0), maxindex);
layout_type (main_type);
/* Make sure we have the canonical MAIN_TYPE. */
static bool
sync_resolve_params (tree orig_function, tree function, VEC(tree, gc) *params)
{
- tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (function));
+ function_args_iterator iter;
tree ptype;
unsigned int parmnum;
+ function_args_iter_init (&iter, TREE_TYPE (function));
/* We've declared the implementation functions to use "volatile void *"
as the pointer parameter, so we shouldn't get any complaints from the
call to check_function_arguments what ever type the user used. */
- arg_types = TREE_CHAIN (arg_types);
+ function_args_iter_next (&iter);
ptype = TREE_TYPE (TREE_TYPE (VEC_index (tree, params, 0)));
/* For the rest of the values, we need to cast these to FTYPE, so that we
don't get warnings for passing pointer types, etc. */
parmnum = 0;
- while (arg_types != void_list_node)
+ while (1)
{
- tree val;
+ tree val, arg_type;
+
+ arg_type = function_args_iter_cond (&iter);
+ /* XXX void_type_node belies the abstraction. */
+ if (arg_type == void_type_node)
+ break;
++parmnum;
if (VEC_length (tree, params) <= parmnum)
type. This isn't portable across the C and C++ front ends atm. */
val = VEC_index (tree, params, parmnum);
val = convert (ptype, val);
- val = convert (TREE_VALUE (arg_types), val);
+ val = convert (arg_type, val);
VEC_replace (tree, params, parmnum, val);
- arg_types = TREE_CHAIN (arg_types);
+ function_args_iter_next (&iter);
}
/* The definition of these primitives is variadic, with the remaining
/* Handle BUILT_IN_NORMAL here. */
switch (orig_code)
{
- case BUILT_IN_FETCH_AND_ADD_N:
- case BUILT_IN_FETCH_AND_SUB_N:
- case BUILT_IN_FETCH_AND_OR_N:
- case BUILT_IN_FETCH_AND_AND_N:
- case BUILT_IN_FETCH_AND_XOR_N:
- case BUILT_IN_FETCH_AND_NAND_N:
- case BUILT_IN_ADD_AND_FETCH_N:
- case BUILT_IN_SUB_AND_FETCH_N:
- case BUILT_IN_OR_AND_FETCH_N:
- case BUILT_IN_AND_AND_FETCH_N:
- case BUILT_IN_XOR_AND_FETCH_N:
- case BUILT_IN_NAND_AND_FETCH_N:
- case BUILT_IN_BOOL_COMPARE_AND_SWAP_N:
- case BUILT_IN_VAL_COMPARE_AND_SWAP_N:
- case BUILT_IN_LOCK_TEST_AND_SET_N:
- case BUILT_IN_LOCK_RELEASE_N:
+ case BUILT_IN_SYNC_FETCH_AND_ADD_N:
+ case BUILT_IN_SYNC_FETCH_AND_SUB_N:
+ case BUILT_IN_SYNC_FETCH_AND_OR_N:
+ case BUILT_IN_SYNC_FETCH_AND_AND_N:
+ case BUILT_IN_SYNC_FETCH_AND_XOR_N:
+ case BUILT_IN_SYNC_FETCH_AND_NAND_N:
+ case BUILT_IN_SYNC_ADD_AND_FETCH_N:
+ case BUILT_IN_SYNC_SUB_AND_FETCH_N:
+ case BUILT_IN_SYNC_OR_AND_FETCH_N:
+ case BUILT_IN_SYNC_AND_AND_FETCH_N:
+ case BUILT_IN_SYNC_XOR_AND_FETCH_N:
+ case BUILT_IN_SYNC_NAND_AND_FETCH_N:
+ case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_N:
+ case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N:
+ case BUILT_IN_SYNC_LOCK_TEST_AND_SET_N:
+ case BUILT_IN_SYNC_LOCK_RELEASE_N:
{
int n = sync_resolve_size (function, params);
tree new_function, first_param, result;
first_param = VEC_index (tree, params, 0);
result = build_function_call_vec (loc, new_function, params, NULL);
- if (orig_code != BUILT_IN_BOOL_COMPARE_AND_SWAP_N
- && orig_code != BUILT_IN_LOCK_RELEASE_N)
+ if (orig_code != BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_N
+ && orig_code != BUILT_IN_SYNC_LOCK_RELEASE_N)
result = sync_resolve_return (first_param, result);
return result;
}
}
-#ifndef TARGET_HAS_TARGETCM
-struct gcc_targetcm targetcm = TARGETCM_INITIALIZER;
-#endif
-
/* Warn for division by zero according to the value of DIVISOR. LOC
is the location of the division operator. */
have all bits set that are set in the ~ operand when it is
extended. */
- op0 = get_narrower (op0, &unsignedp0);
- op1 = get_narrower (op1, &unsignedp1);
+ op0 = c_common_get_narrower (op0, &unsignedp0);
+ op1 = c_common_get_narrower (op1, &unsignedp1);
if ((TREE_CODE (op0) == BIT_NOT_EXPR)
^ (TREE_CODE (op1) == BIT_NOT_EXPR))
{
if (TREE_CODE (op0) == BIT_NOT_EXPR)
- op0 = get_narrower (TREE_OPERAND (op0, 0), &unsignedp0);
+ op0 = c_common_get_narrower (TREE_OPERAND (op0, 0), &unsignedp0);
if (TREE_CODE (op1) == BIT_NOT_EXPR)
- op1 = get_narrower (TREE_OPERAND (op1, 0), &unsignedp1);
+ op1 = c_common_get_narrower (TREE_OPERAND (op1, 0), &unsignedp1);
if (host_integerp (op0, 0) || host_integerp (op1, 0))
{
return ret;
}
+/* Get a new tree vector of the TREE_VALUEs of a TREE_LIST chain. */
+
+VEC(tree,gc) *
+make_tree_vector_from_list (tree list)
+{
+ VEC(tree,gc) *ret = make_tree_vector ();
+ for (; list; list = TREE_CHAIN (list))
+ VEC_safe_push (tree, gc, ret, TREE_VALUE (list));
+ return ret;
+}
+
/* Get a new tree vector which is a copy of an existing one. */
VEC(tree,gc) *
}
}
+/* Initialize language-specific-bits of tree_contains_struct. */
+
+void
+c_common_init_ts (void)
+{
+ MARK_TS_TYPED (C_MAYBE_CONST_EXPR);
+ MARK_TS_TYPED (EXCESS_PRECISION_EXPR);
+}
+
#include "gt-c-family-c-common.h"