https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119006

            Bug ID: 119006
           Summary: IPA ICF and LTO cause strcmp condition to be omitted
           Product: gcc
           Version: 14.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: ipa
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jeff-gcc at caffeinated dot me.uk
  Target Milestone: ---

When compiled with -O2 -flto  (or more minimally: -O -finline
-fipa-icf-functions -foptimize-strlen -ftree-dse -ftree-vrp -flto), GCC
miscompiles the following code:

template<unsigned  N> struct FixedString {
    FixedString(const char* str_) { *this = str_; }
    bool operator==(const char* rhs_) const { return rhs_ and not
__builtin_strcmp(_str, rhs_); }
    bool operator!=(const char* rhs_) const { return !(*this == rhs_); }
    char _str[N + 1];
};
int fixedStringUser(const FixedString<10>& lhs, const char* rhs) {
    return lhs == rhs;
}
void checkString(FixedString<127> reason_) {
    if (reason_ != "StrOverTenChars") asm volatile("nop");
}
int main(int argc, char** argv) {
    FixedString<127> fs = argv[1];
    if (argc > 2) checkString(fs);
}

During LTO WPA, ICF replaces FixedString<127>::operator== with
FixedString<10>::operator==, and then LTRANS reasons that strcmp of a buffer
which can hold a string up to length 10 cannot be equal to a string longer than
10 characters, forgetting that the LHS is actually max length 127. This results
in `checkString` being reduced to the body of the `if` condition, i.e. just the
`asm volatile("nop")`.

Testing on godbolt (https://gcc.godbolt.org/z/bv3YqzTG5) shows that this has
been present since GCC11, and is still present in trunk.

Reply via email to