https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84587
Bug ID: 84587 Summary: [8 Regression] Local variable initializer goes out of scope since r247793 Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: marxin at gcc dot gnu.org CC: jakub at gcc dot gnu.org, jason at gcc dot gnu.org, mpolacek at gcc dot gnu.org Target Milestone: --- Starting from the mentioned revision: $ cat /tmp/snippet.cc #include <cstdlib> #include <initializer_list> template<typename T> class ArrayView { public: using size_t = std::size_t; constexpr ArrayView(const std::initializer_list<T>& v) : m_pointer(v.begin()), m_size(v.size()) {} [[gnu::always_inline]] constexpr T& operator[](size_t n) const { return *(m_pointer + n); } private: T* m_pointer; size_t m_size; }; int main() { ArrayView<const char> a = {'a', 'b', 'c'}; return a[0]; } $ g++ -g /tmp/snippet.cc -fsanitize=address -std=c++11 && ./a.out ================================================================= ==3792==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7fffffffda70 at pc 0x000000400af9 bp 0x7fffffffda30 sp 0x7fffffffda28 READ of size 1 at 0x7fffffffda70 thread T0 #0 0x400af8 in main /tmp/snippet.cc:26 #1 0x7ffff6186f49 in __libc_start_main (/lib64/libc.so.6+0x20f49) #2 0x4007d9 in _start (/home/marxin/Programming/testcases/a.out+0x4007d9) Address 0x7fffffffda70 is located in stack of thread T0 at offset 32 in frame #0 0x400895 in main /tmp/snippet.cc:23 This frame has 3 object(s): [32, 35) '<unknown>' <== Memory access at offset 32 is inside this variable [96, 112) 'a' [160, 176) '<unknown>' HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-use-after-scope /tmp/snippet.cc:26 in main Shadow bytes around the buggy address: 0x10007fff7af0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x10007fff7b40: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1[f8]f2 0x10007fff7b50: f2 f2 f2 f2 f2 f2 00 00 f2 f2 f2 f2 f2 f2 f8 f8 0x10007fff7b60: f2 f2 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 0x10007fff7b70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==3792==ABORTING -fdump-tree-gimple: GCC 7: g++-7 /tmp/snippet.cc -fdump-tree-gimple=/dev/stdout int main() () { int D.3323; { struct ArrayView a; try { a.m_pointer = &._18; a.m_size = 3; _1 = ArrayView<const char>::operator[] (&a, 0); _2 = *_1; D.3323 = (int) _2; return D.3323; } finally { a = {CLOBBER}; } } D.3323 = 0; return D.3323; } GCC 8: g++ /tmp/snippet.cc -fdump-tree-gimple=/dev/stdout main () { const struct initializer_list D.3377; const char D.3376[3]; int D.3403; { struct ArrayView a; try { D.3376[0] = 97; D.3376[1] = 98; D.3376[2] = 99; try { D.3377._M_array = &D.3376; D.3377._M_len = 3; try { ArrayView<const char>::ArrayView (&a, &D.3377); } finally { D.3377 = {CLOBBER}; } } finally { D.3376 = {CLOBBER}; } _1 = ArrayView<const char>::operator[] (&a, 0); _2 = *_1; D.3403 = (int) _2; return D.3403; } finally { a = {CLOBBER}; } } D.3403 = 0; return D.3403; }