From patchwork Sat Sep 8 00:00:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luc Van Oostenryck X-Patchwork-Id: 10592705 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3BD13921 for ; Sat, 8 Sep 2018 00:00:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D2642B5FF for ; Sat, 8 Sep 2018 00:00:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 214C22B603; Sat, 8 Sep 2018 00:00:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6D2EB2B5FF for ; Sat, 8 Sep 2018 00:00:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726147AbeIHEoU (ORCPT ); Sat, 8 Sep 2018 00:44:20 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:53219 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725734AbeIHEoU (ORCPT ); Sat, 8 Sep 2018 00:44:20 -0400 Received: by mail-wm0-f65.google.com with SMTP id y139-v6so16022925wmc.2 for ; Fri, 07 Sep 2018 17:00:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=g5D0hEFIJQoTW7xsk9Je6wNss4K/UqmoHEbhNi21A7Q=; b=YmMqdTGk9gkS0ikEHiq23Rh7qfnGQAzWdCwP64UTFbvZjFEnIgoz7kwHPh55MkoHsH vToo98NzOYDnTiXqKK8p0HKnW8HBWbhav3Cti61EIiVBT8MN+S27Tzcc3aYVEtp3YmZQ OgojOx5AJ/yofXR5fo+pzxV5XUKGZ8HW9Bgd6fSf/MXugDf0TtTmLs8EhdmdkW65E97k bXavzxZ0wjrXFupjSkJCx2p9+4dHjcmk2tuXsRWIooXlqti8B/qgI2XzTN+s7dDlUKFF lr7qSqFilQw/W2PTYpi8z2F9TCbU3IzMB/HwSVP+/L5l8/OBBUw8M705Ed2AKO8vKiUS NZmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=g5D0hEFIJQoTW7xsk9Je6wNss4K/UqmoHEbhNi21A7Q=; b=Qx8f1TN6dH6Wu4ptz0wJLIUAPrICRxyTgqqxLaDI+yPL51KImP/vphPavtUNZbqxCz tflBakWQKAyJQEV8dSdJxGckp111BmlIjrjYbOspGT76oqwQGfXfrk5lY5PseyHixvDd EAklnSol756JtxHFK/mMVHFOH+PuNTkJ2yrm+p+KIlRX0wafYcNvfU8U+cg1DEY4IYWp nMthxAdH/G9Cn5JGscUnC0FUWi7tukgQK9KpAfz6lWzPdRh+zBmNdYbpXI6EUZqXu7D2 Fvw5tuBCAb0JnAoKM2CmVBRfqJrmSV0AtO5F5ZoWVtUeFi9BvfOjU/A5yxAWWmFAQzbS X8TA== X-Gm-Message-State: APzg51A3Ua6qNBbPYQmjUcc5k/GEaMVywDKoGEs7CrKsw2V0yCwlvW5R plskPKaO10Hc6O9E0qq5upiqTU0m X-Google-Smtp-Source: ANB0VdZTzc0RVByxhTTudYOnaQc1WEMp6s+ftu6MVqoAoMUbPC3uziTsqnRVFurfmpbFcs0yUBSzoQ== X-Received: by 2002:a1c:b213:: with SMTP id b19-v6mr6383226wmf.141.1536364854382; Fri, 07 Sep 2018 17:00:54 -0700 (PDT) Received: from localhost.localdomain ([2a02:a03f:4006:df00:c856:97f7:a8a9:88f6]) by smtp.gmail.com with ESMTPSA id t132-v6sm12886115wmf.24.2018.09.07.17.00.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 07 Sep 2018 17:00:53 -0700 (PDT) From: Luc Van Oostenryck To: linux-sparse@vger.kernel.org Cc: Christophe Leroy , Luc Van Oostenryck Subject: [PATCH 05/12] enum: add testcase for base & enumerator type Date: Sat, 8 Sep 2018 02:00:39 +0200 Message-Id: <20180908000046.65842-6-luc.vanoostenryck@gmail.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180908000046.65842-1-luc.vanoostenryck@gmail.com> References: <20180908000046.65842-1-luc.vanoostenryck@gmail.com> Sender: linux-sparse-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sparse@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add various testcases for checking enum's base & enumerator type. Signed-off-by: Luc Van Oostenryck --- validation/enum-base-type.c | 29 +++++++++++++++ validation/enum-bitwise.c | 19 ++++++++++ validation/enum-bounds.c | 24 ++++++++++++ validation/enum-init-constness.c | 9 +++++ validation/enum-invalid.c | 11 ++++++ validation/enum-min-size.c | 30 +++++++++++++++ validation/enum-sign-gcc.c | 63 ++++++++++++++++++++++++++++++++ validation/enum-typecheck.c | 39 ++++++++++++++++++++ 8 files changed, 224 insertions(+) create mode 100644 validation/enum-base-type.c create mode 100644 validation/enum-bitwise.c create mode 100644 validation/enum-bounds.c create mode 100644 validation/enum-init-constness.c create mode 100644 validation/enum-invalid.c create mode 100644 validation/enum-min-size.c create mode 100644 validation/enum-sign-gcc.c create mode 100644 validation/enum-typecheck.c diff --git a/validation/enum-base-type.c b/validation/enum-base-type.c new file mode 100644 index 000000000..ecec59296 --- /dev/null +++ b/validation/enum-base-type.c @@ -0,0 +1,29 @@ +enum n { + NA, + NB = 1L, + NC = 1UL, + ND = 1LL, + NE = 1ULL, + NF = -1, + NG = -1L, + NH = -1LL, +}; +_Static_assert(sizeof(enum n) == sizeof(int), "+-1"); + +enum m { + MA = 0L, + MB = 1L, + MG = -1L, +}; +_Static_assert(sizeof(enum m) == sizeof(int), "+-1L"); + +enum p { + PA = 0UL, + PB = 1UL, +}; +_Static_assert(sizeof(enum p) == sizeof(int), "UL"); + +/* + * check-name: enum-base-type + * check-known-to-fail + */ diff --git a/validation/enum-bitwise.c b/validation/enum-bitwise.c new file mode 100644 index 000000000..fcdb8d7a0 --- /dev/null +++ b/validation/enum-bitwise.c @@ -0,0 +1,19 @@ +#define __bitwise __attribute__((bitwise)) +#define __force __attribute__((force)) + +typedef long long __bitwise bits; + +enum r { + RZ = (__force bits) 0, + RO = (__force bits) 1, + RM = (__force bits) -1, +}; + +_Static_assert([typeof(RZ)] == [bits], "RZ"); +_Static_assert([typeof(RO)] == [bits], "RO"); +_Static_assert([typeof(RM)] == [bits], "RM"); +_Static_assert(sizeof(enum r) == sizeof(bits), "bits"); + +/* + * check-name: enum-bitwise + */ diff --git a/validation/enum-bounds.c b/validation/enum-bounds.c new file mode 100644 index 000000000..d8993edb4 --- /dev/null +++ b/validation/enum-bounds.c @@ -0,0 +1,24 @@ +enum bound_int_max { + IMAX = __INT_MAX__, +}; +_Static_assert([typeof(IMAX)] == [int], ""); + +enum bound_int_maxp1 { + IMP1 = __INT_MAX__ + 1L, +}; +_Static_assert([typeof(IMP1)] == [unsigned int], ""); + +enum bound_int_maxm1 { + IMM1 = -__INT_MAX__ - 1L, +}; +_Static_assert([typeof(IMM1)] == [int], ""); + +enum bound_int_maxm2 { + IMM2 = -__INT_MAX__ - 2L, +}; +_Static_assert([typeof(IMM2)] == [long], ""); + +/* + * check-name: enum-bounds + * check-known-to-fail + */ diff --git a/validation/enum-init-constness.c b/validation/enum-init-constness.c new file mode 100644 index 000000000..5b95bc06a --- /dev/null +++ b/validation/enum-init-constness.c @@ -0,0 +1,9 @@ +extern int invalid; + +enum e { + E = 1 ? 1 : invalid +}; + +/* + * check-name: enum-init-constness + */ diff --git a/validation/enum-invalid.c b/validation/enum-invalid.c new file mode 100644 index 000000000..08846442d --- /dev/null +++ b/validation/enum-invalid.c @@ -0,0 +1,11 @@ +enum e { }; +enum f { F = 0.1 }; + +/* + * check-name: enum-invalid + * + * check-error-start +enum-invalid.c:1:10: error: bad enum definition +enum-invalid.c:2:14: error: bad constant expression + * check-error-end + */ diff --git a/validation/enum-min-size.c b/validation/enum-min-size.c new file mode 100644 index 000000000..264a31542 --- /dev/null +++ b/validation/enum-min-size.c @@ -0,0 +1,30 @@ +enum i { I = 1 }; +_Static_assert(sizeof(enum i) == sizeof(int), "int"); +enum u { U = 1U }; +_Static_assert(sizeof(enum u) == sizeof(int), "uint"); + +enum l { L = 1L }; +_Static_assert(sizeof(enum l) == sizeof(int), "long"); +enum m { M = 1UL }; +_Static_assert(sizeof(enum m) == sizeof(int), "ulong"); + +enum n { N = 1LL }; +_Static_assert(sizeof(enum n) == sizeof(int), "llong"); +enum o { O = 1ULL }; +_Static_assert(sizeof(enum o) == sizeof(int), "ullong"); + + +enum mi { MI = -1 }; +_Static_assert(sizeof(enum i) == sizeof(int), "int"); + +enum ml { ML = -1L }; +_Static_assert(sizeof(enum l) == sizeof(int), "long"); + +enum mn { MN = -1LL }; +_Static_assert(sizeof(enum n) == sizeof(int), "llong"); + + +/* + * check-name: enum-min-size + * check-known-to-fail + */ diff --git a/validation/enum-sign-gcc.c b/validation/enum-sign-gcc.c new file mode 100644 index 000000000..c4779dbe6 --- /dev/null +++ b/validation/enum-sign-gcc.c @@ -0,0 +1,63 @@ +// For enum's underlying/compatible type: +// std C: unspecified +// GCC: 'unsigned int' if no negative values, +// otherwise 'int' (see GCC manul 4.9). +// But also accept ulong, long +// For the type of the enumerators: +// std C: 'int' +// GCC: 'int' if the value fit in a 'int' +// otherwise same as the enum underlying type? +// +// The following tests match GCC's choices + +#define is_unsigned(X) ((typeof(X))-1 > 0) + +enum u { + U = 1U, // fit in 'int' + // no negatives +}; +_Static_assert(sizeof(enum u) == sizeof(int), "size"); +_Static_assert(is_unsigned(enum u), "enum u"); +_Static_assert(is_unsigned(U) == 0, "value U"); // fail + +enum v { + V = __INT_MAX__ + 1U, // doesn't fit in 'int' + // no negatives +}; +_Static_assert(sizeof(enum v) == sizeof(int), "size"); +_Static_assert(is_unsigned(enum v), "enum v"); +_Static_assert(is_unsigned(V) == 1, "value V"); + +enum w { + W = __LONG_MAX__ + 1UL, // doesn't fit in 'long' +}; +_Static_assert(sizeof(enum w) == sizeof(long), "size"); +_Static_assert(is_unsigned(enum w), "enum w"); +_Static_assert(is_unsigned(W) == 1, "value W"); + +enum x { + A = 1, // fit in 'int' + B = 0x100000000UL, // doesn't fit in int +}; +_Static_assert(sizeof(enum x) == sizeof(long), "size"); +_Static_assert(is_unsigned(enum x), "enum x"); +_Static_assert(sizeof(A) == sizeof(int), "size A"); // fail +_Static_assert(is_unsigned(A) == 0, "enum A"); // fail +_Static_assert(sizeof(B) == sizeof(long), "size B"); +_Static_assert(is_unsigned(B) == 1, "enum B"); + +enum y { + C = 1, // fit in 'int' + D = 0x100000000L, // doesn't fit in int +}; +_Static_assert(sizeof(enum y) == sizeof(long), "size"); +_Static_assert(is_unsigned(enum y), "enum y"); +_Static_assert(sizeof(C) == sizeof(int), "size C"); // fail +_Static_assert(is_unsigned(C) == 0, "enum C"); // fail +_Static_assert(sizeof(D) == sizeof(long), "size D"); +_Static_assert(is_unsigned(D) == 1, "enum D"); + +/* + * check-name: enum-sign-gcc + * check-known-to-fail + */ diff --git a/validation/enum-typecheck.c b/validation/enum-typecheck.c new file mode 100644 index 000000000..77b77b47b --- /dev/null +++ b/validation/enum-typecheck.c @@ -0,0 +1,39 @@ +enum good { G, }; +enum bad { B, }; +enum good g; + +enum good compat_int(void) { return 1; } + +void parg(enum good); +void parg(enum bad); + +void farg(enum good a); +void farg(enum bad a) { } + +enum good pret(void); +enum bad pret(void); + +enum good fret(void); +enum bad fret(void) { return 0; } + + +enum good *ptr; +enum bad *ptr; + +enum good *gptr = &g; +enum bad *bptr = &g; + +/* + * check-name: enum-typecheck + * check-command: sparse -Wno-decl $file + * check-known-to-fail + * + * check-error-start +enum-typecheck.c:8:6: error: symbol 'parg' redeclared with different type +enum-typecheck.c:11:6: error: symbol 'farg' redeclared with different type +enum-typecheck.c:14:11: error: symbol 'pret' redeclared with different type +enum-typecheck.c:17:11: error: symbol 'fret' redeclared with different type +enum-typecheck.c:21:12: error: symbol 'ptr' redeclared with different type +enum-typecheck.c:24:20: warning: incorrect type in initializer (different type sizes) + * check-error-end + */