summaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorglisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-09 13:03:13 +0000
committerglisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-09 13:03:13 +0000
commitd7dcba40a5768c70c40d1b7109377c78010abea4 (patch)
treeca712605143da33b695da4c91076aa641b7f23d3 /gcc/c-family
parent11ad02c667d0c697c971e810fb30504de359371f (diff)
downloadgcc-d7dcba40a5768c70c40d1b7109377c78010abea4.tar.gz
2013-10-09 Marc Glisse <marc.glisse@inria.fr>
PR tree-optimization/20318 gcc/c-family/ * c-common.c (handle_returns_nonnull_attribute): New function. (c_common_attribute_table): Add returns_nonnull. gcc/ * doc/extend.texi (returns_nonnull): New function attribute. * fold-const.c (tree_expr_nonzero_warnv_p): Look for returns_nonnull attribute. * tree-vrp.c (gimple_stmt_nonzero_warnv_p): Likewise. (stmt_interesting_for_vrp): Accept all GIMPLE_CALL. gcc/testsuite/ * c-c++-common/pr20318.c: New file. * gcc.dg/tree-ssa/pr20318.c: New file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@203316 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c20
2 files changed, 26 insertions, 0 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index d468344c735..d94921b456d 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2013-10-09 Marc Glisse <marc.glisse@inria.fr>
+
+ PR tree-optimization/20318
+ * c-common.c (handle_returns_nonnull_attribute): New function.
+ (c_common_attribute_table): Add returns_nonnull.
+
2013-10-03 Marc Glisse <marc.glisse@inria.fr>
PR c++/19476
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 8ecb70cfa7c..5fe7cab0f8b 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -371,6 +371,7 @@ static tree ignore_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *);
+static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *);
static void check_function_nonnull (tree, int, tree *);
static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
@@ -747,6 +748,8 @@ const struct attribute_spec c_common_attribute_table[] =
handle_fnspec_attribute, false },
{ "warn_unused", 0, 0, false, false, false,
handle_warn_unused_attribute, false },
+ { "returns_nonnull", 0, 0, false, true, true,
+ handle_returns_nonnull_attribute, false },
{ NULL, 0, 0, false, false, false, NULL, false }
};
@@ -9048,6 +9051,23 @@ handle_no_split_stack_attribute (tree *node, tree name,
return NULL_TREE;
}
+
+/* Handle a "returns_nonnull" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_returns_nonnull_attribute (tree *node, tree, tree, int,
+ bool *no_add_attrs)
+{
+ // Even without a prototype we still have a return type we can check.
+ if (TREE_CODE (TREE_TYPE (*node)) != POINTER_TYPE)
+ {
+ error ("returns_nonnull attribute on a function not returning a pointer");
+ *no_add_attrs = true;
+ }
+ return NULL_TREE;
+}
+
/* Check for valid arguments being passed to a function with FNTYPE.
There are NARGS arguments in the array ARGARRAY. */