r193203 - Sema: Allow IndirectFieldDecl to appear in a non-type template argument

David Majnemer david.majnemer at gmail.com
Wed Oct 23 13:57:02 PDT 2013


On Tue, Oct 22, 2013 at 4:03 PM, David Majnemer <david.majnemer at gmail.com>wrote:

> On Tue, Oct 22, 2013 at 3:43 PM, Richard Smith <richard at metafoo.co.uk>wrote:
>
>> On Tue, Oct 22, 2013 at 2:56 PM, David Majnemer <david.majnemer at gmail.com
>> > wrote:
>>
>>> Author: majnemer
>>> Date: Tue Oct 22 16:56:38 2013
>>> New Revision: 193203
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=193203&view=rev
>>> Log:
>>> Sema: Allow IndirectFieldDecl to appear in a non-type template argument
>>>
>>> We would not identify pointer-to-member construction in a non-type
>>> template argument if it was either a FieldDecl or a CXXMethodDecl.
>>> However, this would incorrectly reject declarations that were injected
>>> via an IndirectFieldDecl (e.g. a field inside of an anonymous union).
>>>
>>
>> Is this really correct? Such fields are not members of the enclosing
>> non-anonymous struct. &Z::union_member below should have type "int
>> Z::<anonymous union>::*", not "int Z::*", as far as I can tell.
>>
>
> GCC, EDG and MSVC all seem to think it should be allowed.
>
> Note that we allowed the following related test case before my change:
> struct a {
>   union { int i; };
> };
>
> template <int (a::*)> struct b;
> constexpr auto z = &a::i;
> typedef b<z> c;
>
> Do you consider this ill-formed as well?
>
>
>> This fixes PR17657.
>>>
>>> Modified:
>>>     cfe/trunk/lib/Sema/SemaTemplate.cpp
>>>     cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp
>>>
>>> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=193203&r1=193202&r2=193203&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Oct 22 16:56:38 2013
>>> @@ -4609,8 +4609,11 @@ static bool CheckTemplateArgumentPointer
>>>                    diag::err_template_arg_not_pointer_to_member_form)
>>>        << Arg->getSourceRange();
>>>
>>> -  if (isa<FieldDecl>(DRE->getDecl()) ||
>>> isa<CXXMethodDecl>(DRE->getDecl())) {
>>> +  if (isa<FieldDecl>(DRE->getDecl()) ||
>>> +      isa<IndirectFieldDecl>(DRE->getDecl()) ||
>>> +      isa<CXXMethodDecl>(DRE->getDecl())) {
>>>      assert((isa<FieldDecl>(DRE->getDecl()) ||
>>> +            isa<IndirectFieldDecl>(DRE->getDecl()) ||
>>>              !cast<CXXMethodDecl>(DRE->getDecl())->isStatic()) &&
>>>             "Only non-static member pointers can make it here");
>>>
>>>
>>> Modified: cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp?rev=193203&r1=193202&r2=193203&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp (original)
>>> +++ cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp Tue Oct 22 16:56:38
>>> 2013
>>> @@ -75,6 +75,9 @@ struct Z {
>>>
>>>    int int_member;
>>>    float float_member;
>>> +  union {
>>> +    int union_member;
>>> +  };
>>>  };
>>>  template<int (Z::*pmf)(int)> struct A6; // expected-note{{template
>>> parameter is declared here}}
>>>  A6<&Z::foo> *a17_1;
>>> @@ -88,6 +91,7 @@ A7<&Z::int_member> *a18_1;
>>>  A7c<&Z::int_member> *a18_2;
>>>  A7<&Z::float_member> *a18_3; // expected-error{{non-type template
>>> argument of type 'float Z::*' cannot be converted to a value of type 'int
>>> Z::*'}}
>>>  A7c<(&Z::int_member)> *a18_4; // expected-warning{{address non-type
>>> template argument cannot be surrounded by parentheses}}
>>> +A7c<&Z::union_member> *a18_5;
>>>
>>
>> Can we mangle this?
>>
>
> We can't mangle it yet but there is no reason to see why we couldn't. EDG
> and GCC both disagree on what it should be mangled to. EDG sticks in __Cn
> where n corresponds to the depth of the anonymous unions if they are
> nested, GCC mangles it as {unnamed type#1}.  I believe neither are correct,
> the Itanium ABI 5.1.2 General Structure section states that the name of an
> anonymous union comes from "the first named data member found by a
> pre-order, depth-first, declaration-order walk of the data members of the
> anonymous union".
>

We now mangle it in r193269.


>
>
>>
>>
>>>  template<unsigned char C> struct Overflow; // expected-note{{template
>>> parameter is declared here}}
>>>
>>>
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131023/4986d1fc/attachment.html>


More information about the cfe-commits mailing list