aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2023-08-10 18:35:13 +0200
committerJan Hubicka <jh@suse.cz>2023-08-10 18:35:13 +0200
commite41103081bfa341bdb1037e94d6b8f7a0af39067 (patch)
tree0f3397acf06d7c30871e9c84934920df29b9ed4e /gcc
parent8afe9d5d2fdd047cbd4e3531170af6b66d30e74a (diff)
downloadgcc-e41103081bfa341bdb1037e94d6b8f7a0af39067.zip
gcc-e41103081bfa341bdb1037e94d6b8f7a0af39067.tar.gz
gcc-e41103081bfa341bdb1037e94d6b8f7a0af39067.tar.bz2
Fix undefined behaviour in profile_count::differs_from_p
This patch avoid overflow in profile_count::differs_from_p and also makes it to return false from one of the values is undefined while other is defined. gcc/ChangeLog: * profile-count.cc (profile_count::differs_from_p): Fix overflow and handling of undefined values.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/profile-count.cc5
1 files changed, 3 insertions, 2 deletions
diff --git a/gcc/profile-count.cc b/gcc/profile-count.cc
index e63c943..a14f379 100644
--- a/gcc/profile-count.cc
+++ b/gcc/profile-count.cc
@@ -128,13 +128,14 @@ profile_count::differs_from_p (profile_count other) const
{
gcc_checking_assert (compatible_p (other));
if (!initialized_p () || !other.initialized_p ())
- return false;
+ return initialized_p () != other.initialized_p ();
if ((uint64_t)m_val - (uint64_t)other.m_val < 100
|| (uint64_t)other.m_val - (uint64_t)m_val < 100)
return false;
if (!other.m_val)
return true;
- int64_t ratio = (int64_t)m_val * 100 / other.m_val;
+ uint64_t ratio;
+ safe_scale_64bit (m_val, 100, other.m_val, &ratio);
return ratio < 99 || ratio > 101;
}