public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] c, cp: CHERI warning improvements
@ 2022-11-01 11:01 Alex Coplan
  0 siblings, 0 replies; only message in thread
From: Alex Coplan @ 2022-11-01 11:01 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:3f068b78c12c9d48936fc33c7bc42fdb7008791b

commit 3f068b78c12c9d48936fc33c7bc42fdb7008791b
Author: Alex Coplan <alex.coplan@arm.com>
Date:   Thu Oct 13 15:02:11 2022 +0100

    c, cp: CHERI warning improvements
    
    Currently for C code like:
    
    char *f(long x) { return (char *)x; }
    
    we emit the warning "cast from provenance-free integer type to pointer
    type will give pointer that can not be dereferenced" but we reuse the
    -Wint-to-pointer-cast warning flag for this.
    
    This patch adds the -Wcheri-capability-misuse flag to align better with
    CHERI LLVM and switches the C frontend to using that flag for this
    warning. We also implement the warning in the C++ frontend, and add
    tests for this warning for both C and C++.
    
    We also take this opportunity to implement the -Wcheri warning group,
    and add all existing CHERI warnings under this flag. This enables using
    -Wno-cheri to turn all the CHERI warnings off, and e.g. -Werror=cheri to
    turn all CHERI warnings into errors.

Diff:
---
 gcc/c-family/c-common.c                            |  9 +++++
 gcc/c-family/c-common.h                            |  2 +
 gcc/c/c-typeck.c                                   |  7 +---
 gcc/common.opt                                     | 19 ++++++---
 gcc/cp/typeck.c                                    |  8 +++-
 .../g++.target/aarch64/morello/cap-misuse-warn.C   | 45 ++++++++++++++++++++++
 .../gcc.target/aarch64/morello/cap-misuse-warn.c   | 24 ++++++++++++
 .../aarch64/morello/cheri-warning-group.c          |  7 ++++
 .../gcc.target/aarch64/morello/conv-bool-ptr.c     |  3 --
 9 files changed, 107 insertions(+), 17 deletions(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 719b7e77a67..4f90f4ac1a4 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5305,6 +5305,15 @@ unary_op_get_intcap_provenance (tree c)
   return c;
 }
 
+void
+warn_int_cap_conversion (location_t loc)
+{
+  if (warning_at (loc, OPT_Wcheri_capability_misuse,
+    "cast from provenance-free integer type to pointer type will give "
+    "pointer that can not be dereferenced"))
+    inform (loc, "insert cast to intptr_t to silence this warning");
+}
+
 /* Given a boolean expression ARG, return a tree representing an increment
    or decrement (as indicated by CODE) of ARG.  The front end must check for
    invalid cases (e.g., decrement in C++).  */
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 0479ea55323..9382383fc46 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1016,6 +1016,8 @@ extern tree binary_op_get_intcap_provenance (location_t,
 					     enum tree_code, tree, tree, bool);
 extern tree unary_op_get_intcap_provenance (tree);
 
+extern void warn_int_cap_conversion (location_t);
+
 /* Handle increment and decrement of boolean types.  */
 extern tree boolean_increment (enum tree_code, tree);
 
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 0195114a3b2..b30442e3c29 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -6074,12 +6074,7 @@ build_c_cast (location_t loc, tree type, tree expr)
 	  && INTEGRAL_TYPE_P (TREE_TYPE (value))
 	  && TREE_CODE (type) != INTCAP_TYPE
 	  && TREE_CODE (value) != INTEGER_CST)
-	{
-	  if (warning_at (loc, OPT_Wint_to_pointer_cast,
-	    "cast from provenance-free integer type to pointer type will give "
-	    "pointer that can not be dereferenced"))
-	    inform (loc, "insert cast to intptr_t to silence this warning");
-	}
+	warn_int_cap_conversion (loc);
 
       if (capability_type_p (type)
 	  && TREE_CODE (type) != INTCAP_TYPE
diff --git a/gcc/common.opt b/gcc/common.opt
index d9ab8c4c18a..85101bad7e6 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -573,32 +573,39 @@ Wcpp
 Common Var(warn_cpp) Init(1) Warning
 Warn when a #warning directive is encountered.
 
+Wcheri
+Common Var(warn_cheri) Warning
+Diagnostic group for all CHERI warnings.
+
 Wcheri-bounds
-Common Var(warn_cheri_bounds) Init(1) Warning
+Common Var(warn_cheri_bounds) Init(1) Warning EnabledBy(Wcheri)
 Warn when an object can not be aligned to ensure non-overlapping bounds.
 
+Wcheri-capability-misuse
+Common Var(warn_cheri_cap_misuse) Init(1) Warning EnabledBy(Wcheri)
+
 Wcheri-provenance
-Common Var(warn_cheri_provenance) Init(1) Warning
+Common Var(warn_cheri_provenance) Init(1) Warning EnabledBy(Wcheri)
 Warn when an expression has ambiguous pointer provenance or will be known
 invalid.
 
 Wcheri-implicit-pointer-conversion-from-cap
-Common Var(warn_cheri_implicit_pointer_conversion_from_cap) Init(1) Warning
+Common Var(warn_cheri_implicit_pointer_conversion_from_cap) Init(1) Warning EnabledBy(Wcheri)
 Warn on implicit conversions from capability pointers to non-capability
 pointers.
 
 Wcheri-implicit-pointer-conversion-to-cap
-Common Var(warn_cheri_implicit_pointer_conversion_to_cap) Init(1) Warning
+Common Var(warn_cheri_implicit_pointer_conversion_to_cap) Init(1) Warning EnabledBy(Wcheri)
 Warn on implicit conversions from non-capability pointers to capability
 pointers.
 
 Wcheri-explicit-pointer-conversion-from-cap
-Common Var(warn_cheri_explicit_pointer_conversion_from_cap) Init(1) Warning
+Common Var(warn_cheri_explicit_pointer_conversion_from_cap) Init(1) Warning EnabledBy(Wcheri)
 Warn on explicit conversions from capability pointers to non-capability
 pointers.
 
 Wcheri-explicit-pointer-conversion-to-cap
-Common Var(warn_cheri_explicit_pointer_conversion_to_cap) Init(1) Warning
+Common Var(warn_cheri_explicit_pointer_conversion_to_cap) Init(1) Warning EnabledBy(Wcheri)
 Warn on explicit conversions from non-capability pointers to capability
 pointers.
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 31b86f96c02..0b398a18982 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8051,8 +8051,12 @@ build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
      converted to a pointer.  */
   else if (TYPE_PTR_P (type) && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
 				 || INTCAP_TYPE_P (intype)))
