diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index cdb6e9584e9554..60706e4195bc57 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -7885,6 +7885,18 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, if ((IsOpenCL || IsHIP || IsScoped) && Op != AtomicExpr::AO__opencl_atomic_init) ++AdjustedNumArgs; + + // Verify if the arguments are of type CompleteType + if (Op == AtomicExpr::AO__atomic_exchange) { + for (auto Arg : Args) { + auto ValType = Arg->getType(); + if (ValType->isPointerType() && !ValType->isNullPtrType() && + RequireCompleteType(Arg->getBeginLoc(), ValType->getPointeeType(), + diag::err_incomplete_type)) { + return ExprError(); + } + } + } // Check we have the right number of arguments. if (Args.size() < AdjustedNumArgs) { Diag(CallRange.getEnd(), diag::err_typecheck_call_too_few_args) diff --git a/clang/test/Sema/atomic-ops.c b/clang/test/Sema/atomic-ops.c index 4fa1223b3038f3..d3402b97818d1a 100644 --- a/clang/test/Sema/atomic-ops.c +++ b/clang/test/Sema/atomic-ops.c @@ -18,7 +18,6 @@ // RUN: -mabi=quadword-atomics -target-cpu pwr8 -DPPC64_PWR8 // Basic parsing/Sema tests for __c11_atomic_* - #include struct S { char c[3]; }; @@ -194,6 +193,9 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci, __atomic_exchange(CI, I, I, memory_order_seq_cst); // expected-error {{address argument to atomic operation must be a pointer to non-const type ('const int *' invalid)}} __atomic_exchange(I, I, CI, memory_order_seq_cst); // expected-warning {{passing 'const int *' to parameter of type 'int *' discards qualifiers}} + extern char xx[]; + __atomic_exchange(&xx, I, I, memory_order_seq_cst); // expected-error {{incomplete type 'char[]' where a complete type is required}} + __c11_atomic_fetch_add(i, 1, memory_order_seq_cst); __c11_atomic_fetch_add(p, 1, memory_order_seq_cst); __c11_atomic_fetch_add(f, 1.0f, memory_order_seq_cst);