r368940 - Fix handling of class member access into a vector type.
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 16 01:11:00 PDT 2019
Not at all; merged it in r369087. Please let me know if there are any
follow-ups.
Thanks,
Hans
On Thu, Aug 15, 2019 at 7:08 PM Richard Smith <richard at metafoo.co.uk> wrote:
>
> Hi Hans,
>
> This fixes a regression in Clang 9; is it too late to get this into the release?
>
> ---------- Forwarded message ---------
> From: Richard Smith via cfe-commits <cfe-commits at lists.llvm.org>
> Date: Wed, 14 Aug 2019 at 15:56
> Subject: r368940 - Fix handling of class member access into a vector type.
> To: <cfe-commits at lists.llvm.org>
>
>
> Author: rsmith
> Date: Wed Aug 14 15:57:50 2019
> New Revision: 368940
>
> URL: http://llvm.org/viewvc/llvm-project?rev=368940&view=rev
> Log:
> Fix handling of class member access into a vector type.
>
> When handling a member access into a non-class, non-ObjC-object type, we
> would perform a lookup into the surrounding scope as if for an
> unqualified lookup. If the member access was followed by a '<' and this
> lookup (or the typo-correction for it) found a template name, we'd treat
> the member access as naming that template.
>
> Now we treat such accesses as never naming a template if the type of the
> object expression is of vector type, so that vector component accesses
> are never misinterpreted as naming something else. This is not entirely
> correct, since it is in fact valid to name a template from the enclosing
> scope in this context, when invoking a pseudo-destructor for the vector
> type via an alias template, but that's very much a corner case, and this
> change leaves that case only as broken as the corresponding case for
> Objective-C types is.
>
> This incidentally adds support for dr2292, which permits a 'template'
> keyword at the start of a member access naming a pseudo-destructor.
>
> Modified:
> cfe/trunk/lib/Sema/SemaExprCXX.cpp
> cfe/trunk/lib/Sema/SemaTemplate.cpp
> cfe/trunk/test/CXX/drs/dr22xx.cpp
> cfe/trunk/test/CXX/drs/dr4xx.cpp
> cfe/trunk/test/SemaCXX/cxx2a-adl-only-template-id.cpp
> cfe/trunk/test/SemaCXX/pseudo-destructors.cpp
> cfe/trunk/test/SemaCXX/vector.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=368940&r1=368939&r2=368940&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Aug 14 15:57:50 2019
> @@ -6794,14 +6794,10 @@ ExprResult Sema::ActOnStartCXXMemberRefe
> // it's legal for the type to be incomplete if this is a pseudo-destructor
> // call. We'll do more incomplete-type checks later in the lookup process,
> // so just skip this check for ObjC types.
> - if (BaseType->isObjCObjectOrInterfaceType()) {
> + if (!BaseType->isRecordType()) {
> ObjectType = ParsedType::make(BaseType);
> MayBePseudoDestructor = true;
> return Base;
> - } else if (!BaseType->isRecordType()) {
> - ObjectType = nullptr;
> - MayBePseudoDestructor = true;
> - return Base;
> }
>
> // The object type must be complete (or dependent), or
>
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=368940&r1=368939&r2=368940&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Aug 14 15:57:50 2019
> @@ -362,13 +362,27 @@ bool Sema::LookupTemplateName(LookupResu
> // x->B::f, and we are looking into the type of the object.
> assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist");
> LookupCtx = computeDeclContext(ObjectType);
> - IsDependent = !LookupCtx;
> + IsDependent = !LookupCtx && ObjectType->isDependentType();
> assert((IsDependent || !ObjectType->isIncompleteType() ||
> ObjectType->castAs<TagType>()->isBeingDefined()) &&
> "Caller should have completed object type");
>
> - // Template names cannot appear inside an Objective-C class or object type.
> - if (ObjectType->isObjCObjectOrInterfaceType()) {
> + // Template names cannot appear inside an Objective-C class or object type
> + // or a vector type.
> + //
> + // FIXME: This is wrong. For example:
> + //
> + // template<typename T> using Vec = T __attribute__((ext_vector_type(4)));
> + // Vec<int> vi;
> + // vi.Vec<int>::~Vec<int>();
> + //
> + // ... should be accepted but we will not treat 'Vec' as a template name
> + // here. The right thing to do would be to check if the name is a valid
> + // vector component name, and look up a template name if not. And similarly
> + // for lookups into Objective-C class and object types, where the same
> + // problem can arise.
> + if (ObjectType->isObjCObjectOrInterfaceType() ||
> + ObjectType->isVectorType()) {
> Found.clear();
> return false;
> }
>
> Modified: cfe/trunk/test/CXX/drs/dr22xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr22xx.cpp?rev=368940&r1=368939&r2=368940&view=diff
> ==============================================================================
> --- cfe/trunk/test/CXX/drs/dr22xx.cpp (original)
> +++ cfe/trunk/test/CXX/drs/dr22xx.cpp Wed Aug 14 15:57:50 2019
> @@ -26,3 +26,12 @@ void f() {
> }
> }
> #endif
> +
> +namespace dr2292 { // dr2292: 9
> +#if __cplusplus >= 201103L
> + template<typename T> using id = T;
> + void test(int *p) {
> + p->template id<int>::~id<int>();
> + }
> +#endif
> +}
>
> Modified: cfe/trunk/test/CXX/drs/dr4xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?rev=368940&r1=368939&r2=368940&view=diff
> ==============================================================================
> --- cfe/trunk/test/CXX/drs/dr4xx.cpp (original)
> +++ cfe/trunk/test/CXX/drs/dr4xx.cpp Wed Aug 14 15:57:50 2019
> @@ -318,8 +318,8 @@ namespace dr420 { // dr420: yes
> q->~id<int>();
> p->id<int>::~id<int>();
> q->id<int>::~id<int>();
> - p->template id<int>::~id<int>(); // expected-error {{'template' keyword not permitted here}} expected-error {{base type 'int' is not a struct}}
> - q->template id<int>::~id<int>(); // expected-error {{'template' keyword not permitted here}} expected-error {{base type 'int' is not a struct}}
> + p->template id<int>::~id<int>(); // OK since dr2292
> + q->template id<int>::~id<int>(); // OK since dr2292
> p->A::template id<int>::~id<int>();
> q->A::template id<int>::~id<int>();
> }
>
> Modified: cfe/trunk/test/SemaCXX/cxx2a-adl-only-template-id.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-adl-only-template-id.cpp?rev=368940&r1=368939&r2=368940&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/cxx2a-adl-only-template-id.cpp (original)
> +++ cfe/trunk/test/SemaCXX/cxx2a-adl-only-template-id.cpp Wed Aug 14 15:57:50 2019
> @@ -65,3 +65,11 @@ void xf(g<int> x); // expected-error {{v
> struct B : g<int> { // expected-error {{expected class name}}
> B() : g<int>() {} // expected-error {{expected class member or base class name}}
> };
> +
> +namespace vector_components {
> + typedef __attribute__((__ext_vector_type__(2))) float vector_float2;
> + bool foo123(vector_float2 &A, vector_float2 &B)
> + {
> + return A.x < B.x && B.y > A.y;
> + }
> +}
>
> Modified: cfe/trunk/test/SemaCXX/pseudo-destructors.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pseudo-destructors.cpp?rev=368940&r1=368939&r2=368940&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/pseudo-destructors.cpp (original)
> +++ cfe/trunk/test/SemaCXX/pseudo-destructors.cpp Wed Aug 14 15:57:50 2019
> @@ -34,7 +34,7 @@ void f(A* a, Foo *f, int *i, double *d,
> g().~Bar(); // expected-error{{non-scalar}}
>
> f->::~Bar();
> - f->N::~Wibble(); // FIXME: technically, Wibble isn't a class-name
> + f->N::~Wibble(); // expected-error{{'N' does not refer to a type}} expected-error{{'Wibble' does not refer to a type}}
>
> f->::~Bar(17, 42); // expected-error{{cannot have any arguments}}
>
> @@ -79,7 +79,7 @@ namespace PR11339 {
> template<class T>
> void destroy(T* p) {
> p->~T(); // ok
> - p->~oops(); // expected-error{{expected the class name after '~' to name a destructor}}
> + p->~oops(); // expected-error{{identifier 'oops' in object destruction expression does not name a type}}
> }
>
> template void destroy(int*); // expected-note{{in instantiation of function template specialization}}
>
> Modified: cfe/trunk/test/SemaCXX/vector.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vector.cpp?rev=368940&r1=368939&r2=368940&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/vector.cpp (original)
> +++ cfe/trunk/test/SemaCXX/vector.cpp Wed Aug 14 15:57:50 2019
> @@ -342,3 +342,19 @@ void test_vector_literal(inte4 res) {
> inte4 b = (inte4)(a, a); //expected-error{{C-style cast from vector 'inte2' (vector of 2 'int' values) to vector 'inte4' (vector of 4 'int' values) of different size}} //expected-warning{{expression result unused}}
> }
>
> +typedef __attribute__((__ext_vector_type__(4))) float vector_float4;
> +typedef __attribute__((__ext_vector_type__(4))) int vector_int4;
> +
> +namespace swizzle_template_confusion {
> + template<typename T> struct xyzw {};
> + vector_int4 foo123(vector_float4 &A, vector_float4 &B) {
> + return A.xyzw < B.x && B.y > A.y; // OK, not a template-id
> + }
> +}
> +
> +namespace swizzle_typo_correction {
> + template<typename T> struct xyzv {};
> + vector_int4 foo123(vector_float4 &A, vector_float4 &B) {
> + return A.xyzw < B.x && B.y > A.y; // OK, not a typo for 'xyzv'
> + }
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list