Skip to content

Commit 6b737c4

Browse files
authored
[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: #91057 Fixes #96289
1 parent 49fdbbc commit 6b737c4

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,9 @@ Bug Fixes to Compiler Builtins
745745

746746
- Fix crash when atomic builtins are called with pointer to zero-size struct (#GH90330)
747747

748+
- Clang now allows pointee types of atomic builtin arguments to be complete template types
749+
that was not instantiated elsewhere.
750+
748751
Bug Fixes to Attribute Support
749752
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
750753

clang/lib/Sema/SemaChecking.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3814,6 +3814,9 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
38143814
}
38153815

38163816
// Pointer to object of size zero is not allowed.
3817+
if (RequireCompleteType(Ptr->getBeginLoc(), AtomTy,
3818+
diag::err_incomplete_type))
3819+
return ExprError();
38173820
if (Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
38183821
Diag(ExprRange.getBegin(), diag::err_atomic_builtin_must_be_pointer)
38193822
<< Ptr->getType() << 1 << Ptr->getSourceRange();

clang/test/Sema/atomic-ops.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,36 @@ void zeroSizeArgError(struct Z *a, struct Z *b, struct Z *c) {
671671

672672
}
673673

674+
struct IncompleteTy IncA, IncB, IncC; // expected-error 3{{tentative definition has type 'struct IncompleteTy' that is never completed}} \
675+
// expected-note 27{{forward declaration of 'struct IncompleteTy'}}
676+
void incompleteTypeArgError() {
677+
__atomic_exchange(&IncB, &IncB, &IncC, memory_order_relaxed); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
678+
__atomic_exchange(&IncB, &IncB, &IncC, memory_order_acq_rel); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
679+
__atomic_exchange(&IncB, &IncB, &IncC, memory_order_acquire); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
680+
__atomic_exchange(&IncB, &IncB, &IncC, memory_order_consume); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
681+
__atomic_exchange(&IncB, &IncB, &IncC, memory_order_release); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
682+
__atomic_exchange(&IncB, &IncB, &IncC, memory_order_seq_cst); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
683+
__atomic_load(&IncA, &IncB, memory_order_relaxed); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
684+
__atomic_load(&IncA, &IncB, memory_order_acq_rel); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
685+
__atomic_load(&IncA, &IncB, memory_order_acquire); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
686+
__atomic_load(&IncA, &IncB, memory_order_consume); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
687+
__atomic_load(&IncA, &IncB, memory_order_release); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
688+
__atomic_load(&IncA, &IncB, memory_order_seq_cst); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
689+
__atomic_store(&IncA, &IncB, memory_order_relaxed); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
690+
__atomic_store(&IncA, &IncB, memory_order_acq_rel); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
691+
__atomic_store(&IncA, &IncB, memory_order_acquire); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
692+
__atomic_store(&IncA, &IncB, memory_order_consume); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
693+
__atomic_store(&IncA, &IncB, memory_order_release); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
694+
__atomic_store(&IncA, &IncB, memory_order_seq_cst); // expected-error {{incomplete type 'struct IncompleteTy' where a complete type is required}}
695+
__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}}
696+
__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}}
697+
__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}}
698+
__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}}
699+
__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}}
700+
__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}}
701+
702+
}
703+
674704
void nullPointerWarning(void) {
675705
volatile _Atomic(int) vai;
676706
_Atomic(int) ai;

clang/test/SemaCXX/atomic-ops.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,18 @@ void PR28623() {
77
void helper(char); // expected-note{{target}}
88
__atomic_store_n(helper, 0, 0); // expected-error{{reference to overloaded function could not be resolved}}
99
}
10+
11+
template<typename>
12+
struct X {
13+
char arr[1];
14+
};
15+
16+
extern X<void>* p, *q;
17+
18+
// They should be accepted.
19+
void f() {
20+
__atomic_exchange(p, p, q, __ATOMIC_RELAXED);
21+
__atomic_load(p, p, __ATOMIC_RELAXED);
22+
__atomic_store(p, p, __ATOMIC_RELAXED);
23+
__atomic_compare_exchange(p, p, q, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
24+
}

0 commit comments

Comments
 (0)