aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2016-01-08 01:00:25 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2016-01-07 18:00:25 -0700
commit7a127fa7c463b6b7c0285b32bac52bbdfc9a2117 (patch)
treed7b58a67882cd51f1addf5e9b63478ed3a012eb1 /gcc/c-family
parentc9733b8599c75031c40b85c15666730135f6f59b (diff)
downloadgcc-7a127fa7c463b6b7c0285b32bac52bbdfc9a2117.zip
gcc-7a127fa7c463b6b7c0285b32bac52bbdfc9a2117.tar.gz
gcc-7a127fa7c463b6b7c0285b32bac52bbdfc9a2117.tar.bz2
PR c/68966 - atomic_fetch_* on atomic_bool not diagnosed
gcc/ChangeLog: * doc/extend.texi (__atomic Builtins, __sync Builtins): Document constraint on the type of arguments. gcc/c-family/ChangeLog: * c-common.c (sync_resolve_size): Reject first argument when it's a pointer to _Bool. gcc/testsuite/ChangeLog: * gcc.dg/atomic-fetch-bool.c: New test. * gcc.dg/sync-fetch-bool.c: New test. From-SVN: r232147
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/c-common.c37
2 files changed, 39 insertions, 5 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 7bae1a7..a2743d8 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,10 @@
+gcc/c-family/ChangeLog:
+2016-01-07 Martin Sebor <msebor@redhat.com>
+
+ PR c/68966
+ * c-common.c (sync_resolve_size): Reject first argument when it's
+ a pointer to _Bool.
+
2016-01-05 David Malcolm <dmalcolm@redhat.com>
PR c/69122
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index a46e52b..0fd37b5c6 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -10657,11 +10657,16 @@ builtin_type_for_size (int size, bool unsignedp)
/* A helper function for resolve_overloaded_builtin in resolving the
overloaded __sync_ builtins. Returns a positive power of 2 if the
first operand of PARAMS is a pointer to a supported data type.
- Returns 0 if an error is encountered. */
+ Returns 0 if an error is encountered.
+ FETCH is true when FUNCTION is one of the _FETCH_OP_ or _OP_FETCH_
+ built-ins. */
static int
-sync_resolve_size (tree function, vec<tree, va_gc> *params)
+sync_resolve_size (tree function, vec<tree, va_gc> *params, bool fetch)
{
+ /* Type of the argument. */
+ tree argtype;
+ /* Type the argument points to. */
tree type;
int size;
@@ -10671,7 +10676,7 @@ sync_resolve_size (tree function, vec<tree, va_gc> *params)
return 0;
}
- type = TREE_TYPE ((*params)[0]);
+ argtype = type = TREE_TYPE ((*params)[0]);
if (TREE_CODE (type) == ARRAY_TYPE)
{
/* Force array-to-pointer decay for C++. */
@@ -10686,12 +10691,16 @@ sync_resolve_size (tree function, vec<tree, va_gc> *params)
if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
goto incompatible;
+ if (fetch && TREE_CODE (type) == BOOLEAN_TYPE)
+ goto incompatible;
+
size = tree_to_uhwi (TYPE_SIZE_UNIT (type));
if (size == 1 || size == 2 || size == 4 || size == 8 || size == 16)
return size;
incompatible:
- error ("incompatible type for argument %d of %qE", 1, function);
+ error ("operand type %qT is incompatible with argument %d of %qE",
+ argtype, 1, function);
return 0;
}
@@ -11250,6 +11259,11 @@ resolve_overloaded_builtin (location_t loc, tree function,
vec<tree, va_gc> *params)
{
enum built_in_function orig_code = DECL_FUNCTION_CODE (function);
+
+ /* Is function one of the _FETCH_OP_ or _OP_FETCH_ built-ins?
+ Those are not valid to call with a pointer to _Bool (or C++ bool)
+ and so must be rejected. */
+ bool fetch_op = true;
bool orig_format = true;
tree new_return = NULL_TREE;
@@ -11325,6 +11339,10 @@ resolve_overloaded_builtin (location_t loc, tree function,
case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_N:
case BUILT_IN_ATOMIC_LOAD_N:
case BUILT_IN_ATOMIC_STORE_N:
+ {
+ fetch_op = false;
+ /* Fallthrough to further processing. */
+ }
case BUILT_IN_ATOMIC_ADD_FETCH_N:
case BUILT_IN_ATOMIC_SUB_FETCH_N:
case BUILT_IN_ATOMIC_AND_FETCH_N:
@@ -11358,7 +11376,16 @@ resolve_overloaded_builtin (location_t loc, tree function,
case BUILT_IN_SYNC_LOCK_TEST_AND_SET_N:
case BUILT_IN_SYNC_LOCK_RELEASE_N:
{
- int n = sync_resolve_size (function, params);
+ /* The following are not _FETCH_OPs and must be accepted with
+ pointers to _Bool (or C++ bool). */
+ if (fetch_op)
+ fetch_op =
+ (orig_code != BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_N
+ && orig_code != BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
+ && orig_code != BUILT_IN_SYNC_LOCK_TEST_AND_SET_N
+ && orig_code != BUILT_IN_SYNC_LOCK_RELEASE_N);
+
+ int n = sync_resolve_size (function, params, fetch_op);
tree new_function, first_param, result;
enum built_in_function fncode;