[clang] 6b737c4 - [clang][Sema] Fix crash on atomic builtins with incomplete type args (#96374)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Jun 29 22:09:14 PDT 2024
Author: Takuya Shimizu
Date: 2024-06-30T14:09:10+09:00
New Revision: 6b737c444617fe8c11eb48f978c579cc160bfff0
URL: https://github.com/llvm/llvm-project/commit/6b737c444617fe8c11eb48f978c579cc160bfff0
DIFF: https://github.com/llvm/llvm-project/commit/6b737c444617fe8c11eb48f978c579cc160bfff0.diff
LOG: [clang][Sema] Fix crash on atomic builtins with incomplete type args (#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
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaChecking.cpp
clang/test/Sema/atomic-ops.c
clang/test/SemaCXX/atomic-ops.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 35d2509eacece..c720e47dbe35b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -745,6 +745,9 @@ Bug Fixes to Compiler Builtins
- Fix crash when atomic builtins are called with pointer to zero-size struct (#GH90330)
+- Clang now allows pointee types of atomic builtin arguments to be complete template types
+ that was not instantiated elsewhere.
+
Bug Fixes to Attribute Support
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 005fbfd42a8ab..cc3615da7f940 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3814,6 +3814,9 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
}
// Pointer to object of size zero is not allowed.
+ if (RequireCompleteType(Ptr->getBeginLoc(), AtomTy,
+ diag::err_incomplete_type))
+ return ExprError();
if (Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
Diag(ExprRange.getBegin(), diag::err_atomic_builtin_must_be_pointer)
<< Ptr->getType() << 1 << Ptr->getSourceRange();
diff --git a/clang/test/Sema/atomic-ops.c b/clang/test/Sema/atomic-ops.c
index 2024b81ce6aec..9b82d82ff8269 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 27{{forward declaration of 'struct IncompleteTy'}}
+void incompleteTypeArgError() {
+ __atomic_exchange(&IncB, &IncB, &IncC, memory_order_relaxed); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_exchange(&IncB, &IncB, &IncC, memory_order_acq_rel); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_exchange(&IncB, &IncB, &IncC, memory_order_acquire); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_exchange(&IncB, &IncB, &IncC, memory_order_consume); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_exchange(&IncB, &IncB, &IncC, memory_order_release); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_exchange(&IncB, &IncB, &IncC, memory_order_seq_cst); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_load(&IncA, &IncB, memory_order_relaxed); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_load(&IncA, &IncB, memory_order_acq_rel); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_load(&IncA, &IncB, memory_order_acquire); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_load(&IncA, &IncB, memory_order_consume); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_load(&IncA, &IncB, memory_order_release); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_load(&IncA, &IncB, memory_order_seq_cst); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_store(&IncA, &IncB, memory_order_relaxed); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_store(&IncA, &IncB, memory_order_acq_rel); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_store(&IncA, &IncB, memory_order_acquire); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_store(&IncA, &IncB, memory_order_consume); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_store(&IncA, &IncB, memory_order_release); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_store(&IncA, &IncB, memory_order_seq_cst); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_relaxed, memory_order_relaxed); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_acq_rel, memory_order_acq_rel); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_acquire, memory_order_acquire); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_consume, memory_order_consume); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_release, memory_order_release); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+ __atomic_compare_exchange(&IncA, &IncB, &IncC, 0, memory_order_seq_cst, memory_order_seq_cst); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
+
+}
+
void nullPointerWarning(void) {
volatile _Atomic(int) vai;
_Atomic(int) ai;
diff --git a/clang/test/SemaCXX/atomic-ops.cpp b/clang/test/SemaCXX/atomic-ops.cpp
index 213161364f585..30d829d1e97d7 100644
--- a/clang/test/SemaCXX/atomic-ops.cpp
+++ b/clang/test/SemaCXX/atomic-ops.cpp
@@ -7,3 +7,18 @@ void PR28623() {
void helper(char); // expected-note{{target}}
__atomic_store_n(helper, 0, 0); // expected-error{{reference to overloaded function could not be resolved}}
}
+
+template<typename>
+struct X {
+ char arr[1];
+};
+
+extern X<void>* p, *q;
+
+// They should be accepted.
+void f() {
+ __atomic_exchange(p, p, q, __ATOMIC_RELAXED);
+ __atomic_load(p, p, __ATOMIC_RELAXED);
+ __atomic_store(p, p, __ATOMIC_RELAXED);
+ __atomic_compare_exchange(p, p, q, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
More information about the cfe-commits
mailing list