When compiling libstdc++-v3/testsuite/21_strings/basic_string/cons/char/1.cc there are various UBs in cc1plus: ../../gcc/ipa-polymorphic-call.c:926:59: runtime error: signed integer overflow: -9223372036854775808 * 8 cannot be represented in type 'long int' ../../gcc/tree-ssa-alias.c:704:30: runtime error: signed integer overflow: -9223372036854775808 * 8 cannot be represented in type 'long int' ../../gcc/dwarf2out.c:13534:15: runtime error: signed integer overflow: 9223372036854775408 + 400 cannot be represented in type 'long int [4]' ../../gcc/dwarf2out.c:13559:11: runtime error: signed integer overflow: -9223372036854775808 + -400 cannot be represented in type 'long int [4]' csz01 = str01.max_size(); // NB: As strlen(str_lit01) != csz01, this test is undefined. It // should not crash, but what gets constructed is a bit arbitrary. try { std::string str03(str_lit01, csz01 + 1); VERIFY( true ); } catch(std::length_error& fail) { VERIFY( true ); } catch(...) { VERIFY( false ); } csz01 + 1 is 0x8000000000000000UL on x86_64, and both ipa-polymorphic-call.c and tree-ssa-alias.c try to multiply that by BITS_PER_UNIT. Another similar UB is on: void foo (char *p) { p[- __LONG_MAX__ - 1] = 1; } at -g -O2 I'm getting ../../gcc/builtins.c:351:54: runtime error: signed integer overflow: -9223372036854775808 * 8 cannot be represented in type 'long int [3]' For ipa-polymorphic-call.c I wrote untested: 2017-07-28 Jakub Jelinek <jakub@redhat.com> * ipa-polymorphic-call.c (ipa_polymorphic_call_context::ipa_polymorphic_call_context): Perform offset arithmetic in offset_int, bail out if the resulting bit offset doesn't fit into shwi. --- gcc/ipa-polymorphic-call.c.jj 2017-06-12 12:41:55.000000000 +0200 +++ gcc/ipa-polymorphic-call.c 2017-07-28 15:02:43.747354910 +0200 @@ -921,9 +921,13 @@ ipa_polymorphic_call_context::ipa_polymo and MEM_REF is meaningless, but we can look futher. */ if (TREE_CODE (base) == MEM_REF) { + offset_int o = mem_ref_offset (base) * BITS_PER_UNIT; + o += offset; + o += offset2; + if (!wi::fits_shwi_p (o)) + break; base_pointer = TREE_OPERAND (base, 0); - offset - += offset2 + mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT; + offset = o.to_shwi (); outer_type = NULL; } /* We found base object. In this case the outer_type @@ -961,10 +965,15 @@ ipa_polymorphic_call_context::ipa_polymo break; } else if (TREE_CODE (base_pointer) == POINTER_PLUS_EXPR - && tree_fits_uhwi_p (TREE_OPERAND (base_pointer, 1))) + && TREE_CODE (TREE_OPERAND (base_pointer, 1)) == INTEGER_CST) { - offset += tree_to_shwi (TREE_OPERAND (base_pointer, 1)) - * BITS_PER_UNIT; + offset_int o = offset_int::from (TREE_OPERAND (base_pointer, 1), + SIGNED); + o *= BITS_PER_UNIT; + o += offset; + if (!wi::fits_shwi_p (o)) + break; + offset = o.to_shwi (); base_pointer = TREE_OPERAND (base_pointer, 0); } else but given that there are tons of other spots, I wonder if using offset_int for such stuff is the right way to go.
Well, yes - offset_int is basically former double_int and thus good for addresses/offsets measured in bits. Of course in this case why do we need the offset in bits at all? ... That said, we're looking at an ADDR_EXPR here, so we know bitsize % BITS_PER_UNIT == 0. Given we reject max_size == -1 this code could have used get_addr_base_and_unit_offset instead and avoid bit precision stuff.
Author: jakub Date: Mon Jul 31 08:22:14 2017 New Revision: 250727 URL: https://gcc.gnu.org/viewcvs?rev=250727&root=gcc&view=rev Log: PR tree-optimization/81603 * ipa-polymorphic-call.c (ipa_polymorphic_call_context::ipa_polymorphic_call_context): Perform offset arithmetic in offset_int, bail out if the resulting bit offset doesn't fit into shwi. Modified: trunk/gcc/ChangeLog trunk/gcc/ipa-polymorphic-call.c
Author: aldyh Date: Wed Sep 13 16:05:54 2017 New Revision: 252184 URL: https://gcc.gnu.org/viewcvs?rev=252184&root=gcc&view=rev Log: PR tree-optimization/81603 * ipa-polymorphic-call.c (ipa_polymorphic_call_context::ipa_polymorphic_call_context): Perform offset arithmetic in offset_int, bail out if the resulting bit offset doesn't fit into shwi. Modified: branches/range-gen2/gcc/ChangeLog branches/range-gen2/gcc/ipa-polymorphic-call.c
Are the committed fixes enough to resolve the bug?
Aldy: Can the bug be marked as resolved?