OSDN Git Service

* trans-stmt.c (gfc_trans_forall_1): Prefer to use smaller logical
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index b2ba01e..91fba52 100644 (file)
@@ -16,8 +16,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -47,6 +47,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tree-mudflap.h"
 #include "opts.h"
 #include "real.h"
+#include "cgraph.h"
 
 cpp_reader *parse_in;          /* Declared in c-pragma.h.  */
 
@@ -290,13 +291,6 @@ int warn_strict_null_sentinel;
    will most likely result in crashes.  */
 int flag_nil_receivers = 1;
 
-/* Nonzero means that we will allow new ObjC exception syntax (@throw,
-   @try, etc.) in source code.  */
-int flag_objc_exceptions = 0;
-
-/* Nonzero means that we generate NeXT setjmp based exceptions.  */
-int flag_objc_sjlj_exceptions = -1;
-
 /* Nonzero means that code generation will be altered to support
    "zero-link" execution.  This currently affects ObjC only, but may
    affect other languages in the future.  */
@@ -521,6 +515,8 @@ static tree handle_always_inline_attribute (tree *, tree, tree, int,
                                            bool *);
 static tree handle_used_attribute (tree *, tree, tree, int, bool *);
 static tree handle_unused_attribute (tree *, tree, tree, int, bool *);
+static tree handle_externally_visible_attribute (tree *, tree, tree, int,
+                                                bool *);
 static tree handle_const_attribute (tree *, tree, tree, int, bool *);
 static tree handle_transparent_union_attribute (tree *, tree, tree,
                                                int, bool *);
@@ -587,6 +583,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_used_attribute },
   { "unused",                 0, 0, false, false, false,
                              handle_unused_attribute },
+  { "externally_visible",     0, 0, true,  false, false,
+                             handle_externally_visible_attribute },
   /* The same comments as for noreturn attributes apply to const ones.  */
   { "const",                  0, 0, true,  false, false,
                              handle_const_attribute },
@@ -952,8 +950,9 @@ unsigned_conversion_warning (tree result, tree operand)
       if (!int_fits_type_p (operand, c_common_signed_type (type)))
        /* This detects cases like converting -129 or 256 to unsigned char.  */
        warning (0, "large integer implicitly truncated to unsigned type");
-      else if (warn_conversion)
-       warning (0, "negative integer implicitly converted to unsigned type");
+      else
+       warning (OPT_Wconversion,
+                "negative integer implicitly converted to unsigned type");
     }
 }
 
@@ -1451,7 +1450,7 @@ check_case_value (tree value)
    if the case is not a case range.
    The caller has to make sure that we are not called with NULL for
    CASE_LOW_P (i.e. the default case).
-   Returns true if the case label is in range of ORIG_TYPE (satured or
+   Returns true if the case label is in range of ORIG_TYPE (saturated or
    untouched) or false if the label is out of range.  */
 
 static bool
@@ -2462,12 +2461,12 @@ c_common_truthvalue_conversion (tree expr)
         two objects.  */
       if (TREE_TYPE (TREE_OPERAND (expr, 0))
          == TREE_TYPE (TREE_OPERAND (expr, 1)))
-       return build_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
-                               TREE_OPERAND (expr, 1), 1);
-      return build_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
-                             fold (build1 (NOP_EXPR,
-                                           TREE_TYPE (TREE_OPERAND (expr, 0)),
-                                           TREE_OPERAND (expr, 1))), 1);
+       return fold_build2 (NE_EXPR, truthvalue_type_node,
+                           TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
+      return fold_build2 (NE_EXPR, truthvalue_type_node,
+                         TREE_OPERAND (expr, 0),
+                         fold_convert (TREE_TYPE (TREE_OPERAND (expr, 0)),
+                                       TREE_OPERAND (expr, 1)));
 
     case BIT_AND_EXPR:
       if (integer_onep (TREE_OPERAND (expr, 1))
@@ -2477,8 +2476,9 @@ c_common_truthvalue_conversion (tree expr)
       break;
 
     case MODIFY_EXPR:
-      if (warn_parentheses && !TREE_NO_WARNING (expr))
-       warning (0, "suggest parentheses around assignment used as truth value");
+      if (!TREE_NO_WARNING (expr))
+       warning (OPT_Wparentheses,
+                "suggest parentheses around assignment used as truth value");
       break;
 
     default:
@@ -3732,8 +3732,9 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location,
     return;
 
   default_node = splay_tree_lookup (cases, (splay_tree_key) NULL);
-  if (warn_switch_default && !default_node)
-    warning (0, "%Hswitch missing default case", &switch_location);
+  if (!default_node)
+    warning (OPT_Wswitch_default, "%Hswitch missing default case",
+            &switch_location);
 
   /* If the switch expression was an enumerated type, check that
      exactly all enumeration literals are covered by the cases.
@@ -3963,7 +3964,7 @@ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
      that changes what the typedef is typing.  */
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -3982,7 +3983,7 @@ handle_nocommon_attribute (tree *node, tree name,
     DECL_COMMON (*node) = 0;
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4000,7 +4001,7 @@ handle_common_attribute (tree *node, tree name, tree ARG_UNUSED (args),
     DECL_COMMON (*node) = 1;
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4027,7 +4028,7 @@ handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args),
                             TYPE_READONLY (TREE_TYPE (type)), 1));
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4046,7 +4047,7 @@ handle_noinline_attribute (tree *node, tree name,
     DECL_UNINLINABLE (*node) = 1;
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4069,7 +4070,7 @@ handle_always_inline_attribute (tree *node, tree name,
     }
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4093,7 +4094,7 @@ handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
     }
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4119,7 +4120,7 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
        TREE_USED (decl) = 1;
       else
        {
-         warning (0, "%qE attribute ignored", name);
+         warning (OPT_Wattributes, "%qE attribute ignored", name);
          *no_add_attrs = true;
        }
     }