-    /* OK */
-    ;
+    {
+      if (capability_type_p (type)
+	  && !INTCAP_TYPE_P (intype)
+	  && TREE_CODE (cp_fully_fold (expr)) != INTEGER_CST)
+	warn_int_cap_conversion (loc);
+    }
   else if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
 	    || TYPE_PTR_OR_PTRMEM_P (type))
 	   && same_type_p (type, intype))
diff --git a/gcc/testsuite/g++.target/aarch64/morello/cap-misuse-warn.C b/gcc/testsuite/g++.target/aarch64/morello/cap-misuse-warn.C
new file mode 100644
index 00000000000..ccd222fdc66
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/morello/cap-misuse-warn.C
@@ -0,0 +1,45 @@
+/* { dg-do compile { target { ! cheri_capability_hybrid } } } */
+
+enum e { foo = 1 };
+
+void *f1(bool x) { return (void *)x; }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f2(e x) { return (void *)x; }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f3(signed char x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f4(unsigned char x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f5(short x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f6(unsigned short x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f7(int x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f8(unsigned int x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f9(long x) { return (void *)x; }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f10(unsigned long x) { return (void *)x; }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+
+void *g1(bool x) { return reinterpret_cast<void *>(x); }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *g2(e x) { return reinterpret_cast<void *>(x); }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *g3(signed char x) { return reinterpret_cast<void *>(x); }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *g4(unsigned char x) { return reinterpret_cast<void *>(x); }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *g5(short x) { return reinterpret_cast<void *>(x); }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *g6(unsigned short x) { return reinterpret_cast<void *>(x); }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *g7(int x) { return reinterpret_cast<void *>(x); }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *g8(unsigned int x) { return reinterpret_cast<void *>(x); }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *g9(long x) { return reinterpret_cast<void *>(x); }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *g10(unsigned long x) { return reinterpret_cast<void *>(x); }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/cap-misuse-warn.c b/gcc/testsuite/gcc.target/aarch64/morello/cap-misuse-warn.c
new file mode 100644
index 00000000000..18fd392b7b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/cap-misuse-warn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { ! cheri_capability_hybrid } } } */
+
+enum e { foo = 1 };
+
+void *f1(_Bool x) { return (void *)x; }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f2(enum e x) { return (void *)x; }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f3(signed char x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f4(unsigned char x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f5(short x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f6(unsigned short x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f7(int x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f8(unsigned int x) { return (void *)x; } /* { dg-warning "cast to pointer from integer of different size" } */
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f9(long x) { return (void *)x; }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
+void *f10(unsigned long x) { return (void *)x; }
+/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/cheri-warning-group.c b/gcc/testsuite/gcc.target/aarch64/morello/cheri-warning-group.c
new file mode 100644
index 00000000000..796af812efc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/cheri-warning-group.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-cheri" } */
+
+/* These two functions would normally elicit CHERI warnings, here we're
+   testing that they can both be disabled with -Wno-cheri.  */
+int *f(long l) { return (int *)l; }
+__intcap g(__intcap x, __intcap y) { return x + y; }
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/conv-bool-ptr.c b/gcc/testsuite/gcc.target/aarch64/morello/conv-bool-ptr.c
deleted file mode 100644
index 09d531a2c77..00000000000
--- a/gcc/testsuite/gcc.target/aarch64/morello/conv-bool-ptr.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* { dg-do compile } */
-void *f(_Bool b) { return (void *)b; }
-/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-11-01 11:01 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-01 11:01 [gcc(refs/vendors/ARM/heads/morello)] c, cp: CHERI warning improvements Alex Coplan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).