]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/12242 (g++ should warn about out-of-range int->enum conversions)
authorManuel López-Ibáñez <manu@gcc.gnu.org>
Sat, 9 Aug 2008 00:30:41 +0000 (00:30 +0000)
committerManuel López-Ibáñez <manu@gcc.gnu.org>
Sat, 9 Aug 2008 00:30:41 +0000 (00:30 +0000)
2008-08-09  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

PR c++/12242
cp/
* cvt.c (ocp_convert): Warn for out-of-range conversions to enum.

testsuite/
* g++.dg/warn/pr12242.C: New.

From-SVN: r138898

gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/pr12242.C [new file with mode: 0644]

index 8fd884285670a2f7f08986cd130bf16220ddad54..bd8821cf7a76996450f6104b50d630dadd8ab4d2 100644 (file)
@@ -1,3 +1,8 @@
+2008-08-09  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR c++/12242
+       * cvt.c (ocp_convert): Warn for out-of-range conversions to enum.
+
 2008-08-09  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR 36901
index 3ee3ba7956bb9cb170f2f9e97c204108733e9d46..8e26927c373f0c589c7dcdb760f9b89d3e3bf3c0 100644 (file)
@@ -638,19 +638,35 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
   if (INTEGRAL_CODE_P (code))
     {
       tree intype = TREE_TYPE (e);
-      /* enum = enum, enum = int, enum = float, (enum)pointer are all
-        errors.  */
-      if (TREE_CODE (type) == ENUMERAL_TYPE
-         && (((INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
+
+      if (TREE_CODE (type) == ENUMERAL_TYPE)
+       {
+         /* enum = enum, enum = int, enum = float, (enum)pointer are all
+            errors.  */
+         if (((INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
                || TREE_CODE (intype) == REAL_TYPE)
               && ! (convtype & CONV_STATIC))
-             || TREE_CODE (intype) == POINTER_TYPE))
-       {
-         if (flags & LOOKUP_COMPLAIN)
-           permerror ("conversion from %q#T to %q#T", intype, type);
+             || TREE_CODE (intype) == POINTER_TYPE)
+           {
+             if (flags & LOOKUP_COMPLAIN)
+               permerror ("conversion from %q#T to %q#T", intype, type);
 
-         if (!flag_permissive)
-           return error_mark_node;
+             if (!flag_permissive)
+               return error_mark_node;
+           }
+
+         /* [expr.static.cast]
+
+            8. A value of integral or enumeration type can be explicitly
+            converted to an enumeration type. The value is unchanged if
+            the original value is within the range of the enumeration
+            values. Otherwise, the resulting enumeration value is
+            unspecified.  */
+         if (TREE_CODE (expr) == INTEGER_CST && !int_fits_type_p (expr, type))
+           warning (OPT_Wconversion, 
+                    "the result of the conversion is unspecified because "
+                    "%qE is outside the range of type %qT",
+                    expr, type);
        }
       if (MAYBE_CLASS_TYPE_P (intype))
        {
index 2603ac27521928095f46f4506ae6f7e22392a412..31b271e94d0f5f8f12acbd179e614091519e5172 100644 (file)
@@ -1,3 +1,8 @@
+2008-08-09  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR c++/12242
+       * g++.dg/warn/pr12242.C: New.
+       
 2008-08-09  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR 36901
diff --git a/gcc/testsuite/g++.dg/warn/pr12242.C b/gcc/testsuite/g++.dg/warn/pr12242.C
new file mode 100644 (file)
index 0000000..db4cc10
--- /dev/null
@@ -0,0 +1,57 @@
+// PR 12242: should warn about out-of-range int->enum conversions
+// { dg-do compile }
+// { dg-options "-Wconversion -fpermissive" }
+enum X { A };
+enum Y { B, C, D };
+
+void example ()
+{
+  int i = 5;
+  X x;
+  Y y;
+  
+  x = 10;  // { dg-warning "warning: invalid conversion from .int. to .X." }
+           // { dg-warning "warning:\[^\n\]*unspecified" "" { target *-*-* } 13 }
+  x = 1;   // { dg-warning "warning: invalid conversion from .int. to .X." }
+  x = C;   // { dg-error "error: cannot convert .Y. to .X. in assignment" }  
+  x = D;   // { dg-error "error: cannot convert .Y. to .X. in assignment" }  
+  y = A;   // { dg-error "error: cannot convert .X. to .Y. in assignment" }  
+  x = y;   // { dg-error "error: cannot convert .Y. to .X. in assignment" }  
+  x = i;   // { dg-warning "warning: invalid conversion from .int. to .X."  }
+}
+
+void foo () 
+{
+  X a = static_cast<X> (10); // { dg-warning "warning:\[^\n\]*unspecified" }
+  X b = static_cast<X> (0);
+  X c = static_cast<X> (1);
+  X d = static_cast<X> (2); // { dg-warning "warning:\[^\n\]*unspecified" }
+  X f = static_cast<X> ((int)A);
+  X g = static_cast<X> (B);
+  X h = static_cast<X> (C);
+  X e = static_cast<X> (D); // { dg-warning "warning\[^\n\]*unspecified" }
+}
+
+enum QEvent { x = 42 }; 
+int bar()
+{ 
+  QEvent x = ( QEvent ) 42000; // { dg-warning "warning\[^\n\]*unspecified" }
+  return ( int ) x; 
+}
+
+enum W {a,b,c};
+enum Z {d,e,f,g};
+void bazz (int, int, int, int);
+
+void baz() {
+  int three = 3;
+  int four = 4;
+  bazz (
+       W(three), 
+       W(3), 
+       Z(four), 
+       Z(4) // { dg-warning "warning\[^\n\]*unspecified" }
+       );
+}
+