94 lines
2.7 KiB
Diff
94 lines
2.7 KiB
Diff
2006-09-18 Jakub Jelinek <jakub@redhat.com>
|
|
|
|
* builtins.c (expand_builtin, maybe_emit_chk_warning): Handle
|
|
BUILT_IN_STRNCAT_CHK.
|
|
|
|
* gcc.dg/builtin-strncat-chk-1.c: New test.
|
|
|
|
--- gcc/builtins.c.jj 2006-09-02 08:54:22.000000000 +0200
|
|
+++ gcc/builtins.c 2006-09-18 16:54:57.000000000 +0200
|
|
@@ -6437,6 +6437,7 @@ expand_builtin (tree exp, rtx target, rt
|
|
case BUILT_IN_STPCPY_CHK:
|
|
case BUILT_IN_STRNCPY_CHK:
|
|
case BUILT_IN_STRCAT_CHK:
|
|
+ case BUILT_IN_STRNCAT_CHK:
|
|
case BUILT_IN_SNPRINTF_CHK:
|
|
case BUILT_IN_VSNPRINTF_CHK:
|
|
maybe_emit_chk_warning (exp, fcode);
|
|
@@ -10128,6 +10129,11 @@ maybe_emit_chk_warning (tree exp, enum b
|
|
arg_mask = 6;
|
|
is_strlen = 1;
|
|
break;
|
|
+ case BUILT_IN_STRNCAT_CHK:
|
|
+ /* For __strncat_chk the warning will be emitted only if overflowing
|
|
+ by at least strlen (dest) + 1 bytes. */
|
|
+ arg_mask = 12;
|
|
+ break;
|
|
case BUILT_IN_STRNCPY_CHK:
|
|
arg_mask = 12;
|
|
break;
|
|
@@ -10165,6 +10171,22 @@ maybe_emit_chk_warning (tree exp, enum b
|
|
if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
|
|
return;
|
|
}
|
|
+ else if (fcode == BUILT_IN_STRNCAT_CHK)
|
|
+ {
|
|
+ tree src = TREE_VALUE (TREE_CHAIN (arglist));
|
|
+ if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
|
|
+ return;
|
|
+ src = c_strlen (src, 1);
|
|
+ if (! src || ! host_integerp (src, 1))
|
|
+ {
|
|
+ locus = EXPR_LOCATION (exp);
|
|
+ warning (0, "%Hcall to %D might overflow destination buffer",
|
|
+ &locus, get_callee_fndecl (exp));
|
|
+ return;
|
|
+ }
|
|
+ else if (tree_int_cst_lt (src, size))
|
|
+ return;
|
|
+ }
|
|
else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
|
|
return;
|
|
|
|
--- gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c.jj 2006-09-18 13:07:54.000000000 +0200
|
|
+++ gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c 2006-09-18 16:55:09.000000000 +0200
|
|
@@ -0,0 +1,38 @@
|
|
+/* Test whether buffer overflow warnings for __strncat_chk builtin
|
|
+ are emitted properly. */
|
|
+/* { dg-do compile } */
|
|
+/* { dg-options "-O2 -std=gnu99" } */
|
|
+
|
|
+extern void abort (void);
|
|
+
|
|
+#include "../gcc.c-torture/execute/builtins/chk.h"
|
|
+
|
|
+char buf1[20];
|
|
+char *q;
|
|
+
|
|
+void
|
|
+test (int arg, ...)
|
|
+{
|
|
+ char *p = &buf1[10];
|
|
+
|
|
+ *p = 0;
|
|
+ strncat (p, "abcdefg", 9);
|
|
+ *p = 0;
|
|
+ strncat (p, "abcdefghi", 9);
|
|
+ *p = 0;
|
|
+ strncat (p, "abcdefghij", 9);
|
|
+ *p = 0;
|
|
+ strncat (p, "abcdefghi", 10);
|
|
+ *p = 0;
|
|
+ strncat (p, "abcdefghij", 10); /* { dg-warning "will always overflow" } */
|
|
+ *p = 0;
|
|
+ strncat (p, "abcdefgh", 11);
|
|
+ *p = 0;
|
|
+ strncat (p, "abcdefghijkl", 11); /* { dg-warning "will always overflow" } */
|
|
+ *p = 0;
|
|
+ strncat (p, q, 9);
|
|
+ *p = 0;
|
|
+ strncat (p, q, 10); /* { dg-warning "might overflow" } */
|
|
+ *p = 0;
|
|
+ strncat (p, q, 11); /* { dg-warning "might overflow" } */
|
|
+}
|