From patchwork Wed Apr 5 21:09:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luc Van Oostenryck X-Patchwork-Id: 9665773 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A3843602B5 for ; Wed, 5 Apr 2017 21:09:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 93A9D28113 for ; Wed, 5 Apr 2017 21:09:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 888B128178; Wed, 5 Apr 2017 21:09:51 +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=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID 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 DB72F28159 for ; Wed, 5 Apr 2017 21:09:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933224AbdDEVJu (ORCPT ); Wed, 5 Apr 2017 17:09:50 -0400 Received: from mail-wr0-f196.google.com ([209.85.128.196]:32921 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934285AbdDEVJs (ORCPT ); Wed, 5 Apr 2017 17:09:48 -0400 Received: by mail-wr0-f196.google.com with SMTP id g19so6062187wrb.0 for ; Wed, 05 Apr 2017 14:09:48 -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=W6R+EH0o7qXusqVpmJt3ujVljK2zU7hkaqSZHFRZeac=; b=j2pbmEoNLupVLdrdfQ5i+X6EhTGEjgUVeotGV7elKgJ7wSPGXuDa6ZBk2vCLwxpbce 2FHuZTjpH9QRri8SWdhZN54uZ6OmUUnu+z3UIuSPblUXQeWZ9zRbVNl6MxDP1aSjsSVf zn+vQyWfTwEt2hYcoCcrMjdxIbL4X5nPtC+3upAtw2MeHxELAvjnfcIkflcq3pOQ0S/+ iichu5luULlqo1wjWGMb3I17hyZspvBZv/Pc+r9BqK7L5jix7k4CTsc+ANn1RS8DUhbE ClMRv/Z/e0AnVfoQrP8/TaK2843Dnxd9FUnwwGC+pLhclVROFhpANkqzfAwhQQ83l3d4 +lhQ== 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=W6R+EH0o7qXusqVpmJt3ujVljK2zU7hkaqSZHFRZeac=; b=rK2QRzVuQ/lmx4q34Jl5AZALfF5gphtQZl97b3euRgXJWhQa6UDVZn1BSodgs+Lizm maZM+8l/ZNju4EVoYDVlhRoDbmDt24Jb68boB2xzZ+8FT59GPG+pB7PGjO0gUIfHca/p Hvk7VilSqMwDZsueq987LNjM08PvIIiAbdDvFCtjrDHq3C0+iVTFzS15PsztGmTd0hKI laUgsHb1G5agiHYB9KiMaYUjmMespm4/Q/LuM1tTrKw1OSv0z0gy1A7J204wtnca4ksV ttAXBuFyNF/LA6WnelNinws8K59o2NVCGJcurMZCu9wjU9tRafIs2Mu5SluzCH1DWvRO 7i1g== X-Gm-Message-State: AFeK/H1efrK/QAJtz7ZG8xYMdn2fArDd7/qKbjctHgxZ5go0wpqqIdly ypIp8SDK5H53hdEVXMc= X-Received: by 10.28.139.134 with SMTP id n128mr19923458wmd.132.1491426587042; Wed, 05 Apr 2017 14:09:47 -0700 (PDT) Received: from localhost.localdomain ([2a02:a03f:88d:1900:fc6c:1650:1726:93b6]) by smtp.gmail.com with ESMTPSA id v29sm27592168wrv.66.2017.04.05.14.09.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 05 Apr 2017 14:09:46 -0700 (PDT) From: Luc Van Oostenryck To: linux-sparse@vger.kernel.org Cc: Christopher Li , Luc Van Oostenryck Subject: [PATCH 9/9] add support for C11's _Atomic as type qualifier Date: Wed, 5 Apr 2017 23:09:27 +0200 Message-Id: <20170405210927.27948-10-luc.vanoostenryck@gmail.com> X-Mailer: git-send-email 2.12.0 In-Reply-To: <20170405210927.27948-1-luc.vanoostenryck@gmail.com> References: <20170405210927.27948-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 This only add the parsing and checks as a type qualifier; there is no operational semantic associated with it. Note: this only support _Atomic as *type qualifier*, not as a *type specifier* (partly because there an ambiguity on how to parse '_Atomic' when followed by an open parenthesis (can be valid as qualifier and as specifier)). Signed-off-by: Luc Van Oostenryck --- gdbhelpers | 3 ++ parse.c | 13 +++++++ show-parse.c | 1 + symbol.h | 3 +- validation/c11-atomic.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ validation/typeof-mods.c | 14 ++++++++ 6 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 validation/c11-atomic.c diff --git a/gdbhelpers b/gdbhelpers index f6399d3bc..2fe9336dd 100644 --- a/gdbhelpers +++ b/gdbhelpers @@ -110,6 +110,9 @@ define gdb_show_ctype if ($arg0->modifiers & MOD_RESTRICT) printf "MOD_RESTRICT " end + if ($arg0->modifiers & MOD_ATOMIC) + printf "MOD_ATOMIC " + end if ($arg0->modifiers & MOD_SIGNED) printf "MOD_SIGNED " end diff --git a/parse.c b/parse.c index 14fc2b9d1..beb358a2b 100644 --- a/parse.c +++ b/parse.c @@ -59,6 +59,7 @@ static declarator_t register_specifier, static_specifier, extern_specifier, thread_specifier, const_qualifier, volatile_qualifier; static declarator_t restrict_qualifier; +static declarator_t atomic_qualifier; static struct token *parse_if_statement(struct token *token, struct statement *stmt); static struct token *parse_return_statement(struct token *token, struct statement *stmt); @@ -177,6 +178,11 @@ static struct symbol_op restrict_op = { .declarator = restrict_qualifier, }; +static struct symbol_op atomic_op = { + .type = KW_QUALIFIER, + .declarator = atomic_qualifier, +}; + static struct symbol_op typeof_op = { .type = KW_SPECIFIER, .declarator = typeof_specifier, @@ -421,6 +427,7 @@ static struct init_keyword { { "restrict", NS_TYPEDEF, .op = &restrict_op}, { "__restrict", NS_TYPEDEF, .op = &restrict_op}, { "__restrict__", NS_TYPEDEF, .op = &restrict_op}, + { "_Atomic", NS_TYPEDEF, .op = &atomic_op}, /* Typedef.. */ { "typedef", NS_TYPEDEF, .op = &typedef_op }, @@ -1464,6 +1471,12 @@ static struct token *restrict_qualifier(struct token *next, struct decl_state *c return next; } +static struct token *atomic_qualifier(struct token *next, struct decl_state *ctx) +{ + apply_qualifier(&next->pos, &ctx->ctype, MOD_ATOMIC); + return next; +} + static void apply_ctype(struct position pos, struct ctype *thistype, struct ctype *ctype) { unsigned long mod = thistype->modifiers; diff --git a/show-parse.c b/show-parse.c index 825db6921..a4ce6f68d 100644 --- a/show-parse.c +++ b/show-parse.c @@ -126,6 +126,7 @@ const char *modifier_string(unsigned long mod) {MOD_CONST, "const"}, {MOD_VOLATILE, "volatile"}, {MOD_RESTRICT, "restrict"}, + {MOD_ATOMIC, "[atomic]"}, {MOD_SIGNED, "[signed]"}, {MOD_UNSIGNED, "[unsigned]"}, {MOD_CHAR, "[char]"}, diff --git a/symbol.h b/symbol.h index ca0ec00c1..58f9df79a 100644 --- a/symbol.h +++ b/symbol.h @@ -214,6 +214,7 @@ struct symbol { #define MOD_CONST 0x00000200 #define MOD_VOLATILE 0x00000400 #define MOD_RESTRICT 0x00000800 +#define MOD_ATOMIC 0x00001000 #define MOD_SIGNED 0x00002000 #define MOD_UNSIGNED 0x00004000 @@ -243,7 +244,7 @@ struct symbol { #define MOD_SIZE (MOD_CHAR | MOD_SHORT | MOD_LONG_ALL) #define MOD_IGNORE (MOD_STORAGE | MOD_ADDRESSABLE | \ MOD_ASSIGNED | MOD_USERTYPE | MOD_EXPLICITLY_SIGNED) -#define MOD_QUALIFIER (MOD_CONST | MOD_VOLATILE | MOD_RESTRICT) +#define MOD_QUALIFIER (MOD_CONST | MOD_VOLATILE | MOD_RESTRICT | MOD_ATOMIC) #define MOD_PTRINHERIT (MOD_QUALIFIER | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST) /* modifiers preserved by typeof() operator */ #define MOD_TYPEOF (MOD_QUALIFIER | MOD_NOCAST | MOD_SPECIFIER) diff --git a/validation/c11-atomic.c b/validation/c11-atomic.c new file mode 100644 index 000000000..bea3dab8f --- /dev/null +++ b/validation/c11-atomic.c @@ -0,0 +1,93 @@ +void f00(int _Atomic dst); +void f01(int _Atomic *dst); +void f02(int _Atomic *dst); +void f03(int _Atomic *dst); + +int _Atomic qo; +int uo; + +void f00(int dst) { } /* check-should-pass */ +void f01(typeof(&qo) dst) { } /* check-should-pass */ +void f02(int *dst) { } /* check-should-fail */ +void f03(typeof(&uo) dst) { } /* check-should-fail */ + +void foo(void) +{ + qo = uo; /* check-should-pass */ + uo = qo; /* check-should-pass */ +} + +void ref(void) +{ + const int qo; + int uo; + extern const int *pqo; + extern int *puo; + + pqo = &qo; /* check-should-pass */ + pqo = &uo; /* check-should-pass */ + pqo = puo; + + puo = &uo; /* check-should-pass */ + + puo = &qo; /* check-should-fail */ + puo = pqo; /* check-should-fail */ +} + +void bar(void) +{ + extern int _Atomic *pqo; + extern int *puo; + + pqo = &qo; /* check-should-pass */ + pqo = &uo; /* check-should-pass */ + pqo = puo; + + puo = &uo; /* check-should-pass */ + + puo = &qo; /* check-should-fail */ + puo = pqo; /* check-should-fail */ +} + +void baz(void) +{ + extern typeof(&qo) pqo; + extern typeof(&uo) puo; + + pqo = &qo; /* check-should-pass */ + pqo = &uo; /* check-should-pass */ + pqo = puo; + + puo = &uo; /* check-should-pass */ + + puo = &qo; /* check-should-fail */ + puo = pqo; /* check-should-fail */ +} + +/* + * check-name: C11 _Atomic type qualifier + * check-command: sparse -Wno-decl $file; + * + * check-error-start +c11-atomic.c:11:6: error: symbol 'f02' redeclared with different type (originally declared at c11-atomic.c:3) - incompatible argument 1 (different modifiers) +c11-atomic.c:12:6: error: symbol 'f03' redeclared with different type (originally declared at c11-atomic.c:4) - incompatible argument 1 (different modifiers) +c11-atomic.c:33:13: warning: incorrect type in assignment (different modifiers) +c11-atomic.c:33:13: expected int *extern [assigned] puo +c11-atomic.c:33:13: got int const * +c11-atomic.c:34:13: warning: incorrect type in assignment (different modifiers) +c11-atomic.c:34:13: expected int *extern [assigned] puo +c11-atomic.c:34:13: got int const *extern [assigned] pqo +c11-atomic.c:48:13: warning: incorrect type in assignment (different modifiers) +c11-atomic.c:48:13: expected int *extern [assigned] puo +c11-atomic.c:48:13: got int [atomic] * +c11-atomic.c:49:13: warning: incorrect type in assignment (different modifiers) +c11-atomic.c:49:13: expected int *extern [assigned] puo +c11-atomic.c:49:13: got int [atomic] *extern [assigned] pqo +c11-atomic.c:63:13: warning: incorrect type in assignment (different modifiers) +c11-atomic.c:63:13: expected int *extern [assigned] puo +c11-atomic.c:63:13: got int [atomic] * +c11-atomic.c:64:13: warning: incorrect type in assignment (different modifiers) +c11-atomic.c:64:13: expected int *extern [assigned] puo +c11-atomic.c:64:13: got int [atomic] *extern [assigned] pqo + * check-error-end + */ diff --git a/validation/typeof-mods.c b/validation/typeof-mods.c index 878a111a2..aa880f373 100644 --- a/validation/typeof-mods.c +++ b/validation/typeof-mods.c @@ -57,6 +57,20 @@ static void test_restrict(void) obj = *ptr; } +static void test_atomic(void) +{ + int _Atomic obj, *ptr; + typeof(obj) var = obj; + typeof(ptr) ptr2 = ptr; + typeof(*ptr) var2 = obj; + typeof(*ptr) *ptr3 = ptr; + typeof(obj) *ptr4 = ptr; + obj = obj; + ptr = ptr; + ptr = &obj; + obj = *ptr; +} + static void test_bitwise(void) { typedef int __bitwise type_t;