[llvm-bugs] [Bug 45607] New: Incorrect transformation with -fstrict-aliasing

via llvm-bugs llvm-bugs at lists.llvm.org
Sun Apr 19 07:07:52 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=45607

            Bug ID: 45607
           Summary: Incorrect transformation with -fstrict-aliasing
           Product: clang
           Version: 10.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C
          Assignee: unassignedclangbugs at nondot.org
          Reporter: cuoq at trust-in-soft.com
                CC: blitzrakete at gmail.com, dgregor at apple.com,
                    erik.pilkington at gmail.com, llvm-bugs at lists.llvm.org,
                    richard-llvm at metafoo.co.uk

C17 6.5:6 says:

The effective type of an object for an access to its stored value is the
declared type of the object, if any.88) If a value is stored into an object
having no declared type through an lvalue having a type that is not a character
type, then the type of the lvalue becomes the effective type of the object for
that access and for subsequent accesses that do not modify the stored value. If
a value is copied into an object having no declared type using memcpy or
memmove, or is copied as an array of character type, then the effective type of
the modified object for that access and for subsequent accesses that do not
modify the value is the effective type of the object from which the value is
copied, if it has one. For all other accesses to an object having no declared
type, the effective type of the object is simply the type of the lvalue used
for the access.

I interpret the words “If a value is stored into an object having no declared
type through an lvalue having a type that is not a character type, then the
type of the lvalue becomes the effective type of the object for that access and
for subsequent accesses that do not modify the stored value” as saying that the
repurposing of dynamically allocated memory is allowed in C. A write of a new
effective type to dynamically allocated memory is not a “subsequent access that
does not modify the stored value”, so it simply changes the type of the memory
to the type of the lvalue being used for the write.

Consider the following program, which was provided by Sorav Bansal:

(Compiler Explorer link: https://gcc.godbolt.org/z/Vg25xq )

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

int a;

__attribute__((__noinline__)) int foo(float *x, int *y, int *z)
{
  int sum = 1;
  for (int i = 0; i < a; i++) {
    *z = 0x123;
    *x = 3.0f;
    sum *= *y;
    *z = 0x40400300;
  }
  return sum;
}

int main()
{
  char *f;
  f = malloc(32);
  if (!f) abort();
  int i = 3;
  a = 1;
  foo((float*)f, &i, (int*)f);
  float fl;
  memcpy(&fl, f, 4);
  printf("f = %f\n", fl);
}

According to my interpretation above (“repurposing of dynamically allocated
memory is allowed”), this program does nothing wrong. The memory location that
both x and z point to is repurposed many times, but it is never read inside
function foo, and main reads it carefully using memcpy.

The behavior I expect for this program is to print:

f = 3.000183

(3.000183 is the float represented by 0x40400300.)

However, when -fstrict-aliasing is enabled, Clang 10 moves the assignment “*x =
3.0f;” after the loop and makes the compiled program print:

f = 3.000000

I think the transformation is wrong here. The function foo does not invoke UB
when passed z and x aliasing pointers to dynamically allocated memory, and the
“naïve memory model” behavior of the function should have been preserved for
such a calling context.

Yes, this would mean that GCC has independently implemented the same bug, but I
am still confident enough that the C standard intended to allow the repurposing
of dynamically allocated memory to report this. Please accept my apologies if I
am wrong.

(Bug reported in GCC at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94658 )

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200419/d88cde1c/attachment.html>


More information about the llvm-bugs mailing list