This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Is escaping of a temp variable valid?
- From: Joey Ye <joey dot ye dot cc at gmail dot com>
- To: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Fri, 15 Aug 2014 16:45:39 +0800
- Subject: Is escaping of a temp variable valid?
- Authentication-results: sourceware.org; auth=none
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) {}
};
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