From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7810) id 4A2A93858D35; Tue, 1 Nov 2022 11:01:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4A2A93858D35 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1667300480; bh=FSLwlGQoHZpwIHrYmQH4p4Ezfe7iaYunc+5KgGU7EYo=; h=From:To:Subject:Date:From; b=hC/kGfVy+yq04g96ODQi+WFM9poFaQJ+EBJaiSjwGm8BHXQEIsTlaejOhtWkRMnpS skLu+4xO6lYEiopVPwJfLeS1DOCdq+Y3kIx1+aKTYqz3GoliLyGUd9sWBwlQIFEZNa ie7ID+nW/t0GBKkYhheBmTKJdWgon3nDDKxY+g34= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Alex Coplan To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/morello)] c, cp: CHERI warning improvements X-Act-Checkin: gcc X-Git-Author: Alex Coplan X-Git-Refname: refs/vendors/ARM/heads/morello X-Git-Oldrev: 70924d59c8f02388cbd22a3b6389126ca89e2fac X-Git-Newrev: 3f068b78c12c9d48936fc33c7bc42fdb7008791b Message-Id: <20221101110120.4A2A93858D35@sourceware.org> Date: Tue, 1 Nov 2022 11:01:20 +0000 (GMT) List-Id: https://gcc.gnu.org/g:3f068b78c12c9d48936fc33c7bc42fdb7008791b commit 3f068b78c12c9d48936fc33c7bc42fdb7008791b Author: Alex Coplan 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(x); } +/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */ +void *g2(e x) { return reinterpret_cast(x); } +/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */ +void *g3(signed char x) { return reinterpret_cast(x); } +/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */ +void *g4(unsigned char x) { return reinterpret_cast(x); } +/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */ +void *g5(short x) { return reinterpret_cast(x); } +/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */ +void *g6(unsigned short x) { return reinterpret_cast(x); } +/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */ +void *g7(int x) { return reinterpret_cast(x); } +/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */ +void *g8(unsigned int x) { return reinterpret_cast(x); } +/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */ +void *g9(long x) { return reinterpret_cast(x); } +/* { dg-warning "cast from provenance-free integer type to pointer type" "" { target *-*-* } .-1 } */ +void *g10(unsigned long x) { return reinterpret_cast(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 } */