[prev in list] [next in list] [prev in thread] [next in thread]
List: cfe-commits
Subject: [cfe-commits] [PATCH] Fix copy-list-initialization in template instantiation.
From: Olivier Goffart <ogoffart () kde ! org>
Date: 2012-12-10 9:44:37
Message-ID: 4048950.4eguVddmco () gargamel
[Download RAW message or body]
Hi,
Attached you will find a suggested fix for
http://llvm.org/bugs/show_bug.cgi?id=14486 and
http://llvm.org/bugs/show_bug.cgi?id=13470
Regards
--
Olivier
["0001-Fix-copy-list-initialization-in-template-instentiati.patch" (0001-Fix-copy-list-initialization-in-template-instentiati.patch)]
From eb748636b150a035c1b8c80ea7ecec27a4b90f22 Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoffart@woboq.com>
Date: Sat, 8 Dec 2012 12:35:15 +0100
Subject: [PATCH] Fix copy-list-initialization in template instentiation.
Fix for http://llvm.org/bugs/show_bug.cgi?id=14486
While parsing, Parser::ParseDeclarationAfterDeclaratorAndAttributes
calls Sema::AddInitializerToDecl with the init expresison is an
InitListExpr*. Then InitializationSequence::Perform is called with
SK_ListConstructorCall, which will call PerformConstructorInitialization
As a result, the initializer is now a CXXConstructExpr*, but the
initialisation type is still copy.
Later, while intensiating, TemplateDeclInstantiator::VisitVarDecl also
calls Sema::AddInitializerToDecl with the CXXConstructExpr* and the type
copy, as we lost the information this was a copy-list-initialization,
the code will try to perform a copy by calling the copy constructor.
This is an error if the copy constructor was deleted.
Note: if the CXXConstructExpr only has one argument,
Sema::SubstInitializer will take that argument out, and AddInitializer
will be called with that argument
This patch does 2 things to solve that problem:
1) If we try to add a CXXConstructExpr, th direct initialisation, it
means the initialisation was already performed. So we need not to
do the InitializationSequence.
2) We remember that the declaration's init style is VarDecl::ListInit
As a result, TemplateDeclInstantiator::VisitVarDecl will pass true
for the DirectInit parametter to AddInitializerToDecl.
That will cause the kind to be IK_DirectList in the constructor of
InitializationSequence, we need to generate a constructor call in
that case too. That is usefull for the cases where we had only one
argument to the constructor
---
lib/Sema/SemaDecl.cpp | 15 ++++++--
lib/Sema/SemaInit.cpp | 1 +
test/SemaCXX/cxx0x-initializer-constructor.cpp | 48 ++++++++++++++++++++++++++
3 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9dd7779..8b88894 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -6721,8 +6721,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
Init = Result.take();
}
- // Perform the initialization.
- if (!VDecl->isInvalidDecl()) {
+ if (VDecl->isInvalidDecl()) {
+ } else if (DirectInit && isa<CXXConstructExpr>(Init)) {
+ //We already have performed the initialisation
+ assert(cast<CXXConstructExpr>(Init)->getType() == DclT);
+ } else {
+ // Perform the initialization.
InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
InitializationKind Kind
= DirectInit ?
@@ -6740,6 +6744,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
Args = CXXDirectInit->getExprs();
NumArgs = CXXDirectInit->getNumExprs();
}
+
InitializationSequence InitSeq(*this, Entity, Kind, Args, NumArgs);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
MultiExprArg(Args, NumArgs), &DclT);
@@ -6748,6 +6753,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
return;
}
+ if (getLangOpts().CPlusPlus0x && !DirectInit && isa<InitListExpr>(Init)
+ && !isa<InitListExpr>(Result.get())) {
+ // Remember this was a copy-list-initialization
+ VDecl->setInitStyle(VarDecl::ListInit);
+ }
+
Init = Result.takeAs<Expr>();
}
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 48b0d1f..2d56676 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -4150,6 +4150,7 @@ InitializationSequence::InitializationSequence(Sema &S,
// source type is the same class as, or a derived class of, the
// class of the destination, constructors are considered. [...]
if (Kind.getKind() == InitializationKind::IK_Direct ||
+ Kind.getKind() == InitializationKind::IK_DirectList ||
(Kind.getKind() == InitializationKind::IK_Copy &&
(Context.hasSameUnqualifiedType(SourceType, DestType) ||
S.IsDerivedFrom(SourceType, DestType))))
diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp \
b/test/SemaCXX/cxx0x-initializer-constructor.cpp index a657ec8..44d6228 100644
--- a/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -320,3 +320,51 @@ namespace rdar11974632 {
Y<int> yi;
}
+
+namespace PR14486 {
+ struct A {
+ A() {}
+ A(int) {}
+ };
+ struct X {
+ X(const X&) = delete; // expected-note 4 {{marked deleted here}}
+ X(int) {}
+ X(int, int) {}
+ X(const A&) {}
+ explicit X(double) {} // expected-note 2 {{here}}
+ explicit X(double,double) {} // expected-note 2 {{here}}
+ };
+ template<typename T>
+ struct Y {
+ static void f1() {
+ X x1{1.};
+ X x2 = {1};
+ X x3 = {1.}; // expected-error{{chosen constructor is explicit}}
+ X x6 = {1, 1};
+ X x7 = {1., 1.}; // expected-error{{chosen constructor is explicit}}
+ X x8 = 1; //expected-error{{invokes deleted constructor}}
+ X x9 = {A()};
+ X x10{A()};
+ X x11 = {A(0)};
+ X x12{A(0)};
+ X x13 = A(); //expected-error{{invokes deleted constructor}}
+ }
+ static void f2() {
+ T x1{1.};
+ T x2 = {1};
+ T x3 = {1.}; // expected-error{{chosen constructor is explicit}}
+ T x6 = {1, 1};
+ T x7 = {1., 1.}; // expected-error{{chosen constructor is explicit}}
+ T x8 = 1; //expected-error{{invokes deleted constructor}}
+ T x9 = {A()};
+ T x10{A()};
+ T x11 = {A(0)};
+ T x12{A(0)};
+ T x13 = A(); //expected-error{{invokes deleted constructor}}
+ }
+ };
+ void f() {
+ Y<X>::f1();
+ Y<X>::f2(); // expected-note{{requested here}}
+ }
+}
--
1.7.12.1
_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic