aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2018-09-17 15:12:12 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2018-09-17 15:12:12 +0200
commit80c6d1f4463b5a848451513d788d38bb366dbefb (patch)
tree829a703a921957e67d4691d0a217fb0560e7c5aa /gcc
parent3ab3a92e8ee19d942c89b0feb99f7a10bde794a8 (diff)
downloadgcc-80c6d1f4463b5a848451513d788d38bb366dbefb.zip
gcc-80c6d1f4463b5a848451513d788d38bb366dbefb.tar.gz
gcc-80c6d1f4463b5a848451513d788d38bb366dbefb.tar.bz2
Add -Wabsolute-value
2018-09-17 Martin Jambor <mjambor@suse.cz> gcc/ * doc/invoke.texi (Warning Options): Likewise. gcc/c-family/ * c.opt (Wabsolute-value): New. gcc/c/ * c-parser.c: (warn_for_abs): New function. (c_parser_postfix_expression_after_primary): Call it. testsuite/ * gcc.dg/warn-abs-1.c: New test. * gcc.dg/dfp/warn-abs-2.c: Likewise. From-SVN: r264368
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-parser.c156
-rw-r--r--gcc/doc/invoke.texi8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/warn-abs-2.c28
-rw-r--r--gcc/testsuite/gcc.dg/warn-abs-1.c67
9 files changed, 279 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 738f0c3..f653d66 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2018-09-17 Martin Jambor <mjambor@suse.cz>
+
+ PR c/63886
+ * doc/invoke.texi (Warning Options): Likewise.
+
2018-09-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/87301
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 75064a2..b299ad2 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,8 @@
+2018-09-17 Martin Jambor <mjambor@suse.cz>
+
+ PR c/63886
+ * c.opt (Wabsolute-value): New.
+
2018-09-06 Bernd Edlinger <bernd.edlinger@hotmail.de>
* c-common.c (complete_flexible_array_elts): New helper function.
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 31a2b97..092ec94 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -271,6 +271,10 @@ Warn if a subobject has an abi_tag attribute that the complete object type does
Wpsabi
C ObjC C++ ObjC++ LTO Var(warn_psabi) Init(1) Warning Undocumented LangEnabledBy(C ObjC C++ ObjC++,Wabi)
+Wabsolute-value
+C ObjC Var(warn_absolute_value) Warning EnabledBy(Wextra)
+Warn on suspicious calls of standard functions computing absolute values.
+
Waddress
C ObjC C++ ObjC++ Var(warn_address) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn about suspicious uses of memory addresses.
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index c28fb1c..3133ca6 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-17 Martin Jambor <mjambor@suse.cz>
+
+ PR c/63886
+ * c-parser.c: (warn_for_abs): New function.
+ (c_parser_postfix_expression_after_primary): Call it.
+
2018-09-13 Bernd Edlinger <bernd.edlinger@hotmail.de>
* c-typeck.c (digest_init): Shorten overlength strings.
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 69ed5ae..1766a25 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -9101,6 +9101,144 @@ sizeof_ptr_memacc_comptypes (tree type1, tree type2)
return comptypes (type1, type2) == 1;
}
+/* Warn for patterns where abs-like function appears to be used incorrectly,
+ gracely ignore any non-abs-like function. The warning location should be
+ LOC. FNDECL is the declaration of called function, it must be a
+ BUILT_IN_NORMAL function. ARG is the first and only argument of the
+ call. */
+
+static void
+warn_for_abs (location_t loc, tree fndecl, tree arg)
+{
+ tree atype = TREE_TYPE (arg);
+
+ /* Casts from pointers (and thus arrays and fndecls) will generate
+ -Wint-conversion warnings. Most other wrong types hopefully lead to type
+ mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
+ types and possibly other exotic types. */
+ if (!INTEGRAL_TYPE_P (atype)
+ && !SCALAR_FLOAT_TYPE_P (atype)
+ && TREE_CODE (atype) != COMPLEX_TYPE)
+ return;
+
+ enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+
+ switch (fcode)
+ {
+ case BUILT_IN_ABS:
+ case BUILT_IN_LABS:
+ case BUILT_IN_LLABS:
+ case BUILT_IN_IMAXABS:
+ if (!INTEGRAL_TYPE_P (atype))
+ {
+ if (SCALAR_FLOAT_TYPE_P (atype))
+ warning_at (loc, OPT_Wabsolute_value,
+ "using integer absolute value function %qD when "
+ "argument is of floating point type %qT",
+ fndecl, atype);
+ else if (TREE_CODE (atype) == COMPLEX_TYPE)
+ warning_at (loc, OPT_Wabsolute_value,
+ "using integer absolute value function %qD when "
+ "argument is of complex type %qT", fndecl, atype);
+ else
+ gcc_unreachable ();
+ return;
+ }
+ if (TYPE_UNSIGNED (atype))
+ warning_at (loc, OPT_Wabsolute_value,
+ "taking the absolute value of unsigned type %qT "
+ "has no effect", atype);
+ break;
+
+ CASE_FLT_FN (BUILT_IN_FABS):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
+ if (!SCALAR_FLOAT_TYPE_P (atype)
+ || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
+ {
+ if (INTEGRAL_TYPE_P (atype))
+ warning_at (loc, OPT_Wabsolute_value,
+ "using floating point absolute value function %qD "
+ "when argument is of integer type %qT", fndecl, atype);
+ else if (DECIMAL_FLOAT_TYPE_P (atype))
+ warning_at (loc, OPT_Wabsolute_value,
+ "using floating point absolute value function %qD "
+ "when argument is of decimal floating point type %qT",
+ fndecl, atype);
+ else if (TREE_CODE (atype) == COMPLEX_TYPE)
+ warning_at (loc, OPT_Wabsolute_value,
+ "using floating point absolute value function %qD when "
+ "argument is of complex type %qT", fndecl, atype);
+ else
+ gcc_unreachable ();
+ return;
+ }
+ break;
+
+ CASE_FLT_FN (BUILT_IN_CABS):
+ if (TREE_CODE (atype) != COMPLEX_TYPE)
+ {
+ if (INTEGRAL_TYPE_P (atype))
+ warning_at (loc, OPT_Wabsolute_value,
+ "using complex absolute value function %qD when "
+ "argument is of integer type %qT", fndecl, atype);
+ else if (SCALAR_FLOAT_TYPE_P (atype))
+ warning_at (loc, OPT_Wabsolute_value,
+ "using complex absolute value function %qD when "
+ "argument is of floating point type %qT",
+ fndecl, atype);
+ else
+ gcc_unreachable ();
+
+ return;
+ }
+ break;
+
+ case BUILT_IN_FABSD32:
+ case BUILT_IN_FABSD64:
+ case BUILT_IN_FABSD128:
+ if (!DECIMAL_FLOAT_TYPE_P (atype))
+ {
+ if (INTEGRAL_TYPE_P (atype))
+ warning_at (loc, OPT_Wabsolute_value,
+ "using decimal floating point absolute value "
+ "function %qD when argument is of integer type %qT",
+ fndecl, atype);
+ else if (SCALAR_FLOAT_TYPE_P (atype))
+ warning_at (loc, OPT_Wabsolute_value,
+ "using decimal floating point absolute value "
+ "function %qD when argument is of floating point "
+ "type %qT", fndecl, atype);
+ else if (TREE_CODE (atype) == COMPLEX_TYPE)
+ warning_at (loc, OPT_Wabsolute_value,
+ "using decimal floating point absolute value "
+ "function %qD when argument is of complex type %qT",
+ fndecl, atype);
+ else
+ gcc_unreachable ();
+ return;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
+ if (TREE_CODE (atype) == COMPLEX_TYPE)
+ {
+ gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
+ atype = TREE_TYPE (atype);
+ ftype = TREE_TYPE (ftype);
+ }
+
+ if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
+ warning_at (loc, OPT_Wabsolute_value,
+ "absolute value function %qD given an argument of type %qT "
+ "but has parameter of type %qT which may cause truncation "
+ "of value", fndecl, atype, ftype);
+}
+
+
/* Parse a postfix expression after the initial primary or compound
literal; that is, parse a series of postfix operators.
@@ -9165,13 +9303,19 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
expr.value, exprlist,
sizeof_arg,
sizeof_ptr_memacc_comptypes);
- if (TREE_CODE (expr.value) == FUNCTION_DECL
- && fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
- && vec_safe_length (exprlist) == 3)
+ if (TREE_CODE (expr.value) == FUNCTION_DECL)
{
- tree arg0 = (*exprlist)[0];
- tree arg2 = (*exprlist)[2];
- warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
+ if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
+ && vec_safe_length (exprlist) == 3)
+ {
+ tree arg0 = (*exprlist)[0];
+ tree arg2 = (*exprlist)[2];
+ warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
+ }
+ if (warn_absolute_value
+ && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
+ && vec_safe_length (exprlist) == 1)
+ warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
}
start = expr.get_start ();
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ec12711..94304c3 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6281,6 +6281,14 @@ example, warn if an unsigned variable is compared against zero with
@code{<} or @code{>=}. This warning is also enabled by
@option{-Wextra}.
+@item -Wabsolute-value @r{(C and Objective-C only)}
+@opindex Wabsolute-value
+@opindex Wno-absolute-value
+Warn when a wrong absolute value function seems to be used or when it
+does not have any effect because its argument is an unsigned type.
+This warning be suppressed with an explicit type cast and it is also
+enabled by @option{-Wextra}.
+
@include cppwarnopts.texi
@item -Wbad-function-cast @r{(C and Objective-C only)}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2e7c878..4fd1ff9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-17 Martin Jambor <mjambor@suse.cz>
+
+ PR c/63886
+ * gcc.dg/warn-abs-1.c: New test.
+ * gcc.dg/dfp/warn-abs-2.c: Likewise.
+
2018-09-17 Bernd Edlinger <bernd.edlinger@hotmail.de>
* gcc.target/x86_64/abi/ms-sysv/ms-sysv.exp: Don't pass
diff --git a/gcc/testsuite/gcc.dg/dfp/warn-abs-2.c b/gcc/testsuite/gcc.dg/dfp/warn-abs-2.c
new file mode 100644
index 0000000..c1a1994
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/warn-abs-2.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-Wabsolute-value" } */
+
+#include <stdlib.h>
+#include <complex.h>
+#include <math.h>
+
+void tst_decimal (_Decimal32 *p32, _Decimal64 *p64, _Decimal128 *p128)
+{
+ *p32 = abs(*p32); /* { dg-warning "using integer absolute value function" } */
+ *p64 = fabs(*p64); /* { dg-warning "using floating point absolute value function" } */
+ *p128 = cabsl(*p128); /* { dg-warning "using complex absolute value function" } */
+}
+
+void tst_notdecimal (int *pi, double *pd, long double *pld, complex double *pc)
+{
+ *pi = __builtin_fabsd32 (*pi); /* { dg-warning "using decimal floating point absolute value function" } */
+ *pd = __builtin_fabsd64 (*pd); /* { dg-warning "using decimal floating point absolute value function" } */
+ *pld = __builtin_fabsd64 (*pld); /* { dg-warning "using decimal floating point absolute value function" } */
+ *pc = __builtin_fabsd128 (*pc); /* { dg-warning "using decimal floating point absolute value function" } */
+}
+
+void
+test_size (_Decimal64 *p64, _Decimal128 *p128)
+{
+ *p64 = __builtin_fabsd32 (*p64); /* { dg-warning "may cause truncation of value" } */
+ *p128 = __builtin_fabsd64 (*p128); /* { dg-warning "may cause truncation of value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/warn-abs-1.c b/gcc/testsuite/gcc.dg/warn-abs-1.c
new file mode 100644
index 0000000..6aa937c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/warn-abs-1.c
@@ -0,0 +1,67 @@
+/* { dg-do compile } */
+/* { dg-options "-Wabsolute-value" } */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <math.h>
+#include <complex.h>
+
+void
+tst_unsigned (unsigned *pu, unsigned long *pl, unsigned long long *pll,
+ uintmax_t *pm)
+{
+ *pu = abs (*pu); /* { dg-warning "taking the absolute value of unsigned type" } */
+ *pl = labs (*pl); /* { dg-warning "taking the absolute value of unsigned type" } */
+ *pll = llabs (*pll); /* { dg-warning "taking the absolute value of unsigned type" } */
+ *pm = imaxabs (*pm); /* { dg-warning "taking the absolute value of unsigned type" } */
+}
+
+void
+test_int_size (long long *pll)
+{
+ *pll = abs (*pll); /* { dg-warning "may cause truncation of value" } */
+ *pll = abs ((int) *pll);
+}
+
+void
+tst_notint (float *pf, double *pd, _Complex double *pc)
+{
+ *pf = abs (*pf); /* { dg-warning "using integer absolute value function" } */
+ *pd = labs (*pd); /* { dg-warning "using integer absolute value function" } */
+ *pc = abs (*pc); /* { dg-warning "using integer absolute value function" } */
+}
+
+void
+tst_notfloat (int *pi, long *pl, complex double *pc)
+{
+ *pi = fabsf (*pi); /* { dg-warning "using floating point absolute value function" } */
+ *pl = fabs (*pl); /* { dg-warning "using floating point absolute value function" } */
+ *pc = fabs (*pc); /* { dg-warning "using floating point absolute value function" } */
+}
+
+void
+tst_float_size (double *pd, long double *pld, _Float128 *pf128)
+{
+ *pd = fabsf (*pd); /* { dg-warning "may cause truncation of value" } */
+ *pld = fabs (*pld); /* { dg-warning "may cause truncation of value" } */
+ *pld = fabs ((double) *pld);
+ *pf128 = fabsl (*pf128); /* { dg-warning "may cause truncation of value" } */
+}
+
+void tst_notcomplex (int *pi, long *pl, long double *pld)
+{
+ *pi = cabs (*pi); /* { dg-warning "using complex absolute value function" } */
+ *pl = cabs (*pl); /* { dg-warning "using complex absolute value function" } */
+ *pld = cabsl (*pld);/* { dg-warning "using complex absolute value function" } */
+}
+
+void tst_cplx_size (complex double *pcd, complex long double *pcld)
+{
+ *pcd = cabsf (*pcd); /* { dg-warning "may cause truncation of value" } */
+ *pcld = cabs (*pcld); /* { dg-warning "may cause truncation of value" } */
+ *pcld = cabs ((complex double) *pcld);
+}
+
+
+
+