When we attempt to create a temporary object of class type, be sure
that the type we're copying is complete.
Boost.Regex now builds, although it's failing its regression tests
with our favorite "Sema doesn't consider destructor as used."
assertion.
llvm-svn: 102271
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d265666..aa1e062 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -720,7 +720,9 @@
"object|copying member subobject|copying array element|allocating object|"
"copying temporary|initializing base subobject|initializing vector element}0 "
"of type %1 invokes deleted constructor">;
-
+def err_temp_copy_incomplete : Error<
+ "copying a temporary object of incomplete type %0">;
+
// C++0x decltype
def err_cannot_determine_declared_type_of_overloaded_function : Error<
"cannot determine the %select{type|declared type}0 of an overloaded "
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index d552b16..ea430bb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3232,7 +3232,11 @@
Loc = CurInitExpr->getLocStart();
break;
}
-
+
+ // Make sure that the type we are copying is complete.
+ if (S.RequireCompleteType(Loc, T, S.PDiag(diag::err_temp_copy_incomplete)))
+ return move(CurInit);
+
// Perform overload resolution using the class's copy constructors.
DeclarationName ConstructorName
= S.Context.DeclarationNames.getCXXConstructorName(
diff --git a/clang/test/SemaTemplate/instantiate-complete.cpp b/clang/test/SemaTemplate/instantiate-complete.cpp
index bc91112..d854c9e 100644
--- a/clang/test/SemaTemplate/instantiate-complete.cpp
+++ b/clang/test/SemaTemplate/instantiate-complete.cpp
@@ -84,3 +84,18 @@
template struct Y<int, float>;
}
+
+namespace TemporaryObjectCopy {
+ // Make sure we instantiate classes when we create a temporary copy.
+ template<typename T>
+ struct X {
+ X(T);
+ };
+
+ template<typename T>
+ void f(T t) {
+ const X<int> &x = X<int>(t);
+ }
+
+ template void f(int);
+}