llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Takuya Shimizu (hazohelet) <details> <summary>Changes</summary> 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 --- Full diff: https://github.com/llvm/llvm-project/pull/96374.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaChecking.cpp (+2-1) - (modified) clang/test/Sema/atomic-ops.c (+30) ``````````diff 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; `````````` </details> https://github.com/llvm/llvm-project/pull/96374 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits