ayzhao created this revision. Herald added a project: All. ayzhao requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
It turns out that FieldDecl::getInClassInitializer() will return nullptr for default member initializers if the field is part of a templated class. The correct thing to do is to call hasInClassInitializer(), which is what we do for braced init lists[0]. Fixes 62266 [0]: https://github.com/llvm/llvm-project/blob/be5f35e24f4c15caf3c4aeccddc54c52560c28a0/clang/lib/Sema/SemaInit.cpp#L685 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D149389 Files: clang/lib/Sema/SemaInit.cpp clang/test/CodeGen/paren-list-agg-init.cpp Index: clang/test/CodeGen/paren-list-agg-init.cpp =================================================================== --- clang/test/CodeGen/paren-list-agg-init.cpp +++ clang/test/CodeGen/paren-list-agg-init.cpp @@ -90,6 +90,15 @@ }; } +namespace gh62266 { + // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, i32 } + template <int J> + struct H { + int i; + int j = J; + }; +} + // CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.000000e+00 }, align 8 constexpr A a1(3.1, 2.0); // CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.000000e+00 }, align 8 @@ -421,3 +430,17 @@ make2<0>(); } } + +namespace gh62266 { + // CHECK: define {{.*}} void {{.*foo20.*}} + // CHECK-NEXT: entry: + // CHECK-NEXT: [[H:%.*h.*]] = alloca [[STRUCT_H]], align 4 + // CHECK-NEXT: [[I:%.*i.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[H]], i32 0, i32 0 + // CHECK-NEXT: store i32 1, ptr [[I]], align 4 + // CHECK-NEXT: [[J:%.*j.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[H]], i32 0, i32 1 + // CHECK-NEXT: store i32 2, ptr [[J]], align 4 + // CHECK-NEXT: ret void + void foo20() { + H<2> h(1); + } +} Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -5377,14 +5377,16 @@ // The remaining elements are initialized with their default member // initializers, if any auto *FD = cast<FieldDecl>(SubEntity.getDecl()); - if (Expr *ICE = FD->getInClassInitializer(); ICE && !VerifyOnly) { - ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD); - if (DIE.isInvalid()) - return false; - S.checkInitializerLifetime(SubEntity, DIE.get()); - InitExprs.push_back(DIE.get()); + if (FD->hasInClassInitializer()) { + if (!VerifyOnly) { + ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD); + if (DIE.isInvalid()) + return false; + S.checkInitializerLifetime(SubEntity, DIE.get()); + InitExprs.push_back(DIE.get()); + } continue; - }; + } } // Remaining class elements without default member initializers and // array elements are value initialized:
Index: clang/test/CodeGen/paren-list-agg-init.cpp =================================================================== --- clang/test/CodeGen/paren-list-agg-init.cpp +++ clang/test/CodeGen/paren-list-agg-init.cpp @@ -90,6 +90,15 @@ }; } +namespace gh62266 { + // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, i32 } + template <int J> + struct H { + int i; + int j = J; + }; +} + // CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.000000e+00 }, align 8 constexpr A a1(3.1, 2.0); // CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.000000e+00 }, align 8 @@ -421,3 +430,17 @@ make2<0>(); } } + +namespace gh62266 { + // CHECK: define {{.*}} void {{.*foo20.*}} + // CHECK-NEXT: entry: + // CHECK-NEXT: [[H:%.*h.*]] = alloca [[STRUCT_H]], align 4 + // CHECK-NEXT: [[I:%.*i.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[H]], i32 0, i32 0 + // CHECK-NEXT: store i32 1, ptr [[I]], align 4 + // CHECK-NEXT: [[J:%.*j.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[H]], i32 0, i32 1 + // CHECK-NEXT: store i32 2, ptr [[J]], align 4 + // CHECK-NEXT: ret void + void foo20() { + H<2> h(1); + } +} Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -5377,14 +5377,16 @@ // The remaining elements are initialized with their default member // initializers, if any auto *FD = cast<FieldDecl>(SubEntity.getDecl()); - if (Expr *ICE = FD->getInClassInitializer(); ICE && !VerifyOnly) { - ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD); - if (DIE.isInvalid()) - return false; - S.checkInitializerLifetime(SubEntity, DIE.get()); - InitExprs.push_back(DIE.get()); + if (FD->hasInClassInitializer()) { + if (!VerifyOnly) { + ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD); + if (DIE.isInvalid()) + return false; + S.checkInitializerLifetime(SubEntity, DIE.get()); + InitExprs.push_back(DIE.get()); + } continue; - }; + } } // Remaining class elements without default member initializers and // array elements are value initialized:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits