[RFC] Support for nonzero attribute

2022-06-03 Thread Miika via Gcc
Hello,

I would like to add support for new attribute: nonzero.
Nonzero attribute works the same way as nonnull but instead of checking for
NULL, it checks for integer or enum with value 0.

Nonzero attribute would issue warnings with new compiler flag
-Wnonzero and -Wnonzero-compare.

Nonzero could be useful when user wants to make sure that for example enum
with value of 0 is not used or flag argument is not set to 0.


For example compiling following code with "gcc -Wnonzero -Wnonzero-compare 
foo.c"

#include 
enum bar{NONE, SOME};

void foo(int d, enum bar b) __attribute__ ((nonzero (1, 2)));
void foo(int d, enum bar b) {
printf("%d\n", d == 0);
printf("%d\n", b == NONE);
}

int main() {
foo(0, NONE);
}


Would give the following error

foo.c: In function 'main':
foo.c:11:9: warning: zero argument where nonzero required (argument 1) 
[-Wnonzero]
   11 | foo(0, NONE);
  | ^~~
foo.c:11:9: warning: zero argument where nonzero required (argument 2) 
[-Wnonzero]
foo.c: In function 'foo':
foo.c:6:9: warning: 'nonzero' argument 'd' compared to 0 [-Wnonzero-compare]
6 | printf("%d\n", d == 0);
  | ^~
foo.c:7:9: warning: 'nonzero' argument 'b' compared to 0 [-Wnonzero-compare]
7 | printf("%d\n", b == NONE);
  | ^


I attached a diff of my POC implementation. It's basically a copied and modified
version of nonnull attribute. The diff is fairly big and doesn't contain any 
tests.
I'm more than happy to figure out tests for it if people think that supporting
nonzero attribute is a good idea.

This is my first time working with GCC so please let me know if there's any 
mistakes!

Best wishes,
Miika Alikirri

---
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5d05e8e0dc8..ae5db84cdfa 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1360,6 +1360,7 @@ OBJS = \
gimple-ssa-evrp-analyze.o \
gimple-ssa-isolate-paths.o \
gimple-ssa-nonnull-compare.o \
+   gimple-ssa-nonzero-compare.o \
gimple-ssa-split-paths.o \
gimple-ssa-store-merging.o \
gimple-ssa-strength-reduction.o \
diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def
index 3239311b5a4..04db95d27ff 100644
--- a/gcc/builtin-attrs.def
+++ b/gcc/builtin-attrs.def
@@ -98,6 +98,7 @@ DEF_ATTR_IDENT (ATTR_FORMAT, "format")
 DEF_ATTR_IDENT (ATTR_FORMAT_ARG, "format_arg")
 DEF_ATTR_IDENT (ATTR_MALLOC, "malloc")
 DEF_ATTR_IDENT (ATTR_NONNULL, "nonnull")
+DEF_ATTR_IDENT (ATTR_NONZERO, "nonzero")
 DEF_ATTR_IDENT (ATTR_NORETURN, "noreturn")
 DEF_ATTR_IDENT (ATTR_NOTHROW, "nothrow")
 DEF_ATTR_IDENT (ATTR_LEAF, "leaf")
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index ac936d5..b76e56b14b9 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -119,6 +119,7 @@ static tree handle_novops_attribute (tree *, tree, tree, 
int, bool *);
 static tree handle_vector_size_attribute (tree *, tree, tree, int,
  bool *);
 static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
+static tree handle_nonzero_attribute (tree *, tree, tree, int, bool *);
 static tree handle_nonstring_attribute (tree *, tree, tree, int, bool *);
 static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
 static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
@@ -379,6 +380,8 @@ const struct attribute_spec c_common_attribute_table[] =
  handle_tls_model_attribute, NULL },
   { "nonnull",0, -1, false, true, true, false,
  handle_nonnull_attribute, NULL },
+  { "nonzero",0, -1, false, true, true, false,
+ handle_nonzero_attribute, NULL },
   { "nonstring",  0, 0, true, false, false, false,
  handle_nonstring_attribute, NULL },
   { "nothrow",0, 0, true,  false, false, false,
@@ -3754,6 +3757,55 @@ handle_nonnull_attribute (tree *node, tree name,
   return NULL_TREE;
 }

+/* Handle the "nonzero" attribute.  */
+
+static tree
+handle_nonzero_attribute (tree *node, tree name,
+ tree args, int ARG_UNUSED (flags),
+ bool *no_add_attrs)
+{
+  tree type = *node;
+
+  /* If no arguments are specified, all int arguments should be
+ non-zero.  Verify a full prototype is given so that the arguments
+ will have the correct types when we actually check them later.
+ Avoid diagnosing type-generic built-ins since those have no
+ prototype.  */
+  if (!args)
+{
+  if (!prototype_p (type)
+ && (!TYPE_ATTRIBUTES (type)
+ || !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type
+   {
+ error ("%qE attribute without arguments on a non-prototype",
+name);
+ *no_add_attrs = true;
+   }
+  return NULL_TR

Re: [RFC] Support for nonzero attribute

2022-06-03 Thread Jakub Jelinek via Gcc
On Fri, Jun 03, 2022 at 04:34:48PM +, Miika via Gcc wrote:
> Hello,
> 
> I would like to add support for new attribute: nonzero.
> Nonzero attribute works the same way as nonnull but instead of checking for
> NULL, it checks for integer or enum with value 0.

NULL/nullptr is very special pointer (at it doesn't point to any object),
while integer with value 0 is just one of many possible values.
For some functions, 0 could be a value it wants to avoid, for others
such value could be -1, negative value, positive, whatever else...
IMHO if we want to add anything like this, it should be more generic,
specify that a particular argument must have value in a specific range.

Jakub



gcc-11-20220603 is now available

2022-06-03 Thread GCC Administrator via Gcc
Snapshot gcc-11-20220603 is now available on
  https://gcc.gnu.org/pub/gcc/snapshots/11-20220603/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 11 git branch
with the following options: git://gcc.gnu.org/git/gcc.git branch 
releases/gcc-11 revision c27cbeb985f7b6e1759399971b4fe2773e91ca71

You'll find:

 gcc-11-20220603.tar.xz   Complete GCC

  SHA256=2bed79a067094784a3213209a933e86f03877360267fb9a4ff76ec8e7f43d8f1
  SHA1=0abdda4c532173f8c49a5fd563928e32a579eb3e

Diffs from 11-20220527 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-11
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.


.eh_frame augmentation character for MTE stack tagging

2022-06-03 Thread Florian Mayer via Gcc
Hey!

We are in the process of implementing MTE (Memory Tagging Extension)
stack tagging in LLVM. To support stack tagging in combination with
exceptions, we need to make sure that the unwinder will untag stack
frames, to avoid leaving behind stale tags. As such, we need some way
to communicate to the unwinder to do that.

In a discussion on llvm-dev [1], it was decided the best way to go
forward with this would be to add a new character ('G' for taG, as the
MTE instructions stg etc.) to the eh_frame augmentation string, and
then handle that in libunwind by clearing the tags of the respective
frame.

How does that sound? Would that be a good course of action for GCC as well?

Thanks,
Florian

[1]: https://lists.llvm.org/pipermail/llvm-dev/2020-May/141345.html