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

Reply via email to