This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/81603] New: Various compiler UB on very large constant offsets
- From: "jakub at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 28 Jul 2017 14:55:34 +0000
- Subject: [Bug tree-optimization/81603] New: Various compiler UB on very large constant offsets
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81603
Bug ID: 81603
Summary: Various compiler UB on very large constant offsets
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: jakub at gcc dot gnu.org
Target Milestone: ---
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.