From patchwork Mon Jan 27 19:09:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Law X-Patchwork-Id: 314464 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D748A2C0081 for ; Tue, 28 Jan 2014 06:09:28 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=sQhrlGkPoFgw4VwxaWCk7VoDdjxek/RcvKDErWEDKWwev+ BK4NeSzmKoESNBqCAKnkoqpZZRBvdEbwiIPG/oPnylpYitHjjsBkI/9XL3wqNlJ8 pfwZekXmesJZBeT0aT1A1Xk8yY0bnL4R8ueVZtoOuzqS5GZwr2RIHndNDStzw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=RuQAo0D/hxxcZ8U1CXY2gU/ymEQ=; b=hjszswiedLNkbi6Kx0y1 UxBH/N0tMv9rownV098okmfnKqKx3QOYyZklwyqNVV38i6I3zsdPR5jAoqCvf9BX OM2cfMKCo9j7IU/pP0X5rvlAW5Zplf253p2ZsUhAlwl4Qv0M9Rv9v4UqMDcpyfC6 IPFJdvAoqfiJOxUScZ7B7Aw= Received: (qmail 1062 invoked by alias); 27 Jan 2014 19:09:19 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 1049 invoked by uid 89); 27 Jan 2014 19:09:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 27 Jan 2014 19:09:12 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s0RJ9BHs002750 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 27 Jan 2014 14:09:11 -0500 Received: from stumpy.slc.redhat.com ([10.3.113.19]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s0RJ9Arx029387 for ; Mon, 27 Jan 2014 14:09:11 -0500 Message-ID: <52E6AED6.6090704@redhat.com> Date: Mon, 27 Jan 2014 12:09:10 -0700 From: Jeff Law User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: gcc-patches Subject: [RFA][PR 16361] Add warnings for NULL pointer dereferences and such X-IsSubscribed: yes [ Yes, 16351, it's that old. ] First, as is often the case, this warning is not going to catch everything. Dead code elimination, unreachable code elimination, etc can/will remove NULL pointer dereferences and if that happens we don't get a warning. It also will not catch cases where a NULL value flows out of a PHI into uses in other blocks where it is then dereferenced or otherwise used erroneously. -Wnull-dereference will warn for NULL pointer dereferences. Both those which appear explicitly in the IL and those which occur if NULL value flows from a PHI to a dereference in the same block as the PHI. -Wnull-attribute will warn if NULL is used as an argument to a function call where the callee's attributes have declared the argument must be non-NULL. Similarly for NULL as a return value when the current function has an attribute declaring the function can never return NULL. Similarly for NULL values flowing from a PHI into an argument/return in the same block as the PHI. We utilize the analysis done for the erroneous-paths optimization. The optimizations and warnings can be enabled/disabled independently. The warnings are not enabled by -Wall. The testsuite verifies basic operation by re-using the existing isolation tests. Each test was split into two tests. One which tests the warning (with the optimization explicitly disabled), the other which tests the optimization. Earlier versions of this patch have been bootstrapped and regression tested. The only difference between those earlier versions and this one are the docs & additions to the testsuite. As with prior patches of mine that touched common.opt, particular attention to those changes would be appreciated. OK, assuming it passes another round of bootstrapping and regression testing? Jeff diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 95a324c..8ffbc50 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2014-01-27 Jeff Law + + * common.opt (Wnull-dereference): New option. + (Wnull-attribute): Likewise. + * doc/invoke.texi: Document new warnings. + * gimple-ssa-isolate-paths.c: (find_implicit_erroneous_behaviour): Warn + for NULL dereferences and NULL values flowing into arguments or + return values where an attribute indicates that should never happen. + Do not optimize unless the optimization is enabled. + (find_explicit_erroneous_behaviour): Similarly. + (gate_isolate_erroneous_paths): Run if we want the optimization + or the warning. + + 2014-01-27 Jakub Jelinek PR bootstrap/59934 diff --git a/gcc/common.opt b/gcc/common.opt index d334cf2..dcff512 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -576,6 +576,17 @@ Wlarger-than= Common RejectNegative Joined UInteger Warning -Wlarger-than= Warn if an object is larger than bytes +Wnull-dereference +Common Var(warn_null_dereference) Warning +Warn if the compiler detects paths which trigger erroneous or undefined +behaviour due to dereferencing a NULL pointer. + +Wnull-attribute +Common Var(warn_null_attribute) Warning +Warn if the compiler detects paths which trigger erroneous or undefined +behaviour due to passing a NULL value for an argument which must be non-NULL or +if a function returns NULL when it has been declared as must not return NULL. + Wunsafe-loop-optimizations Common Var(warn_unsafe_loop_optimizations) Warning Warn if the loop cannot be optimized due to nontrivial assumptions. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 8c620a5..81fb005 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -252,6 +252,7 @@ Objective-C and Objective-C++ Dialects}. -Wimplicit -Wimplicit-function-declaration -Wimplicit-int @gol -Winit-self -Winline -Wmaybe-uninitialized @gol -Wno-int-to-pointer-cast -Wno-invalid-offsetof @gol +-Wnull-dereference -Wnull-attribute @gol -Winvalid-pch -Wlarger-than=@var{len} -Wunsafe-loop-optimizations @gol -Wlogical-op -Wlong-long @gol -Wmain -Wmaybe-uninitialized -Wmissing-braces -Wmissing-field-initializers @gol @@ -3946,6 +3947,18 @@ In order to get a warning about an unused function parameter, you must either specify @option{-Wextra -Wunused} (note that @option{-Wall} implies @option{-Wunused}), or separately specify @option{-Wunused-parameter}. +@item -Wnull-dereference +@opindex Wnull-dereference +@opindex Wno-null-dereference +Warn if the compiler detects paths which trigger erroneous or undefined +behaviour due to dereferencing a NULL pointer. + +@item -Wnull-attribute +@opindex Wnull-attribute +@opindex Wno-null-attribute +Warn if the compiler detects paths which trigger erroneous or undefined +behaviour due to passing a NULL value for an argument which must be non-NULL or if a function returns NULL when it has been declared as must not return NULL. + @item -Wuninitialized @opindex Wuninitialized @opindex Wno-uninitialized diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c index 56fcfc8..aae403b 100644 --- a/gcc/gimple-ssa-isolate-paths.c +++ b/gcc/gimple-ssa-isolate-paths.c @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "tree-pass.h" #include "tree-cfg.h" +#include "diagnostic.h" static bool cfg_altered; @@ -275,11 +276,34 @@ find_implicit_erroneous_behaviour (void) if (gimple_bb (use_stmt) != bb) continue; - if (infer_nonnull_range (use_stmt, lhs, - flag_isolate_erroneous_paths_dereference, - flag_isolate_erroneous_paths_attribute)) + if (infer_nonnull_range (use_stmt, lhs, true, true)) { + /* By calling infer_nonnull_range again, we can determine + if it was a dereference or attribute which gave us the + NULL range and appropriately customize the warning. */ + bool dereference = infer_nonnull_range (use_stmt, lhs, + true, false); + + if (dereference) + warning_at ((gimple_location (use_stmt) + ? gimple_location (use_stmt) + : gimple_phi_arg_location (phi, i)), + OPT_Wnull_dereference, + "Potential NULL pointer dereference"); + else + warning_at ((gimple_location (use_stmt) + ? gimple_location (use_stmt) + : gimple_phi_arg_location (phi, i)), + OPT_Wnull_attribute, + "Potential invalid NULL argument or return value"); + + if ((!flag_isolate_erroneous_paths_dereference + && dereference) + || (!flag_isolate_erroneous_paths_attribute + && !dereference)) + continue; + duplicate = isolate_path (bb, duplicate, e, use_stmt, lhs); @@ -328,10 +352,27 @@ find_explicit_erroneous_behaviour (void) /* By passing null_pointer_node, we can use infer_nonnull_range to detect explicit NULL pointer dereferences and other uses where a non-NULL value is required. */ - if (infer_nonnull_range (stmt, null_pointer_node, - flag_isolate_erroneous_paths_dereference, - flag_isolate_erroneous_paths_attribute)) + if (infer_nonnull_range (stmt, null_pointer_node, true, true)) { + /* By calling infer_nonnull_range again, we can determine + if it was a dereference or attribute which gave us the + NULL range. */ + bool dereference = infer_nonnull_range (stmt, null_pointer_node, + true, false); + + if (dereference) + warning_at (gimple_location (stmt), + OPT_Wnull_dereference, + "NULL pointer dereference"); + else + warning_at (gimple_location (stmt), + OPT_Wnull_attribute, + "Invalid NULL argument or return value"); + + if ((!flag_isolate_erroneous_paths_dereference && dereference) + || (!flag_isolate_erroneous_paths_attribute && !dereference)) + continue; + insert_trap_and_remove_trailing_statements (&si, null_pointer_node); @@ -417,10 +458,10 @@ gimple_ssa_isolate_erroneous_paths (void) static bool gate_isolate_erroneous_paths (void) { - /* If we do not have a suitable builtin function for the trap statement, - then do not perform the optimization. */ return (flag_isolate_erroneous_paths_dereference != 0 - || flag_isolate_erroneous_paths_attribute != 0); + || flag_isolate_erroneous_paths_attribute != 0 + || warn_null_dereference + || warn_null_attribute); } namespace { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fa61d5c..a9c5654 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2014-01-27 Jeff Law + + * gcc.dg/nullwarn.c: New test. + * gcc.dg/tree-ssa/isolate-1.c: Split into two tests. + isolate-1.c, and isolate-1a.c. Add appropriate warning + markers for the former. Disable the optimization, but + enable the warnings for the former test. The latter + test just checks the optimization. + * gcc.dg/tree-ssa-isolate-2.c: Similarly. + * gcc.dg/tree-ssa-isolate-3.c: Similarly. + * gcc.dg/tree-ssa-isolate-4.c: Similarly. + * gcc.dg/tree-ssa-isolate-5.c: Similarly. + 2014-01-27 Christian Bruel * gcc.target/sh/torture/strncmp.c: New tests. diff --git a/gcc/testsuite/gcc.dg/nullwarn.c b/gcc/testsuite/gcc.dg/nullwarn.c new file mode 100644 index 0000000..a496aaf --- /dev/null +++ b/gcc/testsuite/gcc.dg/nullwarn.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wnull-dereference" } */ + +#include + +struct t +{ + int bar; +}; + +void test1 () +{ + struct t *s = NULL; + s->bar = 1; /* { dg-warning "NULL pointer dereference" } */ +} + +void test2 (struct t *s) +{ + if (s == NULL && s->bar > 2) /* { dg-warning "NULL pointer dereference" } */ + return; + + s->bar = 3; +} + +void test3 (struct t *s) +{ + if (s != NULL || s->bar > 2) /* { dg-warning "NULL pointer dereference" } */ + return; + + s->bar = 3; /* { dg-warning "NULL pointer dereference" } */ +} + +void test4 (struct t *s) +{ + if (s != NULL && s->bar > 2) /* { dg-bogus "NULL pointer dereference" } */ + return; +} + +void test5 (struct t *s) +{ + if (s == NULL || s->bar > 2) /* { dg-bogus "NULL pointer dereference" } */ + return; + +} + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c index f1f3101..fabf016 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-isolate-paths" } */ +/* { dg-options "-O2 -fno-isolate-erroneous-paths-dereference -Wnull-dereference" } */ struct demangle_component @@ -38,23 +38,7 @@ d_type (struct d_info *di) { struct demangle_component *ret; ret = d_make_empty (di); - ret->type = 42; - ret->zzz = -1; + ret->type = 42; /* { dg-warning "NULL pointer dereference" } */ + ret->zzz = -1; /* { dg-warning "NULL pointer dereference" } */ return ret; } - -/* We're testing three aspects of isolation here. First that isolation - occurs, second that if we have two null dereferences in a block that - that we delete everything from the first dereferece to the end of the - block, regardless of which comes first in the immediate use iterator - and finally that we set the RHS of the store to zero. */ -/* { dg-final { scan-tree-dump-times "__builtin_trap" 1 "isolate-paths"} } */ -/* { dg-final { scan-tree-dump-times "->type = 42" 1 "isolate-paths"} } */ -/* { dg-final { scan-tree-dump-times "->type ={v} 0" 1 "isolate-paths"} } */ -/* { dg-final { scan-tree-dump-times "->zzz" 1 "isolate-paths"} } */ -/* { dg-final { cleanup-tree-dump "isolate-paths" } } */ - - - - - diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-1a.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-1a.c new file mode 100644 index 0000000..629f051 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-1a.c @@ -0,0 +1,21 @@ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-isolate-paths" } */ + +#include "isolate-1.c" + +/* We're testing three aspects of isolation here. First that isolation + occurs, second that if we have two null dereferences in a block that + that we delete everything from the first dereferece to the end of the + block, regardless of which comes first in the immediate use iterator + and finally that we set the RHS of the store to zero. */ +/* { dg-final { scan-tree-dump-times "__builtin_trap" 1 "isolate-paths"} } */ +/* { dg-final { scan-tree-dump-times "->type = 42" 1 "isolate-paths"} } */ +/* { dg-final { scan-tree-dump-times "->type ={v} 0" 1 "isolate-paths"} } */ +/* { dg-final { scan-tree-dump-times "->zzz" 1 "isolate-paths"} } */ +/* { dg-final { cleanup-tree-dump "isolate-paths" } } */ + + + + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-2.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-2.c index bfcaa2b..247da04 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fisolate-erroneous-paths-attribute -fdump-tree-isolate-paths -fdump-tree-phicprop1" } */ +/* { dg-options "-O2 -fno-isolate-erroneous-paths-attribute -Wnull-attribute" } */ int z; @@ -17,7 +17,7 @@ foo(int a) case 0: return &z; default: - return (int *)0; + return (int *)0; /* { dg-warning "NULL argument or return value" } */ } } @@ -25,19 +25,5 @@ foo(int a) int * bar (void) { - return 0; + return 0; /* { dg-warning "NULL argument or return value" } */ } - -/* We testing that the path isolation code can take advantage of the - returns non-null attribute to isolate a path where NULL flows into - a return statement. We test this twice, once where the NULL flows - from a PHI, the second with an explicit return 0 in the IL. - - We also verify that after isolation phi-cprop simplifies the - return statement so that it returns &z directly. -/* { dg-final { scan-tree-dump-times "__builtin_trap" 2 "isolate-paths"} } */ -/* { dg-final { scan-tree-dump-times "return &z;" 1 "phicprop1"} } */ -/* { dg-final { cleanup-tree-dump "isolate-paths" } } */ -/* { dg-final { cleanup-tree-dump "phicprop1" } } */ - - diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-2a.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-2a.c new file mode 100644 index 0000000..4798550 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-2a.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fisolate-erroneous-paths-attribute -fdump-tree-isolate-paths -fdump-tree-phicprop1" } */ + +#include "isolate-2.c" + +/* We testing that the path isolation code can take advantage of the + returns non-null attribute to isolate a path where NULL flows into + a return statement. We test this twice, once where the NULL flows + from a PHI, the second with an explicit return 0 in the IL. + + We also verify that after isolation phi-cprop simplifies the + return statement so that it returns &z directly. +/* { dg-final { scan-tree-dump-times "__builtin_trap" 2 "isolate-paths"} } */ +/* { dg-final { scan-tree-dump-times "return &z;" 1 "phicprop1"} } */ +/* { dg-final { cleanup-tree-dump "isolate-paths" } } */ +/* { dg-final { cleanup-tree-dump "phicprop1" } } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-3.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-3.c index 7dddd80..7a56548 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-isolate-paths" } */ +/* { dg-options "-O2 -fno-isolate-erroneous-paths-dereference -Wnull-dereference" } */ typedef long unsigned int size_t; @@ -28,7 +28,7 @@ static __inline__ void VEC_rtx_gc_safe_grow (VEC_rtx_gc ** vec_, int size_, const char *file_, unsigned line_, const char *function_) { - ((*vec_) ? &(*vec_)->base : 0)->num = size_; + ((*vec_) ? &(*vec_)->base : 0)->num = size_; /* { dg-warning "NULL pointer dereference" } */ } static __inline__ void @@ -50,16 +50,3 @@ init_alias_analysis (void) (&(reg_base_value), maxreg, "../../../gcc-4.6.0/gcc/alias.c", 2755, __FUNCTION__, arf ())); } - - - -/* This is an example of how a NULL pointer dereference can show up - without a PHI. Note VEC_rtx_gcc_safe_grow. If an earlier pass - (such as VRP) isolates the NULL path for some reason or another - we end up with an explicit NULL dereference in the IL. Yes, it - started with a PHI, but by the time the path isolation code runs - its explicit in the IL. */ -/* { dg-final { scan-tree-dump-times "__builtin_trap" 1 "isolate-paths"} } */ -/* { dg-final { cleanup-tree-dump "isolate-paths" } } */ - - diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-3a.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-3a.c new file mode 100644 index 0000000..fdfafff --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-3a.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-isolate-paths" } */ + +#include "isolate-3.c" + +/* This is an example of how a NULL pointer dereference can show up + without a PHI. Note VEC_rtx_gcc_safe_grow. If an earlier pass + (such as VRP) isolates the NULL path for some reason or another + we end up with an explicit NULL dereference in the IL. Yes, it + started with a PHI, but by the time the path isolation code runs + its explicit in the IL. */ +/* { dg-final { scan-tree-dump-times "__builtin_trap" 1 "isolate-paths"} } */ +/* { dg-final { cleanup-tree-dump "isolate-paths" } } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-4.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-4.c index c9c074d..ed48e5f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fisolate-erroneous-paths-attribute -fdump-tree-isolate-paths -fdump-tree-phicprop1" } */ +/* { dg-options "-O2 -fno-isolate-erroneous-paths-attribute -Wnull-attribute" } */ extern void foo(void *) __attribute__ ((__nonnull__ (1))); @@ -9,24 +9,11 @@ int z; void com (int a) { - foo (a == 42 ? &z : (void *) 0); + foo (a == 42 ? &z : (void *) 0); /* { dg-warning "NULL argument or return value" } */ } void bar (void) { - foo ((void *)0); + foo ((void *)0); /* { dg-warning "NULL argument or return value" } */ } - -/* We testing that the path isolation code can take advantage of the - returns non-null attribute to isolate a path where NULL flows into - a return statement. - - We also verify that after isolation phi-cprop simplifies the - return statement so that it returns &z directly. -/* { dg-final { scan-tree-dump-times "__builtin_trap" 2 "isolate-paths"} } */ -/* { dg-final { scan-tree-dump-times "foo .&z.;" 1 "phicprop1"} } */ -/* { dg-final { cleanup-tree-dump "isolate-paths" } } */ -/* { dg-final { cleanup-tree-dump "phicprop1" } } */ - - diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-4a.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-4a.c new file mode 100644 index 0000000..85007ae --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-4a.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fisolate-erroneous-paths-attribute -fdump-tree-isolate-paths -fdump-tree-phicprop1" } */ + +#include "isolate-4.c" + +/* We testing that the path isolation code can take advantage of the + returns non-null attribute to isolate a path where NULL flows into + a return statement. + + We also verify that after isolation phi-cprop simplifies the + return statement so that it returns &z directly. +/* { dg-final { scan-tree-dump-times "__builtin_trap" 2 "isolate-paths"} } */ +/* { dg-final { scan-tree-dump-times "foo .&z.;" 1 "phicprop1"} } */ +/* { dg-final { cleanup-tree-dump "isolate-paths" } } */ +/* { dg-final { cleanup-tree-dump "phicprop1" } } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c index 4d01d5c..89afc3a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-isolate-paths -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fno-isolate-erroneous-paths-dereference -Wnull-dereference" } */ struct demangle_component { @@ -32,21 +32,7 @@ d_type (struct d_info *di) { struct demangle_component *ret; ret = d_make_empty (di); - foo (ret->type); - bar (ret->zzz); + foo (ret->type); /* { dg-warning "NULL pointer dereference" } */ + bar (ret->zzz); /* { dg-warning "NULL pointer dereference" } */ return ret; } - -/* We're testing two aspects of isolation here. First that isolation - occurs, second that if we have two null dereferences in a block that - that we delete everything from the first dereferece to the end of the - block, regardless of which comes first in the immediate use iterator. - - We leave the 0->type in the IL, so expect to see ->type twice. */ -/* { dg-final { scan-tree-dump-times "__builtin_trap" 1 "isolate-paths"} } */ -/* { dg-final { scan-tree-dump-times "->type" 2 "isolate-paths"} } */ -/* { dg-final { scan-tree-dump-times "->type" 1 "optimized"} } */ -/* { dg-final { scan-tree-dump-times "\\.type" 1 "optimized"} } */ -/* { dg-final { scan-tree-dump-times "->zzz" 1 "isolate-paths"} } */ -/* { dg-final { cleanup-tree-dump "isolate-paths" } } */ -/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-5a.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-5a.c new file mode 100644 index 0000000..0402be9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-5a.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-isolate-paths -fdump-tree-optimized" } */ + +#include "isolate-5.c" + +/* We're testing two aspects of isolation here. First that isolation + occurs, second that if we have two null dereferences in a block that + that we delete everything from the first dereferece to the end of the + block, regardless of which comes first in the immediate use iterator. + + We leave the 0->type in the IL, so expect to see ->type twice. */ +/* { dg-final { scan-tree-dump-times "__builtin_trap" 1 "isolate-paths"} } */ +/* { dg-final { scan-tree-dump-times "->type" 2 "isolate-paths"} } */ +/* { dg-final { scan-tree-dump-times "->type" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "\\.type" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "->zzz" 1 "isolate-paths"} } */ +/* { dg-final { cleanup-tree-dump "isolate-paths" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */