Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8341178

TypeRawPtr::add_offset may be "miscompiled" due to UB

    XMLWordPrintable

Details

    Description

      TypeRawPtr::add_offset has an implicit conversion of a literal 0 to a pointer, which would trigger -Wzero-as-null-pointer-constant. The obvious fix is to change the literal 0 to nullptr.

      However, the surrounding code touches on UB. The problem code (after replacing literal 0 with nullptr) is

      https://github.com/openjdk/jdk/blob/988a531b097ccbd699d233059d73f41cae24dc5b/src/hotspot/share/opto/type.cpp#L3227-L3228
      {code:c++}
      address bits = _bits+offset;
      if (bits == nullptr) ...
      {code}

      The compiler can infer that the result of pointer arithmetic is never null, as that would involve UB. So the compiler could change or elide the comparison and it's positive consequent.

      Exploring with godbolt shows that clang actually does optimize this in a way that differs from a naive reading of the source code.

      Consider the following test file:
      {code:c++}
      #include <stdint.h>
      bool is_arith_null(const char* p, intptr_t i) {
        return (p + i) == nullptr;
      }
      {code}

      gcc produces this:
      {code}
      is_arith_null(char const*, int):
          add rdi, rsi
          sete al
          ret
      {code}
      msvc produces something functionally equivalent.

      But clang produces
      {code}
      is_arith_null(char const*, int):
          test rdi, rdi
          sete al
          ret
      {code}
      The clang-generated code discards the addition and just returns true if the pointer argument is null.

      Attachments

        Issue Links

          Activity

            People

              kbarrett Kim Barrett
              kbarrett Kim Barrett
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated: