From: Richard Smith Date: Thu, 10 Jul 2014 20:53:43 +0000 (+0000) Subject: PR20256: don't accidentally instantiate non-dependent default-initialization as X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=47e86a87ac5926d8d469d3bba41596e86bac3fab;p=clang PR20256: don't accidentally instantiate non-dependent default-initialization as value-initialization. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@212764 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index c655d3f86b..accec95bf7 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3679,8 +3679,9 @@ void Sema::InstantiateVariableInitializer( bool TypeMayContainAuto = true; Expr *InitExpr = Init.get(); - if (Var->hasAttr() && InitExpr && - !InitExpr->isConstantInitializer(getASTContext(), false)) { + if (Var->hasAttr() && + (!InitExpr || + !InitExpr->isConstantInitializer(getASTContext(), false))) { // Do not dynamically initialize dllimport variables. } else if (InitExpr) { bool DirectInit = OldVar->isDirectInit(); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 5626ad5924..269a3bd8a8 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2891,6 +2891,13 @@ ExprResult TreeTransform::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/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp index fad459b481..423d9736b4 100644 --- a/test/CodeGenCXX/value-init.cpp +++ b/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 + 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 + 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 + 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