On Fri, Aug 15, 2014 at 10:45 AM, Joey Ye <joey.ye...@gmail.com> wrote: > Running into an unexpected result with GCC with following case, but > not sure if it is a valid C++ case. > > #define nullptr 0 > enum nonetype { none }; > > template<typename T> > class class_zoo { > public: > const T *data; > int length; > > class_zoo (nonetype) : data (nullptr), length (0) {} > class_zoo (const T &e) : data (&e), length (1) {}
Capturing a const referece via a pointer is error-prone as for example literal constants class_zoo<const int *> zoo(0) have associated objects that live only throughout the function call. So clearly your testcase is invalid. Richard. > }; > > int bar (class_zoo<const int *> p1 = none, > class_zoo<const unsigned *> p2 = none) > { > if (*p1.data==nullptr) return 1; > return 0; > } > > int foo (int *b) // If changing int to const int here, zoo will > return 0 (pass) > { > class_zoo<const int *> zoo(b); > return bar(zoo); > } > > int g = 678; > int main () > { > return foo (&g); > } > > $ g++ main.cpp -fstack-protector -o m > $ ./m > $ echo $? > 1 > > Expand shows: > D.2320 = b_2(D); > class_zoo<const int*>::class_zoo (&zoo, &D.2320); > D.2320 ={v} {CLOBBER}; <------- D.2320 is dead, but it is address > escapes to zoo > <------- with > stack-protector, D.2322 reuses stack slot of D.2320, thus overwrite > D.2320 > class_zoo<const unsigned int*>::class_zoo (&D.2322, 0); > _8 = bar (zoo, D.2322); <-------- D.2320 is accessed via its > address, but value changed now > _9 = _8; > D.2322 ={v} {CLOBBER}; > zoo ={v} {CLOBBER}; > ;; succ: 3 > > ;; basic block 3, loop depth 0 > ;; pred: 2 > <L2>: > return _9; > ;; succ: EXIT > > } > > > Partition 0: size 16 align 16 > D.2322 D.2320 <------- GCC believes they are not > conflict, which is what I not sure of here > Partition 2: size 16 align 16 > zoo > > Questions > 1. Is this a correct test case? > 2. If not, why escaping of D.2320's address to a local is not > accounted as conflicting to other local variables? > > Thanks, > Joey