Changeset View
Changeset View
Standalone View
Standalone View
clang/test/SemaCXX/attr-gsl-owner-pointer-std.cpp
- This file was added.
// RUN: %clang_cc1 -ast-dump %s | \ | |||||
// RUN: FileCheck --implicit-check-not OwnerAttr --implicit-check-not PointerAttr %s | |||||
// Test attribute inference for types in the standard library. | |||||
namespace std { | |||||
// Attributes are inferred for a (complete) class. | |||||
class any { | |||||
// CHECK: CXXRecordDecl {{.*}} any | |||||
// CHECK: OwnerAttr {{.*}} | |||||
}; | |||||
// Attributes are inferred for instantiations of a complete template. | |||||
template <typename T> | |||||
class vector { | |||||
public: | |||||
class iterator {}; | |||||
// CHECK: ClassTemplateDecl {{.*}} vector | |||||
// CHECK: OwnerAttr {{.*}} | |||||
// CHECK: CXXRecordDecl {{.*}} iterator | |||||
// CHECK: PointerAttr {{.*}} | |||||
// CHECK: ClassTemplateSpecializationDecl {{.*}} vector | |||||
// CHECK: TemplateArgument type 'int' | |||||
// CHECK: OwnerAttr | |||||
// CHECK: CXXRecordDecl {{.*}} iterator | |||||
// CHECK: PointerAttr {{.*}} | |||||
}; | |||||
static_assert(sizeof(vector<int>), ""); // Force instantiation. | |||||
static_assert(sizeof(vector<int>::iterator), ""); // Force instantiation. | |||||
// If std::container::iterator is a using declaration, attributes are inferred | |||||
// for the underlying class. | |||||
template <typename T> | |||||
class __set_iterator {}; | |||||
// CHECK: ClassTemplateDecl {{.*}} __set_iterator | |||||
// CHECK: PointerAttr | |||||
// CHECK: ClassTemplateSpecializationDecl {{.*}} __set_iterator | |||||
// CHECK: TemplateArgument type 'int' | |||||
// CHECK: PointerAttr | |||||
template <typename T> | |||||
class set { | |||||
// CHECK: ClassTemplateDecl {{.*}} set | |||||
// CHECK: OwnerAttr {{.*}} | |||||
// CHECK: ClassTemplateSpecializationDecl {{.*}} set | |||||
// CHECK: OwnerAttr {{.*}} | |||||
public: | |||||
using iterator = __set_iterator<T>; | |||||
}; | |||||
static_assert(sizeof(set<int>::iterator), ""); // Force instantiation. | |||||
// If std::container::iterator is a typedef, attributes are inferred for the | |||||
// underlying class. | |||||
template <typename T> | |||||
class __map_iterator {}; | |||||
// CHECK: ClassTemplateDecl {{.*}} __map_iterator | |||||
// CHECK: PointerAttr | |||||
// CHECK: ClassTemplateSpecializationDecl {{.*}} __map_iterator | |||||
// CHECK: TemplateArgument type 'int' | |||||
// CHECK: PointerAttr | |||||
template <typename T> | |||||
class map { | |||||
// CHECK: ClassTemplateDecl {{.*}} map | |||||
// CHECK: OwnerAttr {{.*}} | |||||
// CHECK: ClassTemplateSpecializationDecl {{.*}} map | |||||
// CHECK: OwnerAttr {{.*}} | |||||
public: | |||||
typedef __map_iterator<T> iterator; | |||||
}; | |||||
static_assert(sizeof(map<int>::iterator), ""); // Force instantiation. | |||||
// Inline namespaces are ignored when checking if | |||||
// the class lives in the std namespace. | |||||
inline namespace inlinens { | |||||
template <typename T> | |||||
class __unordered_map_iterator {}; | |||||
// CHECK: ClassTemplateDecl {{.*}} __unordered_map_iterator | |||||
// CHECK: PointerAttr | |||||
// CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_map_iterator | |||||
// CHECK: TemplateArgument type 'int' | |||||
// CHECK: PointerAttr | |||||
template <typename T> | |||||
class unordered_map { | |||||
// CHECK: ClassTemplateDecl {{.*}} unordered_map | |||||
// CHECK: OwnerAttr {{.*}} | |||||
// CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_map | |||||
// CHECK: OwnerAttr {{.*}} | |||||
public: | |||||
typedef __unordered_map_iterator<T> iterator; | |||||
}; | |||||
static_assert(sizeof(unordered_map<int>::iterator), ""); // Force instantiation. | |||||
} // namespace inlinens | |||||
// std::list has an implicit gsl::Owner attribute, | |||||
// but explicit attributes take precedence. | |||||
template <typename T> | |||||
class [[gsl::Pointer]] list{}; | |||||
// CHECK: ClassTemplateDecl {{.*}} list | |||||
// CHECK: PointerAttr {{.*}} | |||||
// CHECK: ClassTemplateSpecializationDecl {{.*}} list | |||||
// CHECK: PointerAttr {{.*}} | |||||
static_assert(sizeof(list<int>), ""); // Force instantiation. | |||||
// Forward declared template (Owner). | |||||
template < | |||||
class CharT, | |||||
class Traits> | |||||
class basic_regex; | |||||
// CHECK: ClassTemplateDecl {{.*}} basic_regex | |||||
// CHECK: OwnerAttr {{.*}} | |||||
// Forward declared template (Pointer). | |||||
template <class T> | |||||
class reference_wrapper; | |||||
// CHECK: ClassTemplateDecl {{.*}} reference_wrapper | |||||
// CHECK: PointerAttr {{.*}} | |||||
class some_unknown_type; | |||||
// CHECK: CXXRecordDecl {{.*}} some_unknown_type | |||||
} // namespace std | |||||
namespace user { | |||||
// If a class is not in the std namespace, we don't infer the attributes. | |||||
class any { | |||||
}; | |||||
} // namespace user |