@@ -4133,6 +4134,47 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
   return NULL_TREE;
 }
 
+/* Handle a "externally_visible" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_externally_visible_attribute (tree *pnode, tree name,
+                                    tree ARG_UNUSED (args),
+                                    int ARG_UNUSED (flags),
+                                    bool *no_add_attrs)
+{
+  tree node = *pnode;
+
+  if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL)
+      || !TREE_PUBLIC (node))
+    {
+      warning (OPT_Wattributes,
+              "%qE attribute have effect only on public objects", name);
+      *no_add_attrs = true;
+    }
+  else if (TREE_CODE (node) == FUNCTION_DECL)
+    {
+      struct cgraph_node *n = cgraph_node (node);
+      n->local.externally_visible = true;
+      if (n->local.finalized)
+       cgraph_mark_needed_node (n);
+    }
+  else if (TREE_CODE (node) == VAR_DECL)
+    {
+      struct cgraph_varpool_node *n = cgraph_varpool_node (node);
+      n->externally_visible = true;
+      if (n->finalized)
+       cgraph_varpool_mark_needed_node (n);
+    }
+  else
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle a "const" attribute; arguments as in
    struct attribute_spec.handler.  */
 
@@ -4153,7 +4195,7 @@ handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
                             TREE_THIS_VOLATILE (TREE_TYPE (type))));
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4197,7 +4239,7 @@ handle_transparent_union_attribute (tree *node, tree name,
     DECL_TRANSPARENT_UNION (decl) = 1;
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4225,7 +4267,7 @@ handle_constructor_attribute (tree *node, tree name,
     }
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4253,7 +4295,7 @@ handle_destructor_attribute (tree *node, tree name,
     }
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4272,7 +4314,7 @@ handle_mode_attribute (tree *node, tree name, tree args,
   *no_add_attrs = true;
 
   if (TREE_CODE (TREE_VALUE (args)) != IDENTIFIER_NODE)
-    warning (0, "%qE attribute ignored", name);
+    warning (OPT_Wattributes, "%qE attribute ignored", name);
   else
     {
       int j;
@@ -4330,9 +4372,10 @@ handle_mode_attribute (tree *node, tree name, tree args,
 
        case MODE_VECTOR_INT:
        case MODE_VECTOR_FLOAT:
-         warning (0, "specifying vector types with __attribute__ ((mode)) "
-                  "is deprecated");
-         warning (0, "use __attribute__ ((vector_size)) instead");
+         warning (OPT_Wattributes, "specifying vector types with "
+                  "__attribute__ ((mode)) is deprecated");
+         warning (OPT_Wattributes,
+                  "use __attribute__ ((vector_size)) instead");
          valid_mode = vector_mode_valid_p (mode);
          break;
 
@@ -4597,7 +4640,7 @@ handle_alias_attribute (tree *node, tree name, tree args,
     }
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4621,13 +4664,14 @@ handle_visibility_attribute (tree *node, tree name, tree args,
     {
       if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
        {
-         warning (0, "%qE attribute ignored on non-class types", name);
+         warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
+                 name);
          return NULL_TREE;
        }
     }
   else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       return NULL_TREE;
     }
 
@@ -4645,7 +4689,7 @@ handle_visibility_attribute (tree *node, tree name, tree args,
         return NULL_TREE;
       if (TREE_CODE (decl) == IDENTIFIER_NODE)
        {
-          warning (0, "%qE attribute ignored on types",
+          warning (OPT_Wattributes, "%qE attribute ignored on types",
                    name);
           return NULL_TREE;
        }
@@ -4719,7 +4763,7 @@ handle_tls_model_attribute (tree *node, tree name, tree args,
 
   if (!DECL_THREAD_LOCAL (decl))
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
   else
@@ -4786,7 +4830,7 @@ handle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args),
     DECL_IS_MALLOC (*node) = 1;
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4804,7 +4848,7 @@ handle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args),
     DECL_IS_RETURNS_TWICE (*node) = 1;
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4850,7 +4894,7 @@ handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args),
   /* ??? TODO: Support types.  */
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -4918,9 +4962,9 @@ handle_deprecated_attribute (tree *node, tree name,
            what = DECL_NAME (TYPE_NAME (type));
        }
       if (what)
-       warning (0, "%qE attribute ignored for %qE", name, what);
+       warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what);
       else
-       warning (0, "%qE attribute ignored", name);
+       warning (OPT_Wattributes, "%qE attribute ignored", name);
     }
 
   return NULL_TREE;
@@ -4944,7 +4988,7 @@ handle_vector_size_attribute (tree *node, tree name, tree args,
 
   if (!host_integerp (size, 1))
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       return NULL_TREE;
     }
 
@@ -5222,7 +5266,7 @@ handle_nothrow_attribute (tree *node, tree name, tree ARG_UNUSED (args),
   /* ??? TODO: Support types.  */
   else
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -5245,7 +5289,7 @@ handle_cleanup_attribute (tree *node, tree name, tree args,
      we'd be missing too much, since we do have attribute constructor.  */
   if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl))
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
       return NULL_TREE;
     }
