1*b0914e72SArtem Dergachev // RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=core,cplusplus.NewDelete -verify %s 27740c6d6SCsaba Dabis 37740c6d6SCsaba Dabis // expected-no-diagnostics: 47740c6d6SCsaba Dabis // From now the profile of the 'StackFrameContext' also contains the 57740c6d6SCsaba Dabis // 'NodeBuilderContext::blockCount()'. With this addition we can distinguish 67740c6d6SCsaba Dabis // between the 'StackArgumentsSpaceRegion' of the 'P' arguments being different 77740c6d6SCsaba Dabis // on every iteration. 87740c6d6SCsaba Dabis 97740c6d6SCsaba Dabis typedef __INTPTR_TYPE__ intptr_t; 107740c6d6SCsaba Dabis 117740c6d6SCsaba Dabis template <typename PointerTy> 127740c6d6SCsaba Dabis struct SmarterPointer { getFromVoidPointerSmarterPointer137740c6d6SCsaba Dabis PointerTy getFromVoidPointer(void *P) const { 147740c6d6SCsaba Dabis return static_cast<PointerTy>(P); 157740c6d6SCsaba Dabis } 167740c6d6SCsaba Dabis getPointerSmarterPointer177740c6d6SCsaba Dabis PointerTy getPointer() const { 187740c6d6SCsaba Dabis return getFromVoidPointer(reinterpret_cast<void *>(Value)); 197740c6d6SCsaba Dabis } 207740c6d6SCsaba Dabis 217740c6d6SCsaba Dabis intptr_t Value = 13; 227740c6d6SCsaba Dabis }; 237740c6d6SCsaba Dabis 247740c6d6SCsaba Dabis struct Node { 257740c6d6SCsaba Dabis SmarterPointer<Node *> Pred; 267740c6d6SCsaba Dabis }; 277740c6d6SCsaba Dabis test(Node * N)287740c6d6SCsaba Dabisvoid test(Node *N) { 297740c6d6SCsaba Dabis while (N) { 307740c6d6SCsaba Dabis SmarterPointer<Node *> Next = N->Pred; 317740c6d6SCsaba Dabis delete N; 327740c6d6SCsaba Dabis 337740c6d6SCsaba Dabis N = Next.getPointer(); 347740c6d6SCsaba Dabis // no-warning: 'Use of memory after it is freed' was here as the same 357740c6d6SCsaba Dabis // 'StackArgumentsSpaceRegion' purged out twice as 'P'. 367740c6d6SCsaba Dabis } 377740c6d6SCsaba Dabis } 38