Skip to content

Commit 95b83e9

Browse files
committed
PR20256: don't accidentally instantiate non-dependent default-initialization as
value-initialization. llvm-svn: 212764
1 parent 31fd9d0 commit 95b83e9

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3679,8 +3679,9 @@ void Sema::InstantiateVariableInitializer(
36793679
bool TypeMayContainAuto = true;
36803680
Expr *InitExpr = Init.get();
36813681

3682-
if (Var->hasAttr<DLLImportAttr>() && InitExpr &&
3683-
!InitExpr->isConstantInitializer(getASTContext(), false)) {
3682+
if (Var->hasAttr<DLLImportAttr>() &&
3683+
(!InitExpr ||
3684+
!InitExpr->isConstantInitializer(getASTContext(), false))) {
36843685
// Do not dynamically initialize dllimport variables.
36853686
} else if (InitExpr) {
36863687
bool DirectInit = OldVar->isDirectInit();

clang/lib/Sema/TreeTransform.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2891,6 +2891,13 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
28912891

28922892
// Build a ParenListExpr to represent anything else.
28932893
SourceRange Parens = Construct->getParenOrBraceRange();
2894+
if (Parens.isInvalid()) {
2895+
// This was a variable declaration's initialization for which no initializer
2896+
// was specified.
2897+
assert(NewArgs.empty() &&
2898+
"no parens or braces but have direct init with arguments?");
2899+
return ExprEmpty();
2900+
}
28942901
return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
28952902
Parens.getEnd());
28962903
}

clang/test/CodeGenCXX/value-init.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,59 @@ namespace PR11124 {
262262
void r170806_a(bool b = bool());
263263
void r170806_b() { r170806_a(); }
264264

265+
namespace PR20256 {
266+
struct data { int i; };
267+
268+
template<typename T = int>
269+
data g() {
270+
data d; // not value-init
271+
return d;
272+
}
273+
template data g();
274+
// CHECK-LABEL: define {{.*}} @_ZN7PR202561gIiEENS_4dataEv(
275+
// CHECK-NOT: store
276+
// CHECK-NOT: memset
277+
// CHECK: }
278+
279+
template<typename ...T>
280+
data h(T ...t) {
281+
data d(t...); // value-init
282+
return d;
283+
}
284+
template data h();
285+
// CHECK-LABEL: define {{.*}} @_ZN7PR202561hIJEEENS_4dataEDpT_(
286+
// CHECK: call void @llvm.memset
287+
// CHECK: }
288+
289+
290+
template<typename T = int>
291+
data j() {
292+
data d = {}; // value-init
293+
return d;
294+
}
295+
template data j();
296+
// CHECK-LABEL: define {{.*}} @_ZN7PR202561jIiEENS_4dataEv(
297+
// CHECK: call void @llvm.memset
298+
// CHECK: }
299+
300+
data f() {
301+
data d; // not value-init
302+
return d;
303+
}
304+
// CHECK-LABEL: define {{.*}} @_ZN7PR202561fEv(
305+
// CHECK-NOT: store
306+
// CHECK-NOT: memset
307+
// CHECK: }
308+
309+
data i() {
310+
data d = {}; // value-init
311+
return d;
312+
}
313+
// CHECK-LABEL: define {{.*}} @_ZN7PR202561iEv(
314+
// CHECK: call void @llvm.memset
315+
// CHECK: }
316+
}
317+
265318
// CHECK-LABEL: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
266319
// CHECK: call void @llvm.memset.p0i8.i64
267320
// CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev

0 commit comments

Comments
 (0)