On Oct 1, 2014, at 12:49 PM, Argyrios Kyrtzidis <[email protected]> wrote:

>> 
>> On Oct 1, 2014, at 12:03 PM, Marshall Clow <[email protected]> wrote:
>> 
>> 
>> On Oct 1, 2014, at 10:17 AM, Bob Wilson <[email protected]> wrote:
>> 
>>>> 
>>>> On Oct 1, 2014, at 9:22 AM, Agustín K-ballo Bergé <[email protected]> 
>>>> wrote:
>>>> 
>>>> Hi Argyrios
>>>> 
>>>> On 30/09/2014 10:45 p.m., Argyrios Kyrtzidis wrote:
>>>>> Hi Marshall,
>>>>> 
>>>>> This seems to have caused a regression with Objective-C++, see the 
>>>>> following test case:
>>>>> 
>>>>> #include <type_traits>
>>>>> 
>>>>> class CXXForwardClass;
>>>>> @class ObjCForwardClass;
>>>>> 
>>>>> static_assert(std::is_trivially_destructible<CXXForwardClass*>::value == 
>>>>> true, "it is true"); // true
>>>>> static_assert(std::is_trivially_destructible<ObjCForwardClass*>::value == 
>>>>> true, "it is true"); // false ?
>>>> 
>>>> This sounds like a pre-existing issue to me. Does the following test case 
>>>> hold?
>>>> 
>>>> static_assert(std::is_destructible<CXXForwardClass*>::value == true, "it 
>>>> is true"); // true
>>>> static_assert(std::is_destructible<ObjCForwardClass*>::value == true, "it 
>>>> is true"); // false ?
>>> 
>>> No, that doesn’t work either.
>>> 
>>>> 
>>>>>> On Sep 2, 2014, at 9:19 AM, Marshall Clow <[email protected]> wrote:
>>>>>> 
>>>>>> Author: marshall
>>>>>> Date: Tue Sep  2 11:19:38 2014
>>>>>> New Revision: 216909
>>>>>> 
>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=216909&view=rev
>>>>>> Log:
>>>>>> Fix PR#20834 - 'is_trivially_destructible yeilds wrong answer for arrays 
>>>>>> of unknown bound' Thanks to K-ballo for the bug report. Update a few of 
>>>>>> the other tests while we're here, and fix a typo in a test name.
>>>>>> 
>>>>>> --- libcxx/trunk/include/type_traits (original)
>>>>>> +++ libcxx/trunk/include/type_traits Tue Sep  2 11:19:38 2014
>>>>>> @@ -2861,7 +2861,7 @@ template <class _Tp> struct _LIBCPP_TYPE
>>>>>> #if __has_feature(has_trivial_destructor) || (_GNUC_VER >= 403)
>>>>>> 
>>>>>> template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY 
>>>>>> is_trivially_destructible
>>>>>> -    : public integral_constant<bool, __has_trivial_destructor(_Tp)> {};
>>>>>> +    : public integral_constant<bool, is_destructible<_Tp>::value && 
>>>>>> __has_trivial_destructor(_Tp)> {};
>>>> 
>>>> This is the relevant change ^. Something that is not destructible cannot 
>>>> be trivially destructible by definition.
>>> 
>>> Right, but the issue wasn’t exposed until r216909.
>> 
>> Interesting (but consistent) behavior here:
>> 
>>      class CXXForwardClass;
>>      @class ObjCForwardClass;
>> 
>>      template <class U>
>>      void destroy ( U& u ) { u.~U(); }
>> 
>>      template <class U>
>>      void test () { U *p = nullptr; destroy<U*>(p); }
>> 
>>      int main () {
>>              test<void>();                           // compiles w/o error
>>              test<CXXForwardClass>();        // compiles w/o error
>>              test<ObjCForwardClass>();       // error.
>>              }
>> 
>> $ totclang11 -ObjC++ junk2.cpp
>> junk2.cpp:39:26: error: member access into incomplete type 'ObjCForwardClass'
>> void destroy ( U& u ) { u.~U(); }
>>                          ^
>> junk2.cpp:50:32: note: in instantiation of function template specialization
>>       'destroy<ObjCForwardClass *>' requested here
>> void test () { U *p = nullptr; destroy<U*>(p); }
>>                                ^
>> junk2.cpp:55:2: note: in instantiation of function template specialization
>>       'test<ObjCForwardClass>' requested here
>>         test<ObjCForwardClass>();
>>         ^
>> junk2.cpp:36:8: note: forward declaration of class here
>> @class ObjCForwardClass;
>>        ^
>> 1 error generated.
> 
> Interesting but this behavior have existed in clang forever, is libcxx 
> depending on this, recently, to do the type trait ?

the bit in destroy is exactly what the standard specifies as how to test for 
“is_destructible”.

Table 49:
For object types and given U equal to remove_all_extents_t<T>, if the 
expression std::declval<U&>(). ̃U() is well-formed when
treated as an unevaluated operand (Clause 5), then is_destructible<T>::value is 
true, otherwise it is false.

Richard Smith pointed out that destroying a pointer to an objective-C class 
might require an ARC call, and so the compiler needs to see the type to figure 
out if it is_destructible.

Note that is_destructible<ObjCForwardClass**>::value is true, so it’s just 
pointers to objective-C objects, not pointers in general.

— Marshall
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to