summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-23 19:18:42 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-23 19:18:42 +0000
commitb356dfef7e02914fdff0b675eacf431c121c6e85 (patch)
treeac68df876d759f7e43bece4908413f8db399a792
parent3b1757a2f339fdc4acd5cac80e00d810cafa7b6e (diff)
downloadgcc-b356dfef7e02914fdff0b675eacf431c121c6e85.tar.gz
* builtins.c (expand_builtin, maybe_emit_chk_warning): Handle
BUILT_IN_STRNCAT_CHK. * gcc.dg/builtin-strncat-chk-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117980 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/builtins.c22
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c38
4 files changed, 69 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c304f18a473..5a6400a5fa4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2006-10-23 Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.c (expand_builtin, maybe_emit_chk_warning): Handle
+ BUILT_IN_STRNCAT_CHK.
+
2006-10-23 Jan Hubicka <jh@suse.cz>
* builtins.c (expand_builtin_memmove): Remove ORIG_EXP argument;
diff --git a/gcc/builtins.c b/gcc/builtins.c
index b2a8647b9fa..5bd927b32e8 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -6494,6 +6494,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
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);
@@ -10243,6 +10244,11 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
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;
@@ -10280,6 +10286,22 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ebbae936261..2a7f88bcae4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2006-10-23 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.dg/builtin-strncat-chk-1.c: New test.
+
2006-10-23 Jan Hubicka <jh@suse.cz>
* gcc.dg/memmove-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c b/gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c
new file mode 100644
index 00000000000..80d7b9d6ebf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c
@@ -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" } */
+}