OSDN Git Service

PR c/46547
[pf3gnuchains/gcc-fork.git] / gcc / c-family / c-common.c
index 63e2d70..cd9175a 100644 (file)
@@ -271,6 +271,14 @@ tree (*make_fname_decl) (location_t, tree, int);
    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;
@@ -381,8 +389,13 @@ static int resort_field_decl_cmp (const void *, const void *);
    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 },
@@ -434,6 +447,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__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 },
@@ -536,6 +550,12 @@ const struct c_common_resword c_common_reswords[] =
   { "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 },
@@ -544,6 +564,15 @@ const struct c_common_resword c_common_reswords[] =
   { "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 =
@@ -1842,8 +1871,7 @@ conversion_warning (tree type, tree expr)
   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;
@@ -2276,8 +2304,7 @@ warn_for_collisions_1 (tree written, tree writer, struct tlist *list,
          && (!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);
        }
@@ -2305,10 +2332,26 @@ warn_for_collisions (struct tlist *list)
 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) */
@@ -2565,22 +2608,6 @@ check_case_value (tree value)
   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);
@@ -3920,7 +3947,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
 
   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)
@@ -5726,7 +5753,8 @@ handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args),
   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)
@@ -6404,7 +6432,7 @@ handle_mode_attribute (tree *node, tree name, tree args,
          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.  */
@@ -7182,7 +7210,8 @@ handle_deprecated_attribute (tree *node, tree name,
          || 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;
@@ -7795,8 +7824,12 @@ parse_optimize_options (tree args, bool attr_p)
   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();
 
@@ -7826,12 +7859,13 @@ handle_optimize_attribute (tree *node, tree name, tree args,
       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);
@@ -7839,7 +7873,7 @@ handle_optimize_attribute (tree *node, tree name, tree args,
        = build_optimization_node ();
 
       /* Restore current options.  */
-      cl_optimization_restore (&cur_opts);
+      cl_optimization_restore (&global_options, &cur_opts);
     }
 
   return NULL_TREE;
@@ -8306,7 +8340,7 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason,
 {
   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)
@@ -8314,7 +8348,7 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason,
     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)
@@ -8351,7 +8385,7 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason,
                                     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;
 }
 
@@ -8681,6 +8715,18 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
   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.