aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/Sema/SemaChecking.cpp6
-rw-r--r--test/Sema/atomic-ops.c7
3 files changed, 14 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 04eb75747d..db3e62908f 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4946,6 +4946,9 @@ def err_atomic_builtin_pointer_size : Error<
def err_atomic_op_needs_atomic : Error<
"first argument to atomic operation must be a pointer to _Atomic "
"type (%0 invalid)">;
+def err_atomic_op_needs_non_const_atomic : Error<
+ "first argument to atomic operation must be a pointer to non-const _Atomic "
+ "type (%0 invalid)">;
def err_atomic_op_needs_trivial_copy : Error<
"first argument to atomic operation must be a pointer to a trivially-copyable"
" type (%0 invalid)">;
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 0e6b5ec9a3..6d8d7f2c04 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -742,6 +742,11 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,
<< Ptr->getType() << Ptr->getSourceRange();
return ExprError();
}
+ if (AtomTy.isConstQualified()) {
+ Diag(DRE->getLocStart(), diag::err_atomic_op_needs_non_const_atomic)
+ << Ptr->getType() << Ptr->getSourceRange();
+ return ExprError();
+ }
ValType = AtomTy->getAs<AtomicType>()->getValueType();
}
@@ -6124,4 +6129,3 @@ void Sema::CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr,
<< ArgumentExpr->getSourceRange()
<< TypeTagExpr->getSourceRange();
}
-
diff --git a/test/Sema/atomic-ops.c b/test/Sema/atomic-ops.c
index f769271631..2a935918ac 100644
--- a/test/Sema/atomic-ops.c
+++ b/test/Sema/atomic-ops.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only -triple=i686-linux-gnu
+// RUN: %clang_cc1 %s -verify -fsyntax-only -triple=i686-linux-gnu -std=c11
// Basic parsing/Sema tests for __c11_atomic_*
@@ -162,4 +162,9 @@ void f(_Atomic(int) *i, _Atomic(int*) *p, _Atomic(float) *d,
__atomic_clear(&flag_k, memory_order_seq_cst); // expected-warning {{passing 'const volatile int *' to parameter of type 'volatile void *'}}
__atomic_clear(&flag, memory_order_seq_cst);
(int)__atomic_clear(&flag, memory_order_seq_cst); // expected-error {{operand of type 'void'}}
+
+ const _Atomic(int) const_atomic;
+ __c11_atomic_init(&const_atomic, 0); // expected-error {{first argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}}
+ __c11_atomic_store(&const_atomic, 0, memory_order_release); // expected-error {{first argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}}
+ __c11_atomic_load(&const_atomic, memory_order_acquire); // expected-error {{first argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}}
}