From c466c4ff909f2a03344110dec66c3c3616e44920 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Fri, 25 Nov 2011 03:00:38 +0000 Subject: re PR c/51256 (ICE with invalid parameter for __atomic builtin) 2011-11-24 Andrew MacLeod PR c/51256 * c-common.c (get_atomic_generic_size): Check for various error conditions (resolve_overloaded_atomic_exchange, resolve_overloaded_atomic_compare_exchange, resolve_overloaded_atomic_load, resolve_overloaded_atomic_store): Return error_mark_node for error conditions. * gcc.dg/atomic-pr51256.c: New. Test error conditions. From-SVN: r181709 --- gcc/c-family/ChangeLog | 10 ++++++ gcc/c-family/c-common.c | 58 +++++++++++++++++++++++++++++++---- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/atomic-pr51256.c | 47 ++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/atomic-pr51256.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 9716cc9..4463106 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,13 @@ +2011-11-24 Andrew MacLeod + + PR c/51256 + * c-common.c (get_atomic_generic_size): Check for various error + conditions + (resolve_overloaded_atomic_exchange, + resolve_overloaded_atomic_compare_exchange, + resolve_overloaded_atomic_load, resolve_overloaded_atomic_store): Return + error_mark_node for error conditions. + 2011-11-08 Richard Guenther PR middle-end/51010 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index a682331..fbbcb38 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -9392,7 +9392,7 @@ get_atomic_generic_size (location_t loc, tree function, VEC(tree,gc) *params) n_model = 2; break; default: - return 0; + gcc_unreachable (); } if (VEC_length (tree, params) != n_param) @@ -9403,13 +9403,33 @@ get_atomic_generic_size (location_t loc, tree function, VEC(tree,gc) *params) /* Get type of first parameter, and determine its size. */ type_0 = TREE_TYPE (VEC_index (tree, params, 0)); - if (TREE_CODE (type_0) != POINTER_TYPE) + if (TREE_CODE (type_0) != POINTER_TYPE || VOID_TYPE_P (TREE_TYPE (type_0))) + { + error_at (loc, "argument 1 of %qE must be a non-void pointer type", + function); + return 0; + } + + /* Types must be compile time constant sizes. */ + if (TREE_CODE ((TYPE_SIZE_UNIT (TREE_TYPE (type_0)))) != INTEGER_CST) { - error_at (loc, "argument 1 of %qE must be a pointer type", function); + error_at (loc, + "argument 1 of %qE must be a pointer to a constant size type", + function); return 0; } + size_0 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (type_0)), 1); + /* Zero size objects are not allowed. */ + if (size_0 == 0) + { + error_at (loc, + "argument 1 of %qE must be a pointer to a nonzero size object", + function); + return 0; + } + /* Check each other parameter is a pointer and the same size. */ for (x = 0; x < n_param - n_model; x++) { @@ -9445,7 +9465,6 @@ get_atomic_generic_size (location_t loc, tree function, VEC(tree,gc) *params) warning_at (loc, OPT_Winvalid_memory_model, "invalid memory model argument %d of %qE", x + 1, function); - return MEMMODEL_SEQ_CST; } } else @@ -9515,6 +9534,13 @@ resolve_overloaded_atomic_exchange (location_t loc, tree function, tree I_type, I_type_ptr; int n = get_atomic_generic_size (loc, function, params); + /* Size of 0 is an error condition. */ + if (n == 0) + { + *new_return = error_mark_node; + return true; + } + /* If not a lock-free size, change to the library generic format. */ if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16) { @@ -9538,8 +9564,7 @@ resolve_overloaded_atomic_exchange (location_t loc, tree function, /* Convert object pointer to required type. */ p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0); - VEC_replace (tree, params, 0, p0); - + VEC_replace (tree, params, 0, p0); /* Convert new value to required type, and dereference it. */ p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR); p1 = build1 (VIEW_CONVERT_EXPR, I_type, p1); @@ -9574,6 +9599,13 @@ resolve_overloaded_atomic_compare_exchange (location_t loc, tree function, tree I_type, I_type_ptr; int n = get_atomic_generic_size (loc, function, params); + /* Size of 0 is an error condition. */ + if (n == 0) + { + *new_return = error_mark_node; + return true; + } + /* If not a lock-free size, change to the library generic format. */ if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16) { @@ -9643,6 +9675,13 @@ resolve_overloaded_atomic_load (location_t loc, tree function, tree I_type, I_type_ptr; int n = get_atomic_generic_size (loc, function, params); + /* Size of 0 is an error condition. */ + if (n == 0) + { + *new_return = error_mark_node; + return true; + } + /* If not a lock-free size, change to the library generic format. */ if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16) { @@ -9696,6 +9735,13 @@ resolve_overloaded_atomic_store (location_t loc, tree function, tree I_type, I_type_ptr; int n = get_atomic_generic_size (loc, function, params); + /* Size of 0 is an error condition. */ + if (n == 0) + { + *new_return = error_mark_node; + return true; + } + /* If not a lock-free size, change to the library generic format. */ if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 229e6d8..ff60be0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-11-24 Andrew MacLeod + + PR c/51256 + * gcc.dg/atomic-pr51256.c: New. Test error conditions. + 2011-11-24 Paolo Carlini PR c++/51227 diff --git a/gcc/testsuite/gcc.dg/atomic-pr51256.c b/gcc/testsuite/gcc.dg/atomic-pr51256.c new file mode 100644 index 0000000..2d39549 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-pr51256.c @@ -0,0 +1,47 @@ +/* Test generic __atomic routines for various errors. */ +/* { dg-do compile } */ +/* { dg-require-effective-target sync_int_long } */ +/* { dg-options "-ansi" } */ + +void f1 (void* p) +{ + __atomic_compare_exchange(p, p, p, 0, 0, 0); /* { dg-error "must be a non-void pointer type" } */ +} + +void f2 (int n) +{ + int a[n], b[n]; + __atomic_load (&a, &b, __ATOMIC_SEQ_CST); /* { dg-error "must be a pointer to a constant size" } */ +} + +struct s { }; +void f3 (void) +{ + struct s a,b; + __atomic_load (&a, &b, __ATOMIC_SEQ_CST); /* { dg-error "must be a pointer to a nonzero size" } */ +} + +void f4 (int a, int b, int c) +{ + __atomic_load (&a, &b, &c, __ATOMIC_SEQ_CST); /* { dg-error "incorrect number of arguments" } */ +} + +void f5 (int a, int b) +{ + __atomic_load (&a, b, __ATOMIC_SEQ_CST); /* { dg-error "must be a pointer type" } */ +} + +void f6 (int a, char b) +{ + __atomic_load (&a, &b, __ATOMIC_SEQ_CST); /* { dg-error "size mismatch in argument" } */ +} + +void f7 (int a, int b) +{ + __atomic_load (&a, &b, 45); /* { dg-warning "invalid memory model argument" } */ +} + +void f8 (int a, int b, float c) +{ + __atomic_load (&a, &b, c); /* { dg-error "non-integer memory model argument" } */ +} -- cgit v1.1