summaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authormanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>2007-05-19 13:32:03 +0000
committermanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>2007-05-19 13:32:03 +0000
commit7ee0d2277e23c2e52f6d6929708039e4aac9b153 (patch)
tree98d10e457cbf659848ab680b6b1b3e192890e140 /gcc/c-common.c
parentdf3d6232299393f4c995d54e13ae47611bc8d823 (diff)
downloadgcc-7ee0d2277e23c2e52f6d6929708039e4aac9b153.tar.gz
2007-05-19 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
* doc/invoke.texi (Warning Options): Add -Wconversion-sign. (Wconversion): Update description. (Wconversion-sign): New. * c.opt (Wconversion-sign): New. * c-opts.c (c_common_post_options): Uninitialized Wconversion-sign means disabled for C++. Otherwise, take the status of Wconversion. * c-common.c (conversion_warning): Warn with either Wconversion or Wconversion-sign. (warnings_for_convert_and_check): Conditions are already checked by conversion_warning. (convert_and_check): Don't check warnings if the conversion failed. cp/ * cvt.c (cp_convert_and_check): Don't check warnings if the conversion failed. testsuite/ * gcc.dg/Wconversion-integer.c: Group testcases and add more. * gcc.dg/Wconversion-sign.c: New. * gcc.dg/Wconversion-integer-no-sign.c: New. * g++.dg/warn/Wconversion-integer.C: Move some warnings to Wconversion-sign.C * g++.dg/warn/Wconversion-sign.C: New. * g++.old-deja/g++.other/warn4.C: Update. * g++.dg/warn/Wconversion1.C: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124856 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 6aa5e642c9b..1026499df52 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -1204,6 +1204,9 @@ conversion_warning (tree type, tree expr)
unsigned int formal_prec = TYPE_PRECISION (type);
+ if (!warn_conversion && !warn_sign_conversion)
+ return;
+
if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST)
{
/* Warn for real constant that is not an exact integer converted
@@ -1220,10 +1223,13 @@ conversion_warning (tree type, tree expr)
&& !int_fits_type_p (expr, type))
{
if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (TREE_TYPE (expr)))
- warning (OPT_Wconversion,
- "negative integer implicitly converted to unsigned type");
- else
- give_warning = true;
+ warning (OPT_Wsign_conversion,
+ "negative integer implicitly converted to unsigned type");
+ else if (!TYPE_UNSIGNED (type) && TYPE_UNSIGNED (TREE_TYPE (expr)))
+ warning (OPT_Wsign_conversion,
+ "conversion of unsigned constant value to negative integer");
+ else
+ give_warning = true;
}
else if (TREE_CODE (type) == REAL_TYPE)
{
@@ -1261,16 +1267,20 @@ conversion_warning (tree type, tree expr)
&& TREE_CODE (type) == INTEGER_TYPE)
{
/* Warn for integer types converted to smaller integer types. */
- if (formal_prec < TYPE_PRECISION (TREE_TYPE (expr))
- /* When they are the same width but different signedness,
- then the value may change. */
- || (formal_prec == TYPE_PRECISION (TREE_TYPE (expr))
- && TYPE_UNSIGNED (TREE_TYPE (expr)) != TYPE_UNSIGNED (type))
- /* Even when converted to a bigger type, if the type is
- unsigned but expr is signed, then negative values
- will be changed. */
- || (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (TREE_TYPE (expr))))
- give_warning = true;
+ if (formal_prec < TYPE_PRECISION (TREE_TYPE (expr)))
+ give_warning = true;
+
+ /* When they are the same width but different signedness,
+ then the value may change. */
+ else if ((formal_prec == TYPE_PRECISION (TREE_TYPE (expr))
+ && TYPE_UNSIGNED (TREE_TYPE (expr)) != TYPE_UNSIGNED (type))
+ /* Even when converted to a bigger type, if the type is
+ unsigned but expr is signed, then negative values
+ will be changed. */
+ || (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (TREE_TYPE (expr))))
+ warning (OPT_Wsign_conversion,
+ "conversion to %qT from %qT may change the sign of the result",
+ type, TREE_TYPE (expr));
}
/* Warn for integer types converted to real types if and only if
@@ -1327,7 +1337,7 @@ warnings_for_convert_and_check (tree type, tree expr, tree result)
if (!int_fits_type_p (expr, c_common_signed_type (type)))
warning (OPT_Woverflow,
"large integer implicitly truncated to unsigned type");
- else if (warn_conversion)
+ else
conversion_warning (type, expr);
}
else if (!int_fits_type_p (expr, unsigned_type_for (type)))
@@ -1341,13 +1351,13 @@ warnings_for_convert_and_check (tree type, tree expr, tree result)
warning (OPT_Woverflow,
"overflow in implicit constant conversion");
- else if (warn_conversion)
+ else
conversion_warning (type, expr);
}
else if (TREE_CODE (result) == INTEGER_CST && TREE_OVERFLOW (result))
warning (OPT_Woverflow,
"overflow in implicit constant conversion");
- else if (warn_conversion)
+ else
conversion_warning (type, expr);
}
@@ -1366,7 +1376,7 @@ convert_and_check (tree type, tree expr)
result = convert (type, expr);
- if (!skip_evaluation && !TREE_OVERFLOW_P (expr))
+ if (!skip_evaluation && !TREE_OVERFLOW_P (expr) && result != error_mark_node)
warnings_for_convert_and_check (type, expr, result);
return result;