diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-07-10 20:53:43 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-07-10 20:53:43 +0000 |
commit | 95b83e917e40bafd7e5bf0a4cdc592745b3b1fcc (patch) | |
tree | 1986b9372b0df622f7c861e17b6ce74c887aa0db | |
parent | 31fd9d09b2ac07e0bae0a81d387db89d5090769d (diff) | |
download | llvm-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.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 7 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/value-init.cpp | 53 |
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 |