aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2012-02-22 09:07:21 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2012-02-22 09:07:21 +0000
commit428c620478d513081399798db5550bf0c779f244 (patch)
tree28ec148f5280a4bbcca6db65eaf1263983c26c9f
parentd77177a752a08abf3f5cf46d7a3fe6143325815d (diff)
Throw away stray CXXDefaultArgExprs. Fixes PR12061.
I think there's a deeper problem here in the way TransformCXXConstructExpr works, but I won't tackle it now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151146 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExprCXX.cpp7
-rw-r--r--test/SemaCXX/new-delete.cpp40
2 files changed, 47 insertions, 0 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index c8e640f191..30f143a825 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1018,6 +1018,13 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
} else if (Initializer && isa<InitListExpr>(Initializer))
initStyle = CXXNewExpr::ListInit;
else {
+ // In template instantiation, the initializer could be a CXXDefaultArgExpr
+ // unwrapped from a CXXConstructExpr that was implicitly built. There is no
+ // particularly sane way we can handle this (especially since it can even
+ // occur for array new), so we throw the initializer away and have it be
+ // rebuilt.
+ if (Initializer && isa<CXXDefaultArgExpr>(Initializer))
+ Initializer = 0;
assert((!Initializer || isa<ImplicitValueInitExpr>(Initializer) ||
isa<CXXConstructExpr>(Initializer)) &&
"Initializer expression that cannot have been implicitly created.");
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index d355c7cc51..579ec33a43 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -460,3 +460,43 @@ namespace P12023 {
return 0;
}
}
+
+namespace PR12061 {
+ template <class C> struct scoped_array {
+ scoped_array(C* p = __null);
+ };
+ template <class Payload> struct Foo {
+ Foo() : a_(new scoped_array<int>[5]) { }
+ scoped_array< scoped_array<int> > a_;
+ };
+ class Bar {};
+ Foo<Bar> x;
+
+ template <class C> struct scoped_array2 {
+ scoped_array2(C* p = __null, C* q = __null);
+ };
+ template <class Payload> struct Foo2 {
+ Foo2() : a_(new scoped_array2<int>[5]) { }
+ scoped_array2< scoped_array2<int> > a_;
+ };
+ class Bar2 {};
+ Foo2<Bar2> x2;
+
+ class MessageLoop {
+ public:
+ explicit MessageLoop(int type = 0);
+ };
+ template <class CookieStoreTestTraits>
+ class CookieStoreTest {
+ protected:
+ CookieStoreTest() {
+ new MessageLoop;
+ }
+ };
+ struct CookieMonsterTestTraits {
+ };
+ class DeferredCookieTaskTest : public CookieStoreTest<CookieMonsterTestTraits>
+ {
+ DeferredCookieTaskTest() {}
+ };
+}