aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-07-10 20:53:43 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-07-10 20:53:43 +0000
commit95b83e917e40bafd7e5bf0a4cdc592745b3b1fcc (patch)
tree1986b9372b0df622f7c861e17b6ce74c887aa0db
parent31fd9d09b2ac07e0bae0a81d387db89d5090769d (diff)
downloadllvm-95b83e917e40bafd7e5bf0a4cdc592745b3b1fcc.zip
llvm-95b83e917e40bafd7e5bf0a4cdc592745b3b1fcc.tar.gz
llvm-95b83e917e40bafd7e5bf0a4cdc592745b3b1fcc.tar.bz2
PR20256: don't accidentally instantiate non-dependent default-initialization as
value-initialization. llvm-svn: 212764
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp5
-rw-r--r--clang/lib/Sema/TreeTransform.h7
-rw-r--r--clang/test/CodeGenCXX/value-init.cpp53
3 files changed, 63 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index c655d3f..accec95 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3679,8 +3679,9 @@ void Sema::InstantiateVariableInitializer(
bool TypeMayContainAuto = true;
Expr *InitExpr = Init.get();
- if (Var->hasAttr<DLLImportAttr>() && InitExpr &&
- !InitExpr->isConstantInitializer(getASTContext(), false)) {
+ if (Var->hasAttr<DLLImportAttr>() &&
+ (!InitExpr ||
+ !InitExpr->isConstantInitializer(getASTContext(), false))) {
// Do not dynamically initialize dllimport variables.
} else if (InitExpr) {
bool DirectInit = OldVar->isDirectInit();
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 5626ad5..269a3bd 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2891,6 +2891,13 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
// Build a ParenListExpr to represent anything else.
SourceRange Parens = Construct->getParenOrBraceRange();
+ if (Parens.isInvalid()) {
+ // This was a variable declaration's initialization for which no initializer
+ // was specified.
+ assert(NewArgs.empty() &&
+ "no parens or braces but have direct init with arguments?");
+ return ExprEmpty();
+ }
return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
Parens.getEnd());
}
diff --git a/clang/test/CodeGenCXX/value-init.cpp b/clang/test/CodeGenCXX/value-init.cpp
index fad459b..423d973 100644
--- a/clang/test/CodeGenCXX/value-init.cpp
+++ b/clang/test/CodeGenCXX/value-init.cpp
@@ -262,6 +262,59 @@ namespace PR11124 {
void r170806_a(bool b = bool());
void r170806_b() { r170806_a(); }
+namespace PR20256 {
+ struct data { int i; };
+
+ template<typename T = int>
+ data g() {
+ data d; // not value-init
+ return d;
+ }
+ template data g();
+ // CHECK-LABEL: define {{.*}} @_ZN7PR202561gIiEENS_4dataEv(
+ // CHECK-NOT: store
+ // CHECK-NOT: memset
+ // CHECK: }
+
+ template<typename ...T>
+ data h(T ...t) {
+ data d(t...); // value-init
+ return d;
+ }
+ template data h();
+ // CHECK-LABEL: define {{.*}} @_ZN7PR202561hIJEEENS_4dataEDpT_(
+ // CHECK: call void @llvm.memset
+ // CHECK: }
+
+
+ template<typename T = int>
+ data j() {
+ data d = {}; // value-init
+ return d;
+ }
+ template data j();
+ // CHECK-LABEL: define {{.*}} @_ZN7PR202561jIiEENS_4dataEv(
+ // CHECK: call void @llvm.memset
+ // CHECK: }
+
+ data f() {
+ data d; // not value-init
+ return d;
+ }
+ // CHECK-LABEL: define {{.*}} @_ZN7PR202561fEv(
+ // CHECK-NOT: store
+ // CHECK-NOT: memset
+ // CHECK: }
+
+ data i() {
+ data d = {}; // value-init
+ return d;
+ }
+ // CHECK-LABEL: define {{.*}} @_ZN7PR202561iEv(
+ // CHECK: call void @llvm.memset
+ // CHECK: }
+}
+
// CHECK-LABEL: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
// CHECK: call void @llvm.memset.p0i8.i64
// CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev