<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/74459>74459</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            template instantiation problem
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          November20
      </td>
    </tr>
</table>

<pre>
    ```c++
struct X {};

template <typename T> struct is_pointer {
        static const bool value = false;
};

template <typename T> struct is_pointer<T *> {
        static const bool value = true;
};

template <class T> class Resource {
    public:
        Resource(T p)
                : r(allocate(p))
        {
        }
        ~Resource()
        {
                release(r);
        }

 private:
        T *r;
        T *allocate(T p)
        {
                return new T(p);
        }
        void release(T *d)
        {
                is_pointer<T> pd;
                const bool a1 = pd.value;

                if (a1) {
                        T temp = *d;
                        delete[] temp;
                        delete d;
                } else {
                        delete d;
                }
        }
};

void fcn()
try {
        int i = 22;
        int *a = new int[3]();
        Resource<int *> b1(a);
        Resource<int> b2(i);
        throw X();
} catch (X) {
}

int main()
{
        fcn();
        return 0;
}
```
"The reason my code doesn't compile is that 'if (a1)' is a runtime condition, and both branches of the if-else are compiled and so must be valid code."
This is a suggestion for me, but I can't understand it. So I instantiated the code:
```c++
struct X {
};
template <typename T> struct is_pointer {
    static const bool value = false;
};
template<> struct is_pointer<int *> {
    static const bool value = true;
};
template<> struct is_pointer<int> {
    static const bool value = false;
};
template <typename T> struct is_pointer<T *> {
    static const bool value = true;
};
template <class T> class Resource {
public:
    Resource<T>(T p) : r(this->allocate(p)) {
 }
    ~Resource<T>() {
        this->release(this->r);
 }
private:
    T *r;
    T *allocate(T p) {
        return new T(p);
    }
    void release(T *d) {
        is_pointer<T> pd;
 const bool a1 = pd.value;
        if (a1) {
            T temp = *d;
            delete [] temp;
            delete d;
        } else {
            delete d;
        }
    }
};
template<> class Resource<int *> {
public:
    Resource(int *p) : r(this->allocate(p)) {
    }
    ~Resource<int *>() {
        this->release(this->r);
 }
private:
    int **r;
    int **allocate(int *p) {
 return new int *(p);
    }
    void release(int **d) {
 is_pointer<int *> pd;
        const bool a1 = pd.value;
        if (a1) {
            int *temp = *d;
            delete [] temp;
 delete d;
        } else {
            delete d;
        }
 }
};
template<> class Resource<int> {
public:
    Resource(int p) : r(this->allocate(p)) {
    }
    ~Resource<int>() {
 this->release(this->r);
    }
private:
    int *r;
    int *allocate(int p) {
        return new int(p);
    }
    void release(int *d);
};
void fcn()
    try {
        int i = 22;
 int *a = new int [3](/*implicit*/(int[3])0);
        Resource<int *> b1(a);
        Resource<int> b2(i);
        throw X();
    } catch (X) {
    }
int main() {
    fcn();
    return 0;
}
```
 I don't understand why "Resource<int *> " instantiates successfully, but "Resource<int>" destructor instantiates unsuccessfully. 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0WM9v6jgQ_mvMZVQUHGjIgUNbHtK77GGXw7utnGQgXjlxZDutuPRvX9mExPkBpe17KGpTezzfjOezv6FMa34sETdk9UxW2xmrTS7V5i_5ikWCigazRGanDXkMzk9K6LN9gi0JnrRRdWrgF5DomURbEjbj558Gi0owg0DCF3OqsGQFwp6EP6BZx_W_leSlQeUcNEtjbZjhKaSy1AYSKQW8MlFbN1s4MKGxw_kOJglf9kDok528F96o-l70VDCtz9Dn179Ry1ql2IEBAFR1InhKwqcW_2JH6HoPFaFxO2Of8AkUoWsmhEyZsUbOxLfycrEhXt7fPcdX7YNYoUCmrZGyVuGkMxd9pfirDcGL3W2o8he5ES_aYUpDcFOrEkp8g_0ltekI4lfJM-iCdTjZDdf9wtuyVFnPdxB7JWcLV-8qm7viD-rceDyArcSC0BgGYC5xywbnxUUWDg0yFGjwfOyc7TUTGC2OtoBC4wTq9RUTmzjir9vTQ1r6DDHq1MPhpQHu0qLUR7HjttRuyhaQl4asnkOy2jbuPOOWiuFLs84WJFnY_bxp6swooWs-MDO5km_wawgVbSFlJs1tpX71C9Vnsw2jYLyXup92tyseaEPXoHclnF8u92XzJ6X7HEEh07KE4gSpzBAyibokNDKQyqLiAoFrMDmzGxJ57CI0sjMMVF0aXqC9mzJuuCwJfQFWZpBIk0OiWJnmqEEewOQI_PDgWMIUXgAyZ60lFLVlOtqrjWcumjmh9BzsPuf6jKfr4xG1BYKDVFCgxUtqAz8hZefI6zJDpY11y80c_pHwE3hpBwxnBjMXifXfXRMfS8mInl-SEnu9fk1LLnAkfLkmHR5t7wa8qh734X0K6-PkviqR387yTnUcKKOF9e4Cu7SVE7jIosm5fiDhj7E8evG3h9S6fB_77Fs3n4vnTnHaEf9S6JwP1dE6GchjOzTSxzH-LWW0872krmnj2O1NVYQ7BLF1NCWG4H2u6aFv06jXlCZOmI19jIXx3mUTG3njgPYpe-U2uMVfum5WfJ69w3jfJ8P4ozS-wAy53I17GfQSbcPx6Nyu-hypO7ABs69d09W48L-T3w3S90j-55j9VVp_ktK_nc9TXL6XxL7rGzyeJPGAwR9eyjbUrzE4GzSs7ftUN-7OsN-R-_QbteUw1ZSD35XvCH3iRSV4yo07TbtzYK1NHAxTgr4Q3-zfp-2nm_juiprq5C-H4Eo339vrfi_fNxr38V4hP27k4SdkctT5vuUnIJReEQRK_Y5Yg67TFLU-1EKcLg31aLXjPYUMz02ZVH0fdel7mcMs24RZHMZshptFFCyiKA6Xq1m-SeJoER8e1-tlGLFgtVguwkP8iEuGAS5DDGd8QwMaLmiwWlC6Xq3nURI9HuIwWR5okD6mCVkGWDAu5kK8FnOpjjOudY2baLlcxTPBEhTa_feIUscwO2m_S6y2M7Wxax6S-qjJMhBcG915MdwI3LRNYZee_bpRKZkILGa1EpvcmErbg2vJuTtyk9fJPJUFoTvrrPn1UCn5H6aG0J0LQRO6cyH-HwAA__8xoxyA">