On Tue, Oct 22, 2013 at 4:03 PM, David Majnemer <[email protected]>wrote:
> On Tue, Oct 22, 2013 at 3:43 PM, Richard Smith <[email protected]>wrote: > >> On Tue, Oct 22, 2013 at 2:56 PM, David Majnemer <[email protected] >> > 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? > A literal reading of the standard suggests that 'z' has type 'int Z::<anonymous union>::*', which would make this ill-formed. That said, that behavior is entirely useless, and our current behavior makes a lot more sense. I'm going to bring this up in CWG. > >> 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". > > >> >> >>> template<unsigned char C> struct Overflow; // expected-note{{template >>> parameter is declared here}} >>> >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> [email protected] >>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >>> >> >> >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
