aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.c-torture
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-07-09 04:15:42 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-07-08 22:15:42 -0600
commitaac9480da1ffd037ceb21790fe341b3ec23283d9 (patch)
tree4951dd2f7b63d615f0746cec0cc0235637d4b588 /gcc/testsuite/gcc.c-torture
parent7d64aec499687f593a1bab4ae7cac843bc1d47af (diff)
downloadgcc-aac9480da1ffd037ceb21790fe341b3ec23283d9.zip
gcc-aac9480da1ffd037ceb21790fe341b3ec23283d9.tar.gz
gcc-aac9480da1ffd037ceb21790fe341b3ec23283d9.tar.bz2
PR middle-end/71924 - missing -Wreturn-local-addr returning alloca result
PR middle-end/71924 - missing -Wreturn-local-addr returning alloca result PR middle-end/90549 - missing -Wreturn-local-addr maybe returning an address of a local array plus offset gcc/ChangeLog: PR middle-end/71924 PR middle-end/90549 * gimple-ssa-isolate-paths.c (isolate_path): Add attribute. Update comment. (args_loc_t): New type. (args_loc_t, locmap_t): same. (diag_returned_locals): New function. (is_addr_local): Same. (handle_return_addr_local_phi_arg, warn_return_addr_local): Same. (find_implicit_erroneous_behavior): Call warn_return_addr_local_phi_arg. (find_explicit_erroneous_behavior): Call warn_return_addr_local. gcc/testsuite/ChangeLog: PR middle-end/71924 PR middle-end/90549 * gcc.c-torture/execute/return-addr.c: New test. * gcc.dg/Wreturn-local-addr-2.c: New test. * gcc.dg/Wreturn-local-addr-4.c: New test. * gcc.dg/Wreturn-local-addr-5.c: New test. * gcc.dg/Wreturn-local-addr-6.c: New test. * gcc.dg/Wreturn-local-addr-7.c: New test. * gcc.dg/Wreturn-local-addr-8.c: New test. * gcc.dg/Wreturn-local-addr-9.c: New test. * gcc.dg/Wreturn-local-addr-10.c: New test. * gcc.dg/Walloca-4.c: Handle expected warnings. * gcc.dg/pr41551.c: Same. * gcc.dg/pr59523.c: Same. * gcc.dg/tree-ssa/pr88775-2.c: Same. * gcc.dg/tree-ssa/alias-37.c: Same. * gcc.dg/winline-7.c: Same. From-SVN: r273261
Diffstat (limited to 'gcc/testsuite/gcc.c-torture')
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/return-addr.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.c-torture/execute/return-addr.c b/gcc/testsuite/gcc.c-torture/execute/return-addr.c
new file mode 100644
index 0000000..7981818
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/return-addr.c
@@ -0,0 +1,122 @@
+/* Test to verify that a function that returns either the address
+ of a local variable or a non-local via a MAX_EXPR or MIN_EXPR
+ doesn't return null when the result of the expression is
+ the latter. */
+
+#define NOIPA __attribute__ ((noclone, noinline, noipa))
+
+#define A(expr) \
+ ((expr) \
+ ? (void)0 \
+ : (__builtin_printf ("assertion failed on line %i: %s\n", \
+ __LINE__, #expr), \
+ __builtin_abort ()))
+
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+/* Return a bigger value than P. The address still points (just
+ past) the local variable pointed to by P so the caller does
+ return the address of a local variable but that's hidden from
+ GCC by the attribute and the point of the test is to verify
+ that the address in the return statement in the caller isn't
+ replaced by null when GCC cannot prove the address doesn't
+ reference a non-local variable. */
+
+NOIPA char* get_max_2 (char *p)
+{
+ return p + 1;
+}
+
+NOIPA char* get_max_3 (char *p, char *q)
+{
+ return p < q ? q + 1 : p + 1;
+}
+
+/* Analogous to the above. The expressions are undefined because
+ they form an address prior to the beginning of the object but
+ it's hidden from GCC by the attributes. */
+
+NOIPA char* get_min_2 (char *p)
+{
+ return p - 1;
+}
+
+NOIPA char* get_min_3 (char *p, char *q)
+{
+ return p < q ? p - 1 : q - 1;
+}
+
+
+NOIPA void* test_max_2 (void)
+{
+ char c;
+
+ char *p = get_max_2 (&c);
+
+ void *q = p > &c ? p : &c; /* MAX_EXPR */
+ return q;
+}
+
+NOIPA void* test_max_3 (void)
+{
+ char c;
+ char d;
+
+ char *p = get_max_3 (&c, &d);
+
+ void *q = p < &c ? &c < &d ? &d : &c : p;
+ return q;
+}
+
+NOIPA void* test_min_2 (void)
+{
+ char c;
+
+ char *p = get_min_2 (&c);
+
+ void *q = p < &c ? p : &c; /* MIN_EXPR" */
+ return q;
+}
+
+NOIPA void* test_min_3 (void)
+{
+ char c;
+ char d;
+
+ char *p = get_min_3 (&c, &d);
+
+ void *q = p > &c ? &c > &d ? &d : &c : p;
+ return q;
+}
+
+NOIPA void* test_min_3_phi (int i)
+{
+ char a, b;
+
+ char *p0 = &a;
+ char *p1 = &b;
+ char *p2 = get_min_3 (&a, &b);
+ char *p3 = get_min_3 (&a, &b);
+
+ char *p4 = p2 < p0 ? p2 : p0;
+ char *p5 = p3 < p1 ? p3 : p1;
+
+ __builtin_printf ("%p %p %p %p\n", p2, p3, p4, p5);
+
+ if (i == 1)
+ return p4;
+ else
+ return p5;
+}
+
+int main ()
+{
+ A (0 != test_max_2 ());
+ A (0 != test_max_3 ());
+
+ A (0 != test_min_2 ());
+ A (0 != test_min_3 ());
+
+ A (0 != test_min_3_phi (0));
+}