static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
-static tree handle_option_attribute (tree *, tree, tree, int, bool *);
+static tree handle_target_attribute (tree *, tree, tree, int, bool *);
static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
static void check_function_nonnull (tree, int, tree *);
handle_error_attribute },
{ "error", 1, 1, true, false, false,
handle_error_attribute },
- { "option", 1, -1, true, false, false,
- handle_option_attribute },
+ { "target", 1, -1, true, false, false,
+ handle_target_attribute },
{ "optimize", 1, -1, true, false, false,
handle_optimize_attribute },
{ NULL, 0, 0, false, false, false, NULL }
input_location = saved_location;
}
if (!ix && !current_function_decl)
- pedwarn (0, "%qD is not defined outside of function scope", decl);
+ pedwarn (input_location, 0, "%qD is not defined outside of function scope", decl);
return decl;
}
separate the %d from the 'C'. 'ISO' should not be
translated, but it may be moved after 'C%d' in languages
where modifiers follow nouns. */
- pedwarn (OPT_Woverlength_strings,
+ pedwarn (input_location, OPT_Woverlength_strings,
"string length %qd is greater than the length %qd "
"ISO C%d compilers are required to support",
nchars - 1, nchars_max, relevant_std);
|| TREE_CODE (value) == VECTOR_CST
|| TREE_CODE (value) == COMPLEX_CST)
&& TREE_OVERFLOW (value))
- pedwarn (OPT_Woverflow, "overflow in constant expression");
+ pedwarn (input_location, OPT_Woverflow, "overflow in constant expression");
}
/* The same as above but print an unconditional error. */
{
case 1:
if (TYPE_MAIN_VARIANT (type) != integer_type_node)
- pedwarn (OPT_Wmain, "first argument of %q+D should be %<int%>",
+ pedwarn (input_location, OPT_Wmain, "first argument of %q+D should be %<int%>",
decl);
break;
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
- pedwarn (OPT_Wmain, "second argument of %q+D should be %<char **%>",
+ pedwarn (input_location, OPT_Wmain, "second argument of %q+D should be %<char **%>",
decl);
break;
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
- pedwarn (OPT_Wmain, "third argument of %q+D should probably be "
+ pedwarn (input_location, OPT_Wmain, "third argument of %q+D should probably be "
"%<char **%>", decl);
break;
}
argument because it's only mentioned in an appendix of the
standard. */
if (argct > 0 && (argct < 2 || argct > 3))
- pedwarn (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
if (emit_lax_note && !emitted_lax_note)
{
emitted_lax_note = true;
- inform ("use -flax-vector-conversions to permit "
+ inform (input_location, "use -flax-vector-conversions to permit "
"conversions between vectors with differing "
"element types or numbers of subparts");
}
{
bool give_warning = false;
+ int i;
+ const int expr_num_operands = TREE_OPERAND_LENGTH (expr);
tree expr_type = TREE_TYPE (expr);
if (!warn_conversion && !warn_sign_conversion)
return;
+ /* If any operand is artificial, then this expression was generated
+ by the compiler and we do not warn. */
+ for (i = 0; i < expr_num_operands; i++)
+ {
+ tree op = TREE_OPERAND (expr, i);
+ if (op && DECL_P (op) && DECL_ARTIFICIAL (op))
+ return;
+ }
+
switch (TREE_CODE (expr))
{
case EQ_EXPR:
TREE_OPERAND (expr, 1),
/* bitwise */1);
- /* If one of the operands is a non-negative constant
- that fits in the target type, then the type of the
- other operand does not matter. */
if (TREE_CODE (expr) == BIT_AND_EXPR)
{
tree op0 = TREE_OPERAND (expr, 0);
tree op1 = TREE_OPERAND (expr, 1);
+ bool unsigned0 = TYPE_UNSIGNED (TREE_TYPE (op0));
+ bool unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1));
+
+ /* If one of the operands is a non-negative constant
+ that fits in the target type, then the type of the
+ other operand does not matter. */
if ((TREE_CODE (op0) == INTEGER_CST
&& int_fits_type_p (op0, c_common_signed_type (type))
&& int_fits_type_p (op0, c_common_unsigned_type (type)))
&& int_fits_type_p (op1,
c_common_unsigned_type (type))))
return;
+ /* If constant is unsigned and fits in the target
+ type, then the result will also fit. */
+ else if ((TREE_CODE (op0) == INTEGER_CST
+ && unsigned0
+ && int_fits_type_p (op0, type))
+ || (TREE_CODE (op1) == INTEGER_CST
+ && unsigned1
+ && int_fits_type_p (op1, type)))
+ return;
}
}
/* Warn for integer types converted to smaller integer types. */
return;
}
+ case ADDR_EXPR:
+ x = TREE_OPERAND (x, 0);
+ if (DECL_P (x))
+ return;
+ writer = 0;
+ goto restart;
+
default:
/* For other expressions, simply recurse on their operands.
Manual tail recursion for unary expressions.
if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
{
- pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"pointer of type %<void *%> used in arithmetic");
size_exp = integer_one_node;
}
else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
{
- pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"pointer to a function used in arithmetic");
size_exp = integer_one_node;
}
else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE)
{
- pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"pointer to member function used in arithmetic");
size_exp = integer_one_node;
}
if (is_sizeof)
{
if (complain && (pedantic || warn_pointer_arith))
- pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"invalid application of %<sizeof%> to a function type");
else if (!complain)
return error_mark_node;
{
if (type_code == VOID_TYPE
&& complain && (pedantic || warn_pointer_arith))
- pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"invalid application of %qs to a void type", op_name);
else if (!complain)
return error_mark_node;
/* Case ranges are a GNU extension. */
if (high_value)
- pedwarn (OPT_pedantic,
+ pedwarn (input_location, OPT_pedantic,
"range expressions in switch statements are non-standard");
type = TREE_TYPE (cond);
for (chain = TYPE_VALUES (type); chain; chain = TREE_CHAIN (chain))
{
tree value = TREE_VALUE (chain);
+ if (TREE_CODE (value) == CONST_DECL)
+ value = DECL_INITIAL (value);
node = splay_tree_lookup (cases, (splay_tree_key) value);
if (node)
{
{
tree result;
- pedwarn (OPT_pedantic, "taking the address of a label is non-standard");
+ pedwarn (input_location, OPT_pedantic, "taking the address of a label is non-standard");
if (label == error_mark_node)
return error_mark_node;
name, "cold");
*no_add_attrs = true;
}
- else
- {
- tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
-
- /* If we are not at -O3, but are optimizing, turn on -O3
- optimizations just for this one function. */
- if (((optimize > 0 && optimize < 3) || optimize_size)
- && targetm.target_option.hot_attribute_sets_optimization
- && (!old_opts || old_opts == optimization_default_node))
- {
- /* Create the hot optimization node if needed. */
- if (!optimization_hot_node)
- {
- struct cl_optimization current_options;
- static const char *os_argv[] = { NULL, "-O3", NULL };
-
- cl_optimization_save (¤t_options);
- decode_options (2, os_argv);
- optimization_hot_node = build_optimization_node ();
- cl_optimization_restore (¤t_options);
- }
-
- DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
- = optimization_hot_node;
- }
- /* Most of the rest of the hot processing is done later with
- lookup_attribute. */
- }
+ /* Most of the rest of the hot processing is done later with
+ lookup_attribute. */
}
else
{
name, "hot");
*no_add_attrs = true;
}
- else
- {
- tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
-
- /* If we are optimizing, but not optimizing for space, turn on -Os
- optimizations just for this one function. */
- if (optimize && !optimize_size
- && targetm.target_option.cold_attribute_sets_optimization
- && (!old_opts || old_opts == optimization_default_node))
- {
- /* Create the cold optimization node if needed. */
- if (!optimization_cold_node)
- {
- struct cl_optimization current_options;
- static const char *os_argv[] = { NULL, "-Os", NULL };
-
- cl_optimization_save (¤t_options);
- decode_options (2, os_argv);
- optimization_cold_node = build_optimization_node ();
- cl_optimization_restore (¤t_options);
- }
-
- DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
- = optimization_cold_node;
- }
- /* Most of the rest of the cold processing is done later with
- lookup_attribute. */
- }
+ /* Most of the rest of the cold processing is done later with
+ lookup_attribute. */
}
else
{
return NULL_TREE;
}
-/* For handling "option" attribute. arguments as in
- struct attribute_spec.handler. */
+/* Handle a "target" attribute. */
static tree
-handle_option_attribute (tree *node, tree name, tree args, int flags,
+handle_target_attribute (tree *node, tree name, tree args, int flags,
bool *no_add_attrs)
{
/* Ensure we have a function type. */
warning (OPT_Wattributes, "%qE attribute ignored", name);
*no_add_attrs = true;
}
- else if (targetm.target_option.valid_attribute_p
- == default_target_option_valid_attribute_p)
- {
- warning (OPT_Wattributes,
- "%qE attribute is not supported on this machine",
- name);
- *no_add_attrs = true;
- }
else if (! targetm.target_option.valid_attribute_p (*node, name, args,
flags))
*no_add_attrs = true;
return error_mark_node;
case CALL_EXPR:
+ case TARGET_EXPR:
error ("cannot apply %<offsetof%> when %<operator[]%> is overloaded");
return error_mark_node;