llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: None (rahulana-quic)

<details>
<summary>Changes</summary>

Currently, atomic pointer initializers can reach CodeGen without the expected 
null-to-pointer cast, triggering an assert. This change ensures that atomic 
pointer initializers are correctly handled for scalar initializations and 
init-list elements.

---
Full diff: https://github.com/llvm/llvm-project/pull/174403.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaInit.cpp (+47-14) 
- (added) clang/test/CodeGen/atomic_zero_initialize.c (+20) 


``````````diff
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index ff278bc7471bd..3c75e40d1ce59 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -1611,8 +1611,8 @@ void InitListChecker::CheckSubElementType(const 
InitializedEntity &Entity,
     // Fall through for subaggregate initialization
   } else if (ElemType->isScalarType() || ElemType->isAtomicType()) {
     // FIXME: Need to handle atomic aggregate types with implicit init lists.
-    return CheckScalarType(Entity, IList, ElemType, Index,
-                           StructuredList, StructuredIndex);
+    return CheckScalarType(Entity, IList, ElemType, Index, StructuredList,
+                           StructuredIndex);
   } else if (const ArrayType *arrayType =
                  SemaRef.Context.getAsArrayType(ElemType)) {
     // arrayType can be incomplete if we're initializing a flexible
@@ -6899,8 +6899,26 @@ void InitializationSequence::InitializeFrom(Sema &S,
       return;
 
     // Handle initialization in C
+    // Check for atomic destinations and unwrap to the underlying value type if
+    // the source is non-atomic. Perform the atomic conversion later
+    bool NeedAtomicConversion = false;
+    if (const AtomicType *AtomicDest = DestType->getAs<AtomicType>()) {
+      bool SourceIsAtomicOrPtrToAtomic =
+          (SourceType->isAtomicType() ||
+           (SourceType->isPointerType() &&
+            SourceType->getPointeeType()->isAtomicType()));
+      if (SourceType.isNull() || !SourceIsAtomicOrPtrToAtomic) {
+        DestType = AtomicDest->getValueType();
+        NeedAtomicConversion = true;
+      }
+    }
+
     AddCAssignmentStep(DestType);
     MaybeProduceObjCObject(S, *this, Entity);
+
+    // Add atomic conversion if needed
+    if (!Failed() && NeedAtomicConversion)
+      AddAtomicConversionStep(Entity.getType());
     return;
   }
 
@@ -7004,13 +7022,25 @@ void InitializationSequence::InitializeFrom(Sema &S,
   //      initializer expression to the cv-unqualified version of the
   //      destination type; no user-defined conversions are considered.
 
-  ImplicitConversionSequence ICS
-    = S.TryImplicitConversion(Initializer, DestType,
-                              /*SuppressUserConversions*/true,
-                              Sema::AllowedExplicit::None,
-                              /*InOverloadResolution*/ false,
-                              /*CStyle=*/Kind.isCStyleOrFunctionalCast(),
-                              allowObjCWritebackConversion);
+  // Check for atomic destinations and unwrap to the underlying value type if
+  // the source is non-atomic. Perform the atomic conversion later
+  bool NeedAtomicConversion = false;
+  if (const AtomicType *AtomicDest = DestType->getAs<AtomicType>()) {
+    bool SourceIsAtomicOrPtrToAtomic =
+        (SourceType->isAtomicType() ||
+         (SourceType->isPointerType() &&
+          SourceType->getPointeeType()->isAtomicType()));
+    if (SourceType.isNull() || !SourceIsAtomicOrPtrToAtomic) {
+      DestType = AtomicDest->getValueType();
+      NeedAtomicConversion = true;
+    }
+  }
+
+  ImplicitConversionSequence ICS = S.TryImplicitConversion(
+      Initializer, DestType,
+      /*SuppressUserConversions*/ true, Sema::AllowedExplicit::None,
+      /*InOverloadResolution*/ false,
+      /*CStyle=*/Kind.isCStyleOrFunctionalCast(), 
allowObjCWritebackConversion);
 
   if (ICS.isStandard() &&
       ICS.Standard.Second == ICK_Writeback_Conversion) {
@@ -7049,6 +7079,10 @@ void InitializationSequence::InitializeFrom(Sema &S,
     AddConversionSequenceStep(ICS, DestType, TopLevelOfInitList);
 
     MaybeProduceObjCObject(S, *this, Entity);
+
+    // Add atomic conversion if needed
+    if (!Failed() && NeedAtomicConversion)
+      AddAtomicConversionStep(Entity.getType());
   }
 }
 
@@ -8516,11 +8550,10 @@ ExprResult InitializationSequence::Perform(Sema &S,
                                         Step->Type, InitialCurInit.get());
 
       bool Complained;
-      if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(),
-                                     Step->Type, SourceType,
-                                     InitialCurInit.get(),
-                                     getAssignmentAction(Entity, true),
-                                     &Complained)) {
+      if (S.DiagnoseAssignmentResult(
+              ConvTy, Kind.getLocation(), Entity.getType(), SourceType,
+              InitialCurInit.get(), getAssignmentAction(Entity, true),
+              &Complained)) {
         PrintInitLocationNote(S, Entity);
         return ExprError();
       } else if (Complained)
diff --git a/clang/test/CodeGen/atomic_zero_initialize.c 
b/clang/test/CodeGen/atomic_zero_initialize.c
new file mode 100644
index 0000000000000..56b6868919853
--- /dev/null
+++ b/clang/test/CodeGen/atomic_zero_initialize.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK-C
+// RUN: %clang_cc1 -emit-llvm -o - %s -x c++ | FileCheck %s 
--check-prefixes=CHECK-CXX
+
+// CHECK-LABEL: @initlist_atomic_pointer_zero
+struct range_tree_node_s {
+  long base;
+  long left;
+  struct range_tree_node_s *_Atomic right;
+};
+
+void initlist_atomic_pointer_zero() {
+  (struct range_tree_node_s){.right = 0};
+}
+
+// CHECK-LABEL: @scalar_atomic_init
+void scalar_atomic_init() {
+  // CHECK-C: store ptr null
+  // CHECK-CXX: store ptr null
+  _Atomic(int*) p = 0;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/174403
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to