[cfe-commits] r89042 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprCXX.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/class-template-spec.cpp test/SemaTemplate/member-function-template.cpp
Douglas Gregor
dgregor at apple.com
Mon Nov 16 21:17:33 PST 2009
Author: dgregor
Date: Mon Nov 16 23:17:33 2009
New Revision: 89042
URL: http://llvm.org/viewvc/llvm-project?rev=89042&view=rev
Log:
Require the object type of a member access expression ("." or "->") to
be complete.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/class-template-spec.cpp
cfe/trunk/test/SemaTemplate/member-function-template.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=89042&r1=89041&r2=89042&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Nov 16 23:17:33 2009
@@ -401,7 +401,9 @@
"lookup from the current scope refers here">;
def err_qualified_member_nonclass : Error<
"qualified member access refers to a member in %0">;
-
+def err_incomplete_member_access : Error<
+ "member access into incomplete type %0">;
+
// C++ class members
def err_storageclass_invalid_for_member : Error<
"storage class specified for a member declaration">;
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=89042&r1=89041&r2=89042&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Nov 16 23:17:33 2009
@@ -2141,12 +2141,19 @@
return move(Base);
}
+ // The object type must be complete (or dependent).
+ if (!BaseType->isDependentType() &&
+ RequireCompleteType(OpLoc, BaseType,
+ PDiag(diag::err_incomplete_member_access)))
+ return ExprError();
+
// C++ [basic.lookup.classref]p2:
// If the id-expression in a class member access (5.2.5) is an
- // unqualified-id, and the type of the object expres- sion is of a class
+ // unqualified-id, and the type of the object expression is of a class
// type C (or of pointer to a class type C), the unqualified-id is looked
// up in the scope of class C. [...]
ObjectType = BaseType.getAsOpaquePtr();
+
return move(Base);
}
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=89042&r1=89041&r2=89042&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Nov 16 23:17:33 2009
@@ -130,12 +130,17 @@
QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
LookupCtx = computeDeclContext(ObjectType);
isDependent = ObjectType->isDependentType();
+ assert((isDependent || !ObjectType->isIncompleteType()) &&
+ "Caller should have completed object type");
} else if (SS.isSet()) {
// This nested-name-specifier occurs after another nested-name-specifier,
// so long into the context associated with the prior nested-name-specifier.
-
LookupCtx = computeDeclContext(SS, EnteringContext);
isDependent = isDependentScopeSpecifier(SS);
+
+ // The declaration context must be complete.
+ if (LookupCtx && RequireCompleteDeclContext(SS))
+ return TNK_Non_template;
}
LookupResult Found(*this, TName, SourceLocation(), LookupOrdinaryName);
@@ -145,11 +150,6 @@
// computed, which is either the type of the base of a member access
// expression or the declaration context associated with a prior
// nested-name-specifier.
-
- // The declaration context must be complete.
- if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
- return TNK_Non_template;
-
LookupQualifiedName(Found, LookupCtx);
if (ObjectTypePtr && Found.empty()) {
Modified: cfe/trunk/test/SemaTemplate/class-template-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-spec.cpp?rev=89042&r1=89041&r2=89042&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/class-template-spec.cpp (original)
+++ cfe/trunk/test/SemaTemplate/class-template-spec.cpp Mon Nov 16 23:17:33 2009
@@ -19,7 +19,7 @@
int test_incomplete_specs(A<double, double> *a1,
A<double> *a2)
{
- (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}}
+ (void)a1->x; // expected-error{{member access into incomplete type}}
(void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}}
}
Modified: cfe/trunk/test/SemaTemplate/member-function-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/member-function-template.cpp?rev=89042&r1=89041&r2=89042&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/member-function-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/member-function-template.cpp Mon Nov 16 23:17:33 2009
@@ -60,3 +60,16 @@
void test_Functor(Functor f) {
f(1);
}
+
+// Instantiation on ->
+template<typename T>
+struct X1 {
+ template<typename U> U& get();
+};
+
+template<typename T> struct X2; // expected-note{{here}}
+
+void test_incomplete_access(X1<int> *x1, X2<int> *x2) {
+ float &fr = x1->get<float>();
+ (void)x2->get<float>(); // expected-error{{implicit instantiation of undefined template}}
+}
More information about the cfe-commits
mailing list