Here we were crashing on an invalid call to posix_memalign. The code in lower_builtin_posix_memalign assumed that the call had valid arguments. The reason the C FE doesn't reject this code is, in short, that int <T> () is compatible with int <T> (void **, size_t, size_t) and we use the former -- so convert_arguments doesn't complain.
So I think let's validate the arguments in lower_stmt. I decided to give an error if we see an invalid usage of posix_memalign, since other code (e.g. alias machinery) assumes correct arguments as well. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2015-08-17 Marek Polacek <pola...@redhat.com> PR middle-end/67222 * gimple-low.c: Include "builtins.h". (lower_stmt): Validate arguments of posix_memalign. * gcc.dg/torture/pr67222.c: New test. diff --git gcc/gimple-low.c gcc/gimple-low.c index d4697e2..03194f0 100644 --- gcc/gimple-low.c +++ gcc/gimple-low.c @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "gimple-low.h" #include "tree-nested.h" +#include "builtins.h" /* The differences between High GIMPLE and Low GIMPLE are the following: @@ -345,10 +346,22 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data) data->cannot_fallthru = false; return; } - else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_POSIX_MEMALIGN - && flag_tree_bit_ccp) + else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_POSIX_MEMALIGN) { - lower_builtin_posix_memalign (gsi); + if (gimple_call_num_args (stmt) != 3 + || !validate_gimple_arglist (dyn_cast <gcall *> (stmt), + POINTER_TYPE, INTEGER_TYPE, + INTEGER_TYPE, VOID_TYPE)) + { + error_at (gimple_location (stmt), "invalid arguments " + "to %qD", decl); + gsi_next (gsi); + return; + } + if (flag_tree_bit_ccp) + lower_builtin_posix_memalign (gsi); + else + gsi_next (gsi); return; } } diff --git gcc/testsuite/gcc.dg/torture/pr67222.c gcc/testsuite/gcc.dg/torture/pr67222.c index e69de29..cf39aa1 100644 --- gcc/testsuite/gcc.dg/torture/pr67222.c +++ gcc/testsuite/gcc.dg/torture/pr67222.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-Wno-implicit-function-declaration" } */ + +void +foo (void **p) +{ + posix_memalign (); /* { dg-error "invalid arguments" } */ + posix_memalign (p); /* { dg-error "invalid arguments" } */ + posix_memalign (0); /* { dg-error "invalid arguments" } */ + posix_memalign (p, 1); /* { dg-error "invalid arguments" } */ + posix_memalign (p, "foo"); /* { dg-error "invalid arguments" } */ + posix_memalign ("gnu", "gcc"); /* { dg-error "invalid arguments" } */ + posix_memalign (1, p); /* { dg-error "invalid arguments" } */ + posix_memalign (1, 2); /* { dg-error "invalid arguments" } */ + posix_memalign (1, 2, 3); /* { dg-error "invalid arguments" } */ + posix_memalign (p, p, p); /* { dg-error "invalid arguments" } */ + posix_memalign (p, "qui", 3); /* { dg-error "invalid arguments" } */ + posix_memalign (p, 1, 2); +} Marek