OSDN Git Service

* typeck.c (build_binary_op): Issue warning if either operand of a
[pf3gnuchains/gcc-fork.git] / gcc / cp / typeck.c
index a7edfc1..0cae938 100644 (file)
@@ -107,12 +107,18 @@ complete_type (tree type)
   else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
     {
       tree t = complete_type (TREE_TYPE (type));
+      unsigned int needs_constructing, has_nontrivial_dtor;
       if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
        layout_type (type);
-      TYPE_NEEDS_CONSTRUCTING (type)
+      needs_constructing
        = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
-      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+      has_nontrivial_dtor
        = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
+      for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+       {
+         TYPE_NEEDS_CONSTRUCTING (t) = needs_constructing;
+         TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = has_nontrivial_dtor;
+       }
     }
   else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
     instantiate_class_template (TYPE_MAIN_VARIANT (type));
@@ -1858,7 +1864,7 @@ check_template_keyword (tree decl)
      DR 228 removed the restriction that the template be a member
      template.  
      
-     DR 96, if accepted would add the further restriction that explcit
+     DR 96, if accepted would add the further restriction that explicit
      template arguments must be provided if the template keyword is
      used, but, as of 2005-10-16, that DR is still in "drafting".  If
      this DR is accepted, then the semantic checks here can be
@@ -2247,15 +2253,7 @@ build_array_ref (tree array, tree idx)
     {
       tree rval, type;
 
-      /* Subscripting with type char is likely to lose
-        on a machine where chars are signed.
-        So warn on any machine, but optionally.
-        Don't warn for unsigned char since that type is safe.
-        Don't warn for signed char because anyone who uses that
-        must have done so deliberately.  */
-      if (warn_char_subscripts
-         && TYPE_MAIN_VARIANT (TREE_TYPE (idx)) == char_type_node)
-       warning (0, "array subscript has type %<char%>");
+      warn_array_subscript_with_type_char (idx);
 
       if (!INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
        {
@@ -3091,6 +3089,10 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
     case NE_EXPR:
       if (warn_float_equal && (code0 == REAL_TYPE || code1 == REAL_TYPE))
        warning (0, "comparing floating point with == or != is unsafe");
+      if ((TREE_CODE (orig_op0) == STRING_CST && !integer_zerop (op1))
+         || (TREE_CODE (orig_op1) == STRING_CST && !integer_zerop (op0)))
+       warning (OPT_Wstring_literal_comparison,
+                "comparison with string literal");
 
       build_type = boolean_type_node;
       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
@@ -3196,6 +3198,11 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
     case GE_EXPR:
     case LT_EXPR:
     case GT_EXPR:
+      if (TREE_CODE (orig_op0) == STRING_CST
+         || TREE_CODE (orig_op1) == STRING_CST)
+       warning (OPT_Wstring_literal_comparison,
+                "comparison with string literal");
+
       build_type = boolean_type_node;
       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
           && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
@@ -3690,7 +3697,7 @@ build_x_unary_op (enum tree_code code, tree xarg)
            }
          else
            {
-             error ("parenthesis around %qE cannot be used to form a"
+             error ("parentheses around %qE cannot be used to form a"
                     " pointer-to-member-function",
                     xarg);
              PTRMEM_OK_P (xarg) = 1;
@@ -4553,8 +4560,8 @@ check_for_casting_away_constness (tree src_type, tree dest_type,
                                  const char *description)
 {
   if (diag_fn && casts_away_constness (src_type, dest_type))
-    error ("%s from type %qT to type %qT casts away constness",
-          description, src_type, dest_type);
+    diag_fn ("%s from type %qT to type %qT casts away constness",
+            description, src_type, dest_type);
 }
 
 /* Convert EXPR (an expression with pointer-to-member type) to TYPE
@@ -5013,6 +5020,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
   else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
           || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
     {
+      tree sexpr = expr;
+
       if (!c_cast_p)
        check_for_casting_away_constness (intype, type, error,
                                          "reinterpret_cast");
@@ -5027,6 +5036,11 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
                 "target type",
                 intype, type);
 
+      /* We need to strip nops here, because the frontend likes to
+        create (int *)&a for array-to-pointer decay, instead of &a[0].  */
+      STRIP_NOPS (sexpr);
+      strict_aliasing_warning (intype, type, sexpr);
+
       return fold_if_not_in_template (build_nop (type, expr));
     }
   else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
@@ -5079,9 +5093,9 @@ build_reinterpret_cast (tree type, tree expr)
 /* Perform a const_cast from EXPR to TYPE.  If the cast is valid,
    return an appropriate expression.  Otherwise, return
    error_mark_node.  If the cast is not valid, and COMPLAIN is true,
-   then a diagnostic will be issued.  If VALID_P is non-NULL, its
-   value upon return will indicate whether or not the conversion
-   succeeded.  */
+   then a diagnostic will be issued.  If VALID_P is non-NULL, we are
+   performing a C-style cast, its value upon return will indicate
+   whether or not the conversion succeeded.  */
 
 static tree
 build_const_cast_1 (tree dst_type, tree expr, bool complain,
@@ -5157,7 +5171,15 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain,
       && comp_ptr_ttypes_const (dst_type, src_type))
     {
       if (valid_p)
-       *valid_p = true;
+       {
+         *valid_p = true;
+         /* This cast is actually a C-style cast.  Issue a warning if
+            the user is making a potentially unsafe cast.  */
+         if (warn_cast_qual)
+           check_for_casting_away_constness (src_type, dst_type,
+                                             warning0,
+                                             "cast");
+       }
       if (reference_type)
        {
          expr = build_unary_op (ADDR_EXPR, expr, 0);