OSDN Git Service

PR c/46547
[pf3gnuchains/gcc-fork.git] / gcc / c-family / c-common.c
index 98568e8..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;
@@ -439,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 },
@@ -564,9 +573,6 @@ const struct c_common_resword c_common_reswords[] =
   { "readwrite",       RID_READWRITE,          D_OBJC }, 
   { "retain",          RID_RETAIN,             D_OBJC }, 
   { "setter",          RID_SETTER,             D_OBJC }, 
-  /* The following two will be removed once @synthesize is fully implemented.  */
-  { "copies",          RID_COPIES,             D_OBJC },
-  { "ivar",            RID_IVAR,               D_OBJC }, 
 };
 
 const unsigned int num_c_common_reswords =
@@ -1865,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;
@@ -2299,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);
        }
@@ -2328,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) */
@@ -3927,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)
@@ -5733,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)
@@ -6411,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.  */
@@ -7807,7 +7828,8 @@ parse_optimize_options (tree args, bool attr_p)
                                                &decoded_options,
                                                &decoded_options_count);
   decode_options (&global_options, &global_options_set,
-                 decoded_options, decoded_options_count);
+                 decoded_options, decoded_options_count,
+                 input_location, global_dc);
 
   targetm.override_options_after_change();