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 <ja...@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