summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-08-14 22:57:50 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-08-14 22:57:50 +0000
commite88444ece6df0a3685bd7b8e80a7a9ab43fa17e8 (patch)
treede0725ab1e4465cac8d31cd69f31e668d318310d /lib/Sema/SemaTemplate.cpp
parent68afe3d5dccef33e028c8a1f9609852396e7217a (diff)
downloadclang-e88444ece6df0a3685bd7b8e80a7a9ab43fa17e8.tar.gz
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368940 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp20
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 3df74edf2f..ce0c2ef402 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -362,13 +362,27 @@ bool Sema::LookupTemplateName(LookupResult &Found,
// 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;
}