executed. */
int c_inhibit_evaluation_warnings;
+/* Whether we are building a boolean conversion inside
+ convert_for_assignment, or some other late binary operation. If
+ build_binary_op is called for C (from code shared by C and C++) in
+ this case, then the operands have already been folded and the
+ result will not be folded again, so C_MAYBE_CONST_EXPR should not
+ be generated. */
+bool in_late_binary_op;
+
/* Whether lexing has been completed, so subsequent preprocessor
errors should use the compiler's input_location. */
bool done_lexing = false;
If -fno-asm is used, D_ASM is added to the mask. If
-fno-gnu-keywords is used, D_EXT is added. If -fno-asm and C in
C89 mode, D_EXT89 is added for both -fno-asm and -fno-gnu-keywords.
- In C with -Wc++-compat, we warn if D_CXXWARN is set. */
+ In C with -Wc++-compat, we warn if D_CXXWARN is set.
+ Note the complication of the D_CXX_OBJC keywords. These are
+ reserved words such as 'class'. In C++, 'class' is a reserved
+ word. In Objective-C++ it is too. In Objective-C, it is a
+ reserved word too, but only if it follows an '@' sign.
+*/
const struct c_common_resword c_common_reswords[] =
{
{ "_Bool", RID_BOOL, D_CONLY },
{ "__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 },
{ "selector", RID_AT_SELECTOR, D_OBJC },
{ "finally", RID_AT_FINALLY, D_OBJC },
{ "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
+ { "optional", RID_AT_OPTIONAL, D_OBJC },
+ { "required", RID_AT_REQUIRED, D_OBJC },
+ { "property", RID_AT_PROPERTY, D_OBJC },
+ { "package", RID_AT_PACKAGE, D_OBJC },
+ { "synthesize", RID_AT_SYNTHESIZE, D_OBJC },
+ { "dynamic", RID_AT_DYNAMIC, D_OBJC },
/* These are recognized only in protocol-qualifier context
(see above) */
{ "bycopy", RID_BYCOPY, D_OBJC },
{ "inout", RID_INOUT, D_OBJC },
{ "oneway", RID_ONEWAY, D_OBJC },
{ "out", RID_OUT, D_OBJC },
+ /* These are recognized inside a property attribute list */
+ { "assign", RID_ASSIGN, D_OBJC },
+ { "copy", RID_COPY, D_OBJC },
+ { "getter", RID_GETTER, D_OBJC },
+ { "nonatomic", RID_NONATOMIC, D_OBJC },
+ { "readonly", RID_READONLY, D_OBJC },
+ { "readwrite", RID_READWRITE, D_OBJC },
+ { "retain", RID_RETAIN, D_OBJC },
+ { "setter", RID_SETTER, D_OBJC },
};
const unsigned int num_c_common_reswords =
int i;
const int expr_num_operands = TREE_OPERAND_LENGTH (expr);
tree expr_type = TREE_TYPE (expr);
- location_t loc = EXPR_HAS_LOCATION (expr)
- ? EXPR_LOCATION (expr) : input_location;
+ location_t loc = EXPR_LOC_OR_HERE (expr);
if (!warn_conversion && !warn_sign_conversion)
return;
&& (!only_writes || list->writer))
{
warned_ids = new_tlist (warned_ids, written, NULL_TREE);
- warning_at (EXPR_HAS_LOCATION (writer)
- ? EXPR_LOCATION (writer) : input_location,
+ warning_at (EXPR_LOC_OR_HERE (writer),
OPT_Wsequence_point, "operation on %qE may be undefined",
list->expr);
}
static int
warning_candidate_p (tree x)
{
- /* !VOID_TYPE_P (TREE_TYPE (x)) is workaround for cp/tree.c
+ if (DECL_P (x) && DECL_ARTIFICIAL (x))
+ return 0;
+
+ /* VOID_TYPE_P (TREE_TYPE (x)) is workaround for cp/tree.c
(lvalue_p) crash on TRY/CATCH. */
- return !(DECL_P (x) && DECL_ARTIFICIAL (x))
- && TREE_TYPE (x) && !VOID_TYPE_P (TREE_TYPE (x)) && lvalue_p (x);
+ if (TREE_TYPE (x) == NULL_TREE || VOID_TYPE_P (TREE_TYPE (x)))
+ return 0;
+
+ if (!lvalue_p (x))
+ return 0;
+
+ /* No point to track non-const calls, they will never satisfy
+ operand_equal_p. */
+ if (TREE_CODE (x) == CALL_EXPR && (call_expr_flags (x) & ECF_CONST) == 0)
+ return 0;
+
+ if (TREE_CODE (x) == STRING_CST)
+ return 0;
+
+ return 1;
}
/* Return nonzero if X and Y appear to be the same candidate (or NULL) */
if (value == NULL_TREE)
return value;
- /* ??? Can we ever get nops here for a valid case value? We
- shouldn't for C. */
- STRIP_TYPE_NOPS (value);
- /* In C++, the following is allowed:
-
- const int i = 3;
- switch (...) { case i: ... }
-
- So, we try to reduce the VALUE to a constant that way. */
- if (c_dialect_cxx ())
- {
- value = decl_constant_value (value);
- STRIP_TYPE_NOPS (value);
- value = fold (value);
- }
-
if (TREE_CODE (value) == INTEGER_CST)
/* Promote char or short to int. */
value = perform_integral_promotions (value);
if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
{
- tree t = c_save_expr (expr);
+ tree t = (in_late_binary_op ? save_expr (expr) : c_save_expr (expr));
expr = (build_binary_op
(EXPR_LOCATION (expr),
(TREE_SIDE_EFFECTS (expr)
tree type = TREE_TYPE (*node);
/* See FIXME comment in c_common_attribute_table. */
- if (TREE_CODE (*node) == FUNCTION_DECL)
+ if (TREE_CODE (*node) == FUNCTION_DECL
+ || objc_method_decl (TREE_CODE (*node)))
TREE_THIS_VOLATILE (*node) = 1;
else if (TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
if (ALL_FIXED_POINT_MODE_P (mode)
&& TYPE_UNSIGNED (type) != UNSIGNED_FIXED_POINT_MODE_P (mode))
{
- error ("signness of type and machine mode %qs don't match", p);
+ error ("signedness of type and machine mode %qs don%'t match", p);
return NULL_TREE;
}
/* For fixed-point modes, we need to pass saturating info. */
|| TREE_CODE (decl) == PARM_DECL
|| TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == FUNCTION_DECL
- || TREE_CODE (decl) == FIELD_DECL)
+ || TREE_CODE (decl) == FIELD_DECL
+ || objc_method_decl (TREE_CODE (decl)))
TREE_DEPRECATED (decl) = 1;
else
warn = 1;
saved_flag_strict_aliasing = flag_strict_aliasing;
/* Now parse the options. */
- decode_options (opt_argc, opt_argv, &decoded_options,
- &decoded_options_count);
+ decode_cmdline_options_to_array_default_mask (opt_argc, opt_argv,
+ &decoded_options,
+ &decoded_options_count);
+ decode_options (&global_options, &global_options_set,
+ decoded_options, decoded_options_count,
+ input_location, global_dc);
targetm.override_options_after_change();
tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
/* Save current options. */
- cl_optimization_save (&cur_opts);
+ cl_optimization_save (&cur_opts, &global_options);
/* If we previously had some optimization options, use them as the
default. */
if (old_opts)
- cl_optimization_restore (TREE_OPTIMIZATION (old_opts));
+ cl_optimization_restore (&global_options,
+ TREE_OPTIMIZATION (old_opts));
/* Parse options, and update the vector. */
parse_optimize_options (args, true);
= build_optimization_node ();
/* Restore current options. */
- cl_optimization_restore (&cur_opts);
+ cl_optimization_restore (&global_options, &cur_opts);
}
return NULL_TREE;
{
diagnostic_info diagnostic;
diagnostic_t dlevel;
- bool save_warn_system_headers = global_dc->warn_system_headers;
+ bool save_warn_system_headers = global_dc->dc_warn_system_headers;
bool ret;
switch (level)
case CPP_DL_WARNING_SYSHDR:
if (flag_no_output)
return false;
- global_dc->warn_system_headers = 1;
+ global_dc->dc_warn_system_headers = 1;
/* Fall through. */
case CPP_DL_WARNING:
if (flag_no_output)
c_option_controlling_cpp_error (reason));
ret = report_diagnostic (&diagnostic);
if (level == CPP_DL_WARNING_SYSHDR)
- global_dc->warn_system_headers = save_warn_system_headers;
+ global_dc->dc_warn_system_headers = save_warn_system_headers;
return ret;
}
return failure;
}
+/* Like c_mark_addressable but don't check register qualifier. */
+void
+c_common_mark_addressable_vec (tree t)
+{
+ while (handled_component_p (t))
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
+ return;
+ TREE_ADDRESSABLE (t) = 1;
+}
+
+
\f
/* Used to help initialize the builtin-types.def table. When a type of
the correct size doesn't exist, use error_mark_node instead of NULL.