https://github.com/hazohelet created 
https://github.com/llvm/llvm-project/pull/96374

This patch fixes the crash when pointers to incomplete type are passed to 
atomic builtins such as `__atomic_load`.
`ASTContext::getTypeInfoInChars` assumes that the argument type is a complete 
type, so I added a check to eliminate cases where incomplete types gets passed 
to this function

Relevant PR: https://github.com/llvm/llvm-project/pull/91057
Fixes https://github.com/llvm/llvm-project/issues/96289

>From 7a76e4fe198eb2b9751ccd40f8e3850e7bae119c Mon Sep 17 00:00:00 2001
From: Takuya Shimizu <shimizu2...@gmail.com>
Date: Sat, 22 Jun 2024 12:05:50 +0900
Subject: [PATCH] [clang][Sema] Fix crash on atomic with incomplete type args

---
 clang/lib/Sema/SemaChecking.cpp |  3 ++-
 clang/test/Sema/atomic-ops.c    | 30 ++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7a2076d139c69..1872bdb5767f0 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -4570,7 +4570,8 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, 
SourceRange ExprRange,
   }
 
   // Pointer to object of size zero is not allowed.
-  if (Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
+  if (!AtomTy->isIncompleteType() &&
+      Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
     Diag(ExprRange.getBegin(), diag::err_atomic_builtin_must_be_pointer)
         << Ptr->getType() << 1 << Ptr->getSourceRange();
     return ExprError();
diff --git a/clang/test/Sema/atomic-ops.c b/clang/test/Sema/atomic-ops.c
index 2024b81ce6aec..d957461b6cb75 100644
--- a/clang/test/Sema/atomic-ops.c
+++ b/clang/test/Sema/atomic-ops.c
@@ -671,6 +671,36 @@ void zeroSizeArgError(struct Z *a, struct Z *b, struct Z 
*c) {
 
 }
 
+struct IncompleteTy IncA, IncB, IncC; // expected-error 3{{tentative 
definition has type 'struct IncompleteTy' that is never completed}} \
+                                      // expected-note 3{{forward declaration 
of 'struct IncompleteTy'}}
+void incompleteTypeArgError() {
+  __atomic_exchange(&IncB, &IncB, &IncC, memory_order_relaxed); // 
expected-error {{must be a pointer to a trivially-copyable type}}
+  __atomic_exchange(&IncB, &IncB, &IncC, memory_order_acq_rel); // 
expected-error {{must be a pointer to a trivially-copyable type}}
+  __atomic_exchange(&IncB, &IncB, &IncC, memory_order_acquire); // 
expected-error {{must be a pointer to a trivially-copyable type}}
+  __atomic_exchange(&IncB, &IncB, &IncC, memory_order_consume); // 
expected-error {{must be a pointer to a trivially-copyable type}}
+  __atomic_exchange(&IncB, &IncB, &IncC, memory_order_release); // 
expected-error {{must be a pointer to a trivially-copyable type}}
+  __atomic_exchange(&IncB, &IncB, &IncC, memory_order_seq_cst); // 
expected-error {{must be a pointer to a trivially-copyable type}}
+  __atomic_load(&IncA, &IncB, memory_order_relaxed); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_load(&IncA, &IncB, memory_order_acq_rel); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_load(&IncA, &IncB, memory_order_acquire); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_load(&IncA, &IncB, memory_order_consume); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_load(&IncA, &IncB, memory_order_release); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_load(&IncA, &IncB, memory_order_seq_cst); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_store(&IncA, &IncB, memory_order_relaxed); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_store(&IncA, &IncB, memory_order_acq_rel); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_store(&IncA, &IncB, memory_order_acquire); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_store(&IncA, &IncB, memory_order_consume); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_store(&IncA, &IncB, memory_order_release); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_store(&IncA, &IncB, memory_order_seq_cst); // expected-error {{must 
be a pointer to a trivially-copyable type}}
+  __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_relaxed, 
memory_order_relaxed); // expected-error {{must be a pointer to a 
trivially-copyable type}}
+  __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_acq_rel, 
memory_order_acq_rel); // expected-error {{must be a pointer to a 
trivially-copyable type}}
+  __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_acquire, 
memory_order_acquire); // expected-error {{must be a pointer to a 
trivially-copyable type}}
+  __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_consume, 
memory_order_consume); // expected-error {{must be a pointer to a 
trivially-copyable type}}
+  __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_release, 
memory_order_release); // expected-error {{must be a pointer to a 
trivially-copyable type}}
+  __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_seq_cst, 
memory_order_seq_cst); // expected-error {{must be a pointer to a 
trivially-copyable type}}
+
+}
+
 void nullPointerWarning(void) {
   volatile _Atomic(int) vai;
   _Atomic(int) ai;

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to