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).