aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2014-08-04 18:37:31 +0000
committerBill Wendling <isanbard@gmail.com>2014-08-04 18:37:31 +0000
commit001a4b73cd6f6c51bff07f8dccb29385967fa941 (patch)
tree11d15a90822e66f0c9592952968f7a452b316275 /clang
parent405f701d60d3952c8f4a65997edfa3c2150bfed4 (diff)
downloadllvm-001a4b73cd6f6c51bff07f8dccb29385967fa941.zip
llvm-001a4b73cd6f6c51bff07f8dccb29385967fa941.tar.gz
llvm-001a4b73cd6f6c51bff07f8dccb29385967fa941.tar.bz2
Merging r213913:
------------------------------------------------------------------------ r213913 | rsmith | 2014-07-24 18:12:44 -0700 (Thu, 24 Jul 2014) | 4 lines PR20445: Properly transform the initializer in a CXXNewExpr rather than running it through the normal TreeTransform logic for Exprs (which will strip off implicit parts of the initialization and never re-create them). ------------------------------------------------------------------------ llvm-svn: 214750
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp11
-rw-r--r--clang/lib/Sema/TreeTransform.h16
-rw-r--r--clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp10
3 files changed, 19 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 7fe5e7a..0dabdca 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1184,14 +1184,6 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
NumInits = List->getNumExprs();
}
- // Determine whether we've already built the initializer.
- bool HaveCompleteInit = false;
- if (Initializer && isa<CXXConstructExpr>(Initializer) &&
- !isa<CXXTemporaryObjectExpr>(Initializer))
- HaveCompleteInit = true;
- else if (Initializer && isa<ImplicitValueInitExpr>(Initializer))
- HaveCompleteInit = true;
-
// C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
if (TypeMayContainAuto && AllocType->isUndeducedType()) {
if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
@@ -1481,8 +1473,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
// do it now.
if (!AllocType->isDependentType() &&
!Expr::hasAnyTypeDependentArguments(
- llvm::makeArrayRef(Inits, NumInits)) &&
- !HaveCompleteInit) {
+ llvm::makeArrayRef(Inits, NumInits))) {
// C++11 [expr.new]p15:
// A new-expression that creates an object of type T initializes that
// object as follows:
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 34d13c9..312811d 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -344,7 +344,7 @@ public:
/// TransformExpr or TransformExprs.
///
/// \returns the transformed initializer.
- ExprResult TransformInitializer(Expr *Init, bool CXXDirectInit);
+ ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
/// \brief Transform the given list of expressions.
///
@@ -2858,7 +2858,7 @@ ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
template<typename Derived>
ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
- bool CXXDirectInit) {
+ bool NotCopyInit) {
// Initializers are instantiated like expressions, except that various outer
// layers are stripped.
if (!Init)
@@ -2878,13 +2878,13 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
if (CXXStdInitializerListExpr *ILE =
dyn_cast<CXXStdInitializerListExpr>(Init))
- return TransformInitializer(ILE->getSubExpr(), CXXDirectInit);
+ return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
- // If this is not a direct-initializer, we only need to reconstruct
+ // If this is copy-initialization, we only need to reconstruct
// InitListExprs. Other forms of copy-initialization will be a no-op if
// the initializer is already the right type.
CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
- if (!CXXDirectInit && !(Construct && Construct->isListInitialization()))
+ if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
return getDerived().TransformExpr(Init);
// Revert value-initialization back to empty parens.
@@ -2907,12 +2907,12 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
// If the initialization implicitly converted an initializer list to a
// std::initializer_list object, unwrap the std::initializer_list too.
if (Construct && Construct->isStdInitListInitialization())
- return TransformInitializer(Construct->getArg(0), CXXDirectInit);
+ return TransformInitializer(Construct->getArg(0), NotCopyInit);
SmallVector<Expr*, 8> NewArgs;
bool ArgChanged = false;
if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
- /*IsCall*/true, NewArgs, &ArgChanged))
+ /*IsCall*/true, NewArgs, &ArgChanged))
return ExprError();
// If this was list initialization, revert to list form.
@@ -8124,7 +8124,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
Expr *OldInit = E->getInitializer();
ExprResult NewInit;
if (OldInit)
- NewInit = getDerived().TransformExpr(OldInit);
+ NewInit = getDerived().TransformInitializer(OldInit, true);
if (NewInit.isInvalid())
return ExprError();
diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
index 33bd844..4d30344 100644
--- a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -455,3 +455,13 @@ namespace ArrayOfInitList {
};
S x[1] = {};
}
+
+namespace PR20445 {
+ struct vector { vector(std::initializer_list<int>); };
+ struct MyClass { explicit MyClass(const vector &v); };
+ template<int x> void f() { new MyClass({42, 43}); }
+ template void f<0>();
+ // CHECK-LABEL: define {{.*}} @_ZN7PR204451fILi0EEEvv(
+ // CHECK: call void @_ZN7PR204456vectorC1ESt16initializer_listIiE(
+ // CHECK: call void @_ZN7PR204457MyClassC1ERKNS_6vectorE(
+}