[PATCH] Diagnose const destination to __atomic_load

Eric Fiselier eric at efcs.ca
Thu Jun 11 17:50:59 PDT 2015


Hi rsmith,

Currently clang allows `__atomic_load(int const*, int const*, int)` where the destination argument is const. However the destination must be non-const. This is an initial patch that attempts to diagnose this problem.

http://reviews.llvm.org/D10407

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaChecking.cpp
  test/Sema/atomic-ops.c

Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -6122,6 +6122,9 @@
 def err_atomic_op_needs_non_const_atomic : Error<
   "address argument to atomic operation must be a pointer to non-const _Atomic "
   "type (%0 invalid)">;
+def err_atomic_load_needs_non_const_dest : Error<
+  "address argument to atomic load must be a pointer to non-const %0 "
+ "(%1 invalid)">;
 def err_atomic_op_needs_trivial_copy : Error<
   "address argument to atomic operation must be a pointer to a "
   "trivially-copyable type (%0 invalid)">;
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -1620,6 +1620,24 @@
   if (!IsC11 && !IsN)
     ByValType = Ptr->getType();
 
+  if (Op == AtomicExpr::AO__atomic_load) {
+    Expr *SecondPtr = TheCall->getArg(1);
+    SecondPtr = DefaultFunctionArrayLvalueConversion(SecondPtr).get();
+    const PointerType *SecondPointerType = SecondPtr->getType()->getAs<PointerType>();
+    if (!SecondPointerType) {
+        Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer)
+          << SecondPtr->getType() << SecondPtr->getSourceRange();
+        return ExprError();
+    }
+    QualType SecondPointeeType = SecondPointerType->getPointeeType();
+    if (SecondPointeeType.isConstQualified()) {
+        Diag(DRE->getLocStart(), diag::err_atomic_load_needs_non_const_dest)
+            << ByValType->getPointeeType() << SecondPtr->getType()
+            << SecondPtr->getSourceRange();
+        return ExprError();
+    }
+  }
+
   // The first argument --- the pointer --- has a fixed type; we
   // deduce the types of the rest of the arguments accordingly.  Walk
   // the remaining arguments, converting them to the deduced value type.
Index: test/Sema/atomic-ops.c
===================================================================
--- test/Sema/atomic-ops.c
+++ test/Sema/atomic-ops.c
@@ -86,7 +86,7 @@
 _Static_assert(__atomic_always_lock_free(8, &i64), "");
 
 void f(_Atomic(int) *i, _Atomic(int*) *p, _Atomic(float) *d,
-       int *I, int **P, float *D, struct S *s1, struct S *s2) {
+       int *I, const int *CI, int **P, float *D, struct S *s1, struct S *s2) {
   __c11_atomic_init(I, 5); // expected-error {{pointer to _Atomic}}
   __c11_atomic_load(0); // expected-error {{too few arguments to function}}
   __c11_atomic_load(0,0,0); // expected-error {{too many arguments to function}}
@@ -103,6 +103,9 @@
   __atomic_load_n(s1, memory_order_relaxed); // expected-error {{must be a pointer to integer or pointer}}
 
   __atomic_load(i, I, memory_order_relaxed); // expected-error {{must be a pointer to a trivially-copyable type}}
+  __atomic_load(CI, I, memory_order_relaxed);
+  __atomic_load(I, CI, memory_order_relaxed);  // expected-error {{address argument to atomic load must be a pointer to non-const 'int' ('const int *' invalid}}
+  __atomic_load(I, 42, memory_order_relaxed);  // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}}
   __atomic_load(I, i, memory_order_relaxed); // expected-warning {{passing '_Atomic(int) *' to parameter of type 'int *'}}
   __atomic_load(I, *P, memory_order_relaxed);
   __atomic_load(I, *P, memory_order_relaxed, 42); // expected-error {{too many arguments}}

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D10407.27558.patch
Type: text/x-patch
Size: 3475 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150612/ae150ad0/attachment.bin>


More information about the cfe-commits mailing list