Issue 75593
Summary [POC][Clang v17.0.6] Optimization resulting in invalid code
Labels clang
Assignees
Reporter RipleyTom
    When compiled with `clang++ -O3 -march=skylake main.cpp` with clang 17.0.6 the following code results in a crash.

>From what I'm able to gather, it inlines blah which inlines the vec.resize() except it doesn't check if size == 0 which result in a crash because it sets 1 bytes to 0 and then decreases the value:
Faulty assembly:
```x86asm
   0x00005555555554d9 <+121>: movsxd r15,DWORD PTR [r13+0x0]
   0x00005555555554dd <+125>:   test r15,r15
   0x00005555555554e0 <+128>:   js     0x555555555578 <_ZN4bloh8add_blahERKSt6vectorI5stuffSaIS1_EE+280>
   0x00005555555554e6 <+134>:   mov    rdi,r15
   0x00005555555554e9 <+137>:   call 0x555555555080 <_Znwm@plt>
   0x00005555555554ee <+142>:   mov r12,rax
   0x00005555555554f1 <+145>:   mov    BYTE PTR [rax],0x0
 0x00005555555554f4 <+148>:   mov    rdx,r15
   0x00005555555554f7 <+151>: dec    rdx
   0x00005555555554fa <+154>:   je     0x555555555508 <_ZN4bloh8add_blahERKSt6vectorI5stuffSaIS1_EE+168>
   0x00005555555554fc <+156>:   lea    rdi,[r12+0x1]
   0x0000555555555501 <+161>:   xor esi,esi
   0x0000555555555503 <+163>:   call   0x555555555050 <memset@plt>
```

r15 is value->size_data, it calls the new with size 0, then decreases the size by 1 which results in 0xFFFFFFFFFFFFFFFF which it checks against 0 and then calls memset with size 0xFFFFFFFFFFFFFFFF and finally results in invalid memory access and the crash.

POC:
```cpp
#include <vector>
#include <cstdint>
#include <cstring>

struct stuff
{
	int size_data;
	std::uint8_t *data;
};

class blah
{
public:
	blah(const stuff *value)
	{
		vec.resize(value->size_data);
		std::memcpy(vec.data(), value->data, value->size_data);
	}

private:
	std::vector<std::uint8_t> vec;
};

class bloh
{
	std::vector<blah> list_blahs;

public:
	void add_blah(const std::vector<stuff> &list_values)
	{
		for (const auto &dastuff : list_values)
		{
			list_blahs.push_back(blah(&dastuff));
		}
	}
};

int main()
{
	stuff the_stuff[3] = {{5}, {1}, {0}};
	std::vector<stuff> list_stuff;

	for (int i = 0; i < 3; i++)
	{
		the_stuff[i].data = "" std::uint8_t[8];
		list_stuff.push_back(the_stuff[i]);
	}

	bloh da_bloh;
	da_bloh.add_blah(list_stuff);

	return 0;
}
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to