[clang] [clang][sema] check args of __atomic_exchange is complete type (PR #75135)

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 11 21:08:37 PST 2023


https://github.com/knightXun updated https://github.com/llvm/llvm-project/pull/75135

>From dc3714573f92b2303ca3bad046b355ccb66c2957 Mon Sep 17 00:00:00 2001
From: knightXun <badgangkiller at gmail.com>
Date: Tue, 12 Dec 2023 12:23:54 +0800
Subject: [PATCH 1/2] [clang][sema] check args of __atomic_exchange is complete
 type make sure the args of __atomic_exchange is complete type, make it
 consistent with GCC issue: https://github.com/llvm/llvm-project/issues/74464

---
 clang/lib/Sema/SemaChecking.cpp | 12 ++++++++++++
 clang/test/Sema/atomic-ops.c    |  4 +++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index cdb6e9584e955..a88d3a6928edd 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;
+
+  // Check if the arguments are 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 4fa1223b3038f..6f1d3c4b86ef9 100644
--- a/clang/test/Sema/atomic-ops.c
+++ b/clang/test/Sema/atomic-ops.c
@@ -19,6 +19,7 @@
 
 // Basic parsing/Sema tests for __c11_atomic_*
 
+#include "clang-c/Index.h"
 #include <stdatomic.h>
 
 struct S { char c[3]; };
@@ -130,7 +131,7 @@ _Static_assert(__atomic_always_lock_free(8, &i64), "");
 void f(_Atomic(int) *i, const _Atomic(int) *ci,
        _Atomic(int*) *p, _Atomic(float) *f, _Atomic(double) *d,
        _Atomic(long double) *ld,
-       int *I, const int *CI,
+       int *I, const int *CI,char c[],
        int **P, float *F, double *D, struct S *s1, struct S *s2) {
   __c11_atomic_init(I, 5); // expected-error {{pointer to _Atomic}}
   __c11_atomic_init(ci, 5); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}}
@@ -192,6 +193,7 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci,
   (int)__atomic_exchange(s1, s2, s2, memory_order_seq_cst); // expected-error {{operand of type 'void'}}
   __atomic_exchange(I, I, I, memory_order_seq_cst);
   __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(&c, I, I, memory_order_seq_cst); // expected-error {{incomplete type 'char[]' where a complete type is required}}
   __atomic_exchange(I, I, CI, memory_order_seq_cst); // expected-warning {{passing 'const int *' to parameter of type 'int *' discards qualifiers}}
 
   __c11_atomic_fetch_add(i, 1, memory_order_seq_cst);

>From ba0f684674610a0c6d7600859088cdace5480126 Mon Sep 17 00:00:00 2001
From: knightXun <badgangkiller at gmail.com>
Date: Tue, 12 Dec 2023 13:05:56 +0800
Subject: [PATCH 2/2] fix ut

---
 clang/lib/Sema/SemaChecking.cpp | 2 +-
 clang/test/Sema/atomic-ops.c    | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a88d3a6928edd..60706e4195bc5 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7886,7 +7886,7 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
       Op != AtomicExpr::AO__opencl_atomic_init)
     ++AdjustedNumArgs;
 
-  // Check if the arguments are CompleteType
+  // Verify if the arguments are of type CompleteType
   if (Op == AtomicExpr::AO__atomic_exchange) {
     for (auto Arg : Args) {
       auto ValType = Arg->getType();
diff --git a/clang/test/Sema/atomic-ops.c b/clang/test/Sema/atomic-ops.c
index 6f1d3c4b86ef9..d3402b97818d1 100644
--- a/clang/test/Sema/atomic-ops.c
+++ b/clang/test/Sema/atomic-ops.c
@@ -18,8 +18,6 @@
 // RUN:   -mabi=quadword-atomics -target-cpu pwr8 -DPPC64_PWR8
 
 // Basic parsing/Sema tests for __c11_atomic_*
-
-#include "clang-c/Index.h"
 #include <stdatomic.h>
 
 struct S { char c[3]; };
@@ -131,7 +129,7 @@ _Static_assert(__atomic_always_lock_free(8, &i64), "");
 void f(_Atomic(int) *i, const _Atomic(int) *ci,
        _Atomic(int*) *p, _Atomic(float) *f, _Atomic(double) *d,
        _Atomic(long double) *ld,
-       int *I, const int *CI,char c[],
+       int *I, const int *CI,
        int **P, float *F, double *D, struct S *s1, struct S *s2) {
   __c11_atomic_init(I, 5); // expected-error {{pointer to _Atomic}}
   __c11_atomic_init(ci, 5); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}}
@@ -193,9 +191,11 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci,
   (int)__atomic_exchange(s1, s2, s2, memory_order_seq_cst); // expected-error {{operand of type 'void'}}
   __atomic_exchange(I, I, I, memory_order_seq_cst);
   __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(&c, I, I, memory_order_seq_cst); // expected-error {{incomplete type 'char[]' where a complete type is required}}
   __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);



More information about the cfe-commits mailing list