This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix -fsanitize=undefined with PCH (PR sanitizer/66343)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>, Marek Polacek <polacek at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 5 Oct 2016 17:25:23 +0200
- Subject: [PATCH] Fix -fsanitize=undefined with PCH (PR sanitizer/66343)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
As mentioned in the PR, ubsan.c uses ASM_GENERATE_INTERNAL_LABEL with
static counters that aren't registered with GC, and those functions can be
called already during parsing, so we can get clashes between labels
created during PCH creation and labels created afterwards.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?
2016-10-05 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/66343
* ubsan.c (ubsan_ids): New GTY(()) array.
(ubsan_type_descriptor, ubsan_create_data): Use ubsan_ids
instead of static local counters.
* gcc.dg/pch/pr66343-1.c: New test.
* gcc.dg/pch/pr66343-1.hs: New file.
* gcc.dg/pch/pr66343-2.c: New test.
* gcc.dg/pch/pr66343-2.hs: New file.
--- gcc/ubsan.c.jj 2016-09-05 09:46:33.000000000 +0200
+++ gcc/ubsan.c 2016-10-05 11:59:04.650214079 +0200
@@ -314,6 +314,10 @@ get_ubsan_type_info_for_type (tree type)
return 0;
}
+/* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
+ ubsan_ids[1] for Lubsan_data labels. */
+static GTY(()) unsigned int ubsan_ids[2];
+
/* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
descriptor. It first looks into the hash table; if not found,
create the VAR_DECL, put it into the hash table and return the
@@ -461,10 +465,9 @@ ubsan_type_descriptor (tree type, enum u
TREE_STATIC (str) = 1;
char tmp_name[32];
- static unsigned int type_var_id_num;
- ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
+ ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
- dtype);
+ dtype);
TREE_STATIC (decl) = 1;
TREE_PUBLIC (decl) = 0;
DECL_ARTIFICIAL (decl) = 1;
@@ -564,8 +567,7 @@ ubsan_create_data (const char *name, int
/* Now, fill in the type. */
char tmp_name[32];
- static unsigned int ubsan_var_id_num;
- ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
+ ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
ret);
TREE_STATIC (var) = 1;
--- gcc/testsuite/gcc.dg/pch/pr66343-1.c.jj 2016-10-05 12:00:38.000000000 +0200
+++ gcc/testsuite/gcc.dg/pch/pr66343-1.c 2016-10-05 12:30:44.134995415 +0200
@@ -0,0 +1,15 @@
+/* PR sanitizer/66343 */
+/* { dg-do assemble } */
+/* { dg-options "-fsanitize=undefined" } */
+
+#include "pr66343-1.h"
+
+void
+bar (int a, int b)
+{
+ a / b;
+}
+
+/* Hack to turn off PCH assembly comparison, as it is incompatible
+ with dg-do assemble. The target condition will be always false. */
+/* { dg-error "" "" { target { lp64 && { ! lp64 } } } } */
--- gcc/testsuite/gcc.dg/pch/pr66343-1.hs.jj 2016-10-05 12:07:27.845784413 +0200
+++ gcc/testsuite/gcc.dg/pch/pr66343-1.hs 2016-10-05 12:11:25.498754049 +0200
@@ -0,0 +1,8 @@
+/* PR sanitizer/66343 */
+/* { dg-options "-fsanitize=undefined" } */
+
+void
+foo (int a, int b)
+{
+ a / b;
+}
--- gcc/testsuite/gcc.dg/pch/pr66343-2.c.jj 2016-10-05 12:31:27.569443302 +0200
+++ gcc/testsuite/gcc.dg/pch/pr66343-2.c 2016-10-05 12:31:44.065233616 +0200
@@ -0,0 +1,10 @@
+/* PR sanitizer/66343 */
+/* { dg-options "-fsanitize=undefined" } */
+
+#include "pr66343-2.h"
+
+void
+bar (int a, int b)
+{
+ a / b;
+}
--- gcc/testsuite/gcc.dg/pch/pr66343-2.hs.jj 2016-10-05 12:31:31.452393944 +0200
+++ gcc/testsuite/gcc.dg/pch/pr66343-2.hs 2016-10-05 12:11:25.000000000 +0200
@@ -0,0 +1,8 @@
+/* PR sanitizer/66343 */
+/* { dg-options "-fsanitize=undefined" } */
+
+void
+foo (int a, int b)
+{
+ a / b;
+}
Jakub