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