@@ -5284,7 +5328,7 @@ handle_warn_unused_result_attribute (tree *node, tree name,
   /* Ignore the attribute for functions not returning any value.  */
   if (VOID_TYPE_P (TREE_TYPE (*node)))
     {
-      warning (0, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
       *no_add_attrs = true;
     }
 
@@ -5301,7 +5345,8 @@ handle_sentinel_attribute (tree *node, tree name, tree args,
 
   if (!params)
     {
-      warning (0, "%qE attribute requires prototypes with named arguments", name);
+      warning (OPT_Wattributes,
+              "%qE attribute requires prototypes with named arguments", name);
       *no_add_attrs = true;
     }
   else
@@ -5311,7 +5356,8 @@ handle_sentinel_attribute (tree *node, tree name, tree args,
 
       if (VOID_TYPE_P (TREE_VALUE (params)))
         {
-         warning (0, "%qE attribute only applies to variadic functions", name);
+         warning (OPT_Wattributes,
+                  "%qE attribute only applies to variadic functions", name);
          *no_add_attrs = true;
        }
     }
@@ -5520,51 +5566,51 @@ catenate_strings (const char *lhs, const char *rhs_start, int rhs_size)
   return result;
 }
 
-/* Issue the error given by MSGID, indicating that it occurred before
+/* Issue the error given by GMSGID, indicating that it occurred before
    TOKEN, which had the associated VALUE.  */
 
 void
-c_parse_error (const char *msgid, enum cpp_ttype token, tree value)
+c_parse_error (const char *gmsgid, enum cpp_ttype token, tree value)
 {
 #define catenate_messages(M1, M2) catenate_strings ((M1), (M2), sizeof (M2))
 
   char *message = NULL;
 
   if (token == CPP_EOF)
-    message = catenate_messages (msgid, " at end of input");
+    message = catenate_messages (gmsgid, " at end of input");
   else if (token == CPP_CHAR || token == CPP_WCHAR)
     {
       unsigned int val = TREE_INT_CST_LOW (value);
       const char *const ell = (token == CPP_CHAR) ? "" : "L";
       if (val <= UCHAR_MAX && ISGRAPH (val))
-        message = catenate_messages (msgid, " before %s'%c'");
+        message = catenate_messages (gmsgid, " before %s'%c'");
       else
-        message = catenate_messages (msgid, " before %s'\\x%x'");
+        message = catenate_messages (gmsgid, " before %s'\\x%x'");
 
       error (message, ell, val);
       free (message);
       message = NULL;
     }
   else if (token == CPP_STRING || token == CPP_WSTRING)
-    message = catenate_messages (msgid, " before string constant");
+    message = catenate_messages (gmsgid, " before string constant");
   else if (token == CPP_NUMBER)
-    message = catenate_messages (msgid, " before numeric constant");
+    message = catenate_messages (gmsgid, " before numeric constant");
   else if (token == CPP_NAME)
     {
-      message = catenate_messages (msgid, " before %qE");
+      message = catenate_messages (gmsgid, " before %qE");
       error (message, value);
       free (message);
       message = NULL;
     }
   else if (token < N_TTYPES)
     {
-      message = catenate_messages (msgid, " before %qs token");
+      message = catenate_messages (gmsgid, " before %qs token");
       error (message, cpp_type2name (token));
       free (message);
       message = NULL;
     }
   else
-    error (msgid);
+    error (gmsgid);
 
   if (message)
     {
@@ -6030,4 +6076,19 @@ resolve_overloaded_builtin (tree function, tree params)
     }
 }
 
+/* Ignoring their sign, return true if two scalar types are the same.  */
+bool
+same_scalar_type_ignoring_signedness (tree t1, tree t2)
+{
+  enum tree_code c1 = TREE_CODE (t1), c2 = TREE_CODE (t2);
+
+  gcc_assert ((c1 == INTEGER_TYPE || c1 == REAL_TYPE)
+             && (c2 == INTEGER_TYPE || c2 == REAL_TYPE));
+
+  /* Equality works here because c_common_signed_type uses
+     TYPE_MAIN_VARIANT.  */
+  return lang_hooks.types.signed_type (t1)
+    == lang_hooks.types.signed_type (t2);
+}
+
 #include "gt-c-common.h"