This patch ought to fix the unexpected size of type 'long long unsigned int:40' issue in PR58413. Since libubsan will fail when the precision of a type is not 32/64/128, we can't pass the width of a bitfield, instead we should pass the TYPE_SIZE of the base type, I guess.
What is not very nice is that the type we get in the bit-field case doesn't have the TYPE_NAME set, so we'll have to live with "<unnamed>" (renamed, since I find it better than "<unknown>"). Regtested/ran bootstrap-ubsan on x86_64-linux. Ok for trunk? 2013-09-16 Marek Polacek <pola...@redhat.com> PR sanitizer/58413 * ubsan.c (ubsan_type_descriptor): Change TYPE_PRECISION of a bit-field type to its TYPE_SIZE. Tweak type name. * c-c++-common/ubsan/shift-4.c: New test. --- gcc/ubsan.c.mp2 2013-09-16 16:55:26.653579402 +0200 +++ gcc/ubsan.c 2013-09-16 16:57:29.192016988 +0200 @@ -251,6 +251,10 @@ ubsan_type_descriptor (tree type) /* See through any typedefs. */ type = TYPE_MAIN_VARIANT (type); + /* Handle bit-fields. */ + if (compare_tree_int (TYPE_SIZE (type), TYPE_PRECISION (type) == 1)) + TYPE_PRECISION (type) = tree_low_cst (TYPE_SIZE (type), 1); + tree decl = decl_for_type_lookup (type); if (decl != NULL_TREE) return decl; @@ -270,7 +274,7 @@ ubsan_type_descriptor (tree type) tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); } else - tname = "<unknown>"; + tname = "<unnamed>"; if (TREE_CODE (type) == INTEGER_TYPE) { --- gcc/testsuite/c-c++-common/ubsan/shift-4.c.mp2 2013-09-16 17:01:55.852982631 +0200 +++ gcc/testsuite/c-c++-common/ubsan/shift-4.c 2013-09-16 17:32:32.114891611 +0200 @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -w" } */ + +struct S { unsigned long long int b:40; } s; + +int +main () +{ + s.b = 2; + s.b <<= 120; + return 0; +} + +/* { dg-output "shift exponent 120 is too large\[^\n\r]*(\n|\r\n|\r)" } */ Marek