This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Warn on and fold NULL checks against inline functions
- From: Patrick Palka <patrick at parcs dot ath dot cx>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Patrick Palka <patrick at parcs dot ath dot cx>
- Date: Mon, 26 May 2014 15:01:57 -0400
- Subject: [PATCH] Warn on and fold NULL checks against inline functions
- Authentication-results: sourceware.org; auth=none
Hi,
This patch teaches the C++ frontend to warn on NULL checks against
inline functions and it teaches the middle-end to fold NULL checks
against inline functions. These two things are currently done for
non-inline C++ functions, but inline functions are exceptional in that
the C++ frontend marks them as weak, and NULL checks against weak
symbols cannot be folded in general because the symbol may be mapped to
NULL at link-time.
But in the case of an inline function, the fact that it's a weak symbol
is an implementation detail. And because it is not permitted to
explicitly give an inline function the "weak" attribute (see
handle_weak_attribute), in order to acheive $SUBJECT it suffices to
assume that all inline functions are non-null, which is what this patch
does.
Bootstrap and regtest against x86_64-unknown-linux-gnu in progress. Is
this patch OK assuming no regressions?
2014-05-26 Patrick Palka <patrick@parcs.ath.cx>
* c-family/c-common.c (decl_with_nonnull_addr_p): Assume inline
functions are non-null.
* fold-const.c (tree_single_nonzero_warnv_p): Likewise.
---
gcc/c-family/c-common.c | 4 +++-
gcc/fold-const.c | 5 ++++-
gcc/testsuite/g++.dg/inline-1.C | 14 ++++++++++++++
3 files changed, 21 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/inline-1.C
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 6ec14fc..d4747a0 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -4508,7 +4508,9 @@ decl_with_nonnull_addr_p (const_tree expr)
return (DECL_P (expr)
&& (TREE_CODE (expr) == PARM_DECL
|| TREE_CODE (expr) == LABEL_DECL
- || !DECL_WEAK (expr)));
+ || !DECL_WEAK (expr)
+ || (TREE_CODE (expr) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (expr))));
}
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 188b179..2796079 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -16052,7 +16052,10 @@ tree_single_nonzero_warnv_p (tree t, bool *strict_overflow_p)
|| (DECL_CONTEXT (base)
&& TREE_CODE (DECL_CONTEXT (base)) == FUNCTION_DECL
&& auto_var_in_fn_p (base, DECL_CONTEXT (base)))))
- return !VAR_OR_FUNCTION_DECL_P (base) || !DECL_WEAK (base);
+ return !VAR_OR_FUNCTION_DECL_P (base)
+ || !DECL_WEAK (base)
+ || (TREE_CODE (base) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (base));
/* Constants are never weak. */
if (CONSTANT_CLASS_P (base))
diff --git a/gcc/testsuite/g++.dg/inline-1.C b/gcc/testsuite/g++.dg/inline-1.C
new file mode 100644
index 0000000..65beff1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/inline-1.C
@@ -0,0 +1,14 @@
+// { dg-options "-Waddress" }
+
+inline void
+foo (void)
+{
+}
+
+int
+bar (void)
+{
+ return foo == 0; // { dg-warning "never be NULL" }
+}
+
+// { dg-final { scan-assembler-not "foo" } }
--
2.0.0.rc2