From patchwork Thu Jun 15 19:17:50 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: 9790069 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 C82B260231 for ; Thu, 15 Jun 2017 19:18:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B7F83284C3 for ; Thu, 15 Jun 2017 19:18:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AAF6028620; Thu, 15 Jun 2017 19:18:11 +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.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, 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 40B27284C3 for ; Thu, 15 Jun 2017 19:18:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750899AbdFOTSK (ORCPT ); Thu, 15 Jun 2017 15:18:10 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:32942 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750814AbdFOTSJ (ORCPT ); Thu, 15 Jun 2017 15:18:09 -0400 Received: by mail-wm0-f65.google.com with SMTP id f90so1367159wmh.0 for ; Thu, 15 Jun 2017 12:18:09 -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; bh=XIplqsgcfDS16Ga24kAwpuqcmCNB4J68d5lFptbjYbk=; b=dF3fpH4HJdUN7fsnyp9F35jJnMSDnKWgqz4UjWIfcIrYBaPLJpV+cdDEaUGlNKLjbd xDGC6MtZtC079M7qsSxlOH/MRcN3JqEdiTO2WAd/I4gouhotBOOorvG1iXnWM+sytjjN 2Fitawc0o+myBddRy9IEKak+q2sXb62Kt4peKNwRUiPBIH2Pu8NMxl8utP5IRQd7P3oo UbiXe5BiKeHrQaggWeP95eVsQFZf6XXWvF+EEOwSPLf0UoR7Onoc/V3VVlw7pvprxiNn D8u24GV/6RXdLr/TZwg9MDdidN8p5OiIr74XwUV1obO0T3SNqUOYqWxTVfDRHFemzg3F b9HA== 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; bh=XIplqsgcfDS16Ga24kAwpuqcmCNB4J68d5lFptbjYbk=; b=oa8Xf0M8lpZQxtwv48qLE9yK8UfNc3g9psCb92mjW9Av9ECLa3/m6JjHpb7WVOfb2s pSkEn5QmeAVv/APKfBFj09S5rZNmcoHxfFHzqMEk8fWez3HpfM1+8TILbw0KK8eAcut6 hjxIDh1SrzY5qJFRibgWvpcW551VPr6lm7izdZxyvaldvVILnTcSg8cG14NadQtOLBBY BZwqwYQnaRwZolyn6h4zrR4TqjGQVG8OiRVcRAXx9OZJw0dCC75QLRkIca1MlZhWPrko uaj2LauGjpSeLGpBaOb+cPcIRLSiZw3XS8X7J0cEKgD2QqDhG8ksHYkNbJVmsk9fT+0+ 6CSw== X-Gm-Message-State: AKS2vOwjOhRGCptqXs9kuLI/xa2V/ifAsUIpNUhhDroDmr2JVH7iu7AD s6WU2OKJpRBBMZd8f2k= X-Received: by 10.80.172.228 with SMTP id x91mr4707087edc.66.1497554288375; Thu, 15 Jun 2017 12:18:08 -0700 (PDT) Received: from localhost.localdomain ([2a02:a03f:89c:5400:b408:73dc:1493:32be]) by smtp.gmail.com with ESMTPSA id f48sm59418eda.42.2017.06.15.12.18.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Jun 2017 12:18:07 -0700 (PDT) From: Luc Van Oostenryck To: linux-sparse@vger.kernel.org Cc: Chris Li , Luc Van Oostenryck Subject: [PATCH] fix: add missing examine in evaluate_dereference() Date: Thu, 15 Jun 2017 21:17:50 +0200 Message-Id: <20170615191750.71888-1-luc.vanoostenryck@gmail.com> X-Mailer: git-send-email 2.13.0 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 sparse use lazy type evaluation. This evaluation is done via the examine_*() functions, which we must insure to have been called when type information is needed. However, it seems that this is not done for expressions with multiple level of dereferencing. There is (at least) two symptoms: 1) When the inner expression is complex and contains a typeof: a bogus error message is issued, either "error: internal error: bad type in derived(11)" or "error: cannot dereference this type", sometimes followed by another bogus "warning: unknown expression (...)". 2) This one is only visible with test-linearize but happen even on a plain double deref: the result of the inner deref is typeless. Obviously the first symptom is a consequence of the second one. Fix this by adding a call to examine_symbol_type() at the beginning of evaluate_dereference(). Note: This fixes all the 17 "cannot dereference" and 19 "internal error" present on the Linux kernel while using sparse on a x86-64 allyesconfig (most coming from the call of rcu_dereference_sched() in cpufreq_update_util()). Signed-off-by: Luc Van Oostenryck --- evaluate.c | 2 ++ validation/badtype5.c | 18 ++++++++++++++++++ validation/linear/missing-insn-size.c | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 validation/badtype5.c create mode 100644 validation/linear/missing-insn-size.c diff --git a/evaluate.c b/evaluate.c index e606c2786..cf3cf244d 100644 --- a/evaluate.c +++ b/evaluate.c @@ -1738,6 +1738,8 @@ static struct symbol *evaluate_dereference(struct expression *expr) return expr->ctype; } + examine_symbol_type(ctype); + /* Dereferencing a node drops all the node information. */ if (ctype->type == SYM_NODE) ctype = ctype->ctype.base_type; diff --git a/validation/badtype5.c b/validation/badtype5.c new file mode 100644 index 000000000..c3c34ab23 --- /dev/null +++ b/validation/badtype5.c @@ -0,0 +1,18 @@ +#define __force __attribute__((force)) + +int foo(int *addr); +int foo(int *addr) +{ + return *(*((typeof(addr) __force *) addr)); +} + +/* + * check-name: badtype5.c + * check-description: + * evaluate_dereference() used to miss a call to + * examine_symbol_type(). This, in the present, left + * a SYM_TYPEOF as type for the last dereferencing + * which produced "error: cannot dereference this type". + * The presence of the __force and the typeof is needed + * to create the situation. + */ diff --git a/validation/linear/missing-insn-size.c b/validation/linear/missing-insn-size.c new file mode 100644 index 000000000..fe588634c --- /dev/null +++ b/validation/linear/missing-insn-size.c @@ -0,0 +1,19 @@ +int foo(int **a); +int foo(int **a) +{ + return **a; +} + +/* + * check-name: missing instruction's size + * check-description: + * sparse used to have a problem with *all* + * double dereferencing due to missing a + * call to examine_symbol_type(). The symptom + * here is that the inner deref had no type. + * check-command: test-linearize $file + * check-output-ignore + * + * check-output-excludes: load\\s + * check-output-contains: load\\. + */