mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 18:46:04 +00:00
C++ constant expression handling: eagerly instantiate static const integral data
members of class templates so that their values can be used in ICEs. This required reverting r105465, to get such instantiated members to be included in serialized ASTs. llvm-svn: 147023
This commit is contained in:
parent
1d8efaba7e
commit
ed2974f3cf
@ -9526,7 +9526,12 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
|
||||
// This is a modification of an existing AST node. Notify listeners.
|
||||
if (ASTMutationListener *L = getASTMutationListener())
|
||||
L->StaticDataMemberInstantiated(Var);
|
||||
PendingInstantiations.push_back(std::make_pair(Var, Loc));
|
||||
QualType T = Var->getType();
|
||||
if (T.isConstQualified() && !T.isVolatileQualified() &&
|
||||
T->isIntegralOrEnumerationType())
|
||||
InstantiateStaticDataMemberDefinition(Loc, Var);
|
||||
else
|
||||
PendingInstantiations.push_back(std::make_pair(Var, Loc));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,8 +359,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
||||
SemaRef.CheckVariableDeclaration(Var, Previous);
|
||||
|
||||
if (D->isOutOfLine()) {
|
||||
if (!D->isStaticDataMember())
|
||||
D->getLexicalDeclContext()->addDecl(Var);
|
||||
D->getLexicalDeclContext()->addDecl(Var);
|
||||
Owner->makeDeclVisibleInContext(Var);
|
||||
} else {
|
||||
Owner->addDecl(Var);
|
||||
|
@ -38,9 +38,12 @@ template<typename T> struct TestBaseSpecifiers2 : TestBaseSpecifiers<T> { };
|
||||
template <typename T>
|
||||
struct TS3 {
|
||||
static const int value = 0;
|
||||
static const int value2;
|
||||
};
|
||||
template <typename T>
|
||||
const int TS3<T>::value;
|
||||
template <typename T>
|
||||
const int TS3<T>::value2 = 1;
|
||||
// Instantiate struct, but not value.
|
||||
struct instantiate : TS3<int> {};
|
||||
|
||||
@ -96,8 +99,9 @@ struct TestBaseSpecifiers4 : TestBaseSpecifiers3 { };
|
||||
struct A { };
|
||||
struct B : A { };
|
||||
|
||||
// Instantiate TS3's member.
|
||||
// Instantiate TS3's members.
|
||||
static const int ts3m1 = TS3<int>::value;
|
||||
extern int arr[TS3<int>::value2];
|
||||
|
||||
// Redefinition of typedef
|
||||
typedef int Integer;
|
||||
@ -132,6 +136,7 @@ void test() {
|
||||
|
||||
// Should have remembered that there is a definition.
|
||||
static const int ts3m2 = TS3<int>::value;
|
||||
int arr[TS3<int>::value2];
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
#endif
|
||||
|
@ -31,4 +31,4 @@ struct X1 {
|
||||
template<typename T>
|
||||
const unsigned X1<T>::value = sizeof(T);
|
||||
|
||||
int array3[X1<int>::value == sizeof(int)? 1 : -1]; // expected-error{{variable length array declaration not allowed at file scope}}
|
||||
int array3[X1<int>::value == sizeof(int)? 1 : -1];
|
||||
|
Loading…
x
Reference in New Issue
Block a user