From patchwork Thu Apr 12 23:53:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 897821 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-476320-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="XEOS6VkZ"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40McxY4jw0z9s06 for ; Fri, 13 Apr 2018 09:46:24 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=u/32wqha8JGcvm+V +tXXFsbVZpS1H14JFEWE/zAVE/+b71H1Jl8nMXGAOji+cBvXykUxfYcC+3QuMn7N fHQbzldj8NB+FGbOr9NsI4EFHEgebutlOIEoAm/3TPYn0Hgf6vn3lzlLUuECerLE YUWlkHgCx94CM5LCQ+6MW1U91fU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=lv7IHxmUxKjrmmsFXavQHw n/cLI=; b=XEOS6VkZvsOhAZKrLj6SAuePFm6z0AqVt3wySH0o3hGzEnkQyXarud BqOpA6lrYDFZUcDFQfFD0reeIdz8zNX8QLk3n4EwuGN13Pv9URU+B3vYxDbvjw/E zU1kx3jfKeT7aDBLdrxYZ+HgI30G3EsalFSAewf63HWjm9MLyZ7kc= Received: (qmail 24284 invoked by alias); 12 Apr 2018 23:46:17 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 24274 invoked by uid 89); 12 Apr 2018 23:46:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.2 spammy=dgbogus, dg-bogus X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 12 Apr 2018 23:46:14 +0000 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 802A0313B4E2 for ; Thu, 12 Apr 2018 23:46:13 +0000 (UTC) Received: from c64.redhat.com (ovpn-112-12.phx2.redhat.com [10.3.112.12]) by smtp.corp.redhat.com (Postfix) with ESMTP id A299318AC3; Thu, 12 Apr 2018 23:46:12 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [committed] Prevent erroneous "macro had not yet been defined" messages (PR c++/85385) Date: Thu, 12 Apr 2018 19:53:53 -0400 Message-Id: <1523577233-54944-1-git-send-email-dmalcolm@redhat.com> MIME-Version: 1.0 X-IsSubscribed: yes PR c++/85385 reports an issue where we emit bogus "macro had not yet been defined" notes when a macro is mis-used: $ cat test.c #define MACRO(X,Y) void test () { MACRO(42); } $ ./xg++ -B. -c test.c test.c:5:11: error: macro "MACRO" requires 2 arguments, but only 1 given MACRO(42); ^ test.c: In function ‘void test()’: test.c:5:3: error: ‘MACRO’ was not declared in this scope MACRO(42); ^~~~~ test.c:5:3: note: test.c:1: note: it was later defined here #define MACRO(X,Y) The macro *had* been defined, it was merely misused. This patch fixes the issue by only issuing the note if the use location is before the definition location (using linemap_location_before_p). Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu; adds 39 PASS results to g++.sum. Committed to trunk as r259360. gcc/cp/ChangeLog: PR c++/85385 * name-lookup.c (macro_use_before_def::maybe_make): New function, checking that the use is indeed before the definition. (macro_use_before_def::macro_use_before_def): Make private. (macro_use_before_def::~macro_use_before_def): Make private. Move check for UNKNOWN_LOCATION to macro_use_before_def::maybe_make. (lookup_name_fuzzy): Call macro_use_before_def::maybe_make rather than using new directly. gcc/testsuite/ChangeLog: PR c++/85385 * g++.dg/diagnostic/macro-arg-count.C: New test. --- gcc/cp/name-lookup.c | 39 ++++++++++++----- gcc/testsuite/g++.dg/diagnostic/macro-arg-count.C | 51 +++++++++++++++++++++++ 2 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/diagnostic/macro-arg-count.C diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index b923107..d2e5acb 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -5888,6 +5888,27 @@ consider_binding_level (tree name, best_match &bm, class macro_use_before_def : public deferred_diagnostic { public: + /* Factory function. Return a new macro_use_before_def instance if + appropriate, or return NULL. */ + static macro_use_before_def * + maybe_make (location_t use_loc, cpp_hashnode *macro) + { + source_location def_loc = cpp_macro_definition_location (macro); + if (def_loc == UNKNOWN_LOCATION) + return NULL; + + /* We only want to issue a note if the macro was used *before* it was + defined. + We don't want to issue a note for cases where a macro was incorrectly + used, leaving it unexpanded (e.g. by using the wrong argument + count). */ + if (!linemap_location_before_p (line_table, use_loc, def_loc)) + return NULL; + + return new macro_use_before_def (use_loc, macro); + } + + private: /* Ctor. LOC is the location of the usage. MACRO is the macro that was used. */ macro_use_before_def (location_t loc, cpp_hashnode *macro) @@ -5901,13 +5922,10 @@ class macro_use_before_def : public deferred_diagnostic if (is_suppressed_p ()) return; - source_location def_loc = cpp_macro_definition_location (m_macro); - if (def_loc != UNKNOWN_LOCATION) - { - inform (get_location (), "the macro %qs had not yet been defined", - (const char *)m_macro->ident.str); - inform (def_loc, "it was later defined here"); - } + inform (get_location (), "the macro %qs had not yet been defined", + (const char *)m_macro->ident.str); + inform (cpp_macro_definition_location (m_macro), + "it was later defined here"); } private: @@ -5990,12 +6008,13 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc) bm.consider ((const char *)best_macro->ident.str); else if (bmm.get_best_distance () == 0) { - /* If we have an exact match for a macro name, then the - macro has been used before it was defined. */ + /* If we have an exact match for a macro name, then either the + macro was used with the wrong argument count, or the macro + has been used before it was defined. */ cpp_hashnode *macro = bmm.blithely_get_best_candidate (); if (macro && (macro->flags & NODE_BUILTIN) == 0) return name_hint (NULL, - new macro_use_before_def (loc, macro)); + macro_use_before_def::maybe_make (loc, macro)); } /* Try the "starts_decl_specifier_p" keywords to detect diff --git a/gcc/testsuite/g++.dg/diagnostic/macro-arg-count.C b/gcc/testsuite/g++.dg/diagnostic/macro-arg-count.C new file mode 100644 index 0000000..12b2dbd --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/macro-arg-count.C @@ -0,0 +1,51 @@ +// { dg-options "-fdiagnostics-show-caret" } + +#define MACRO_1(X,Y) +void test_1 () +{ + MACRO_1(42); // { dg-line "use_of_MACRO_1" } + // { dg-error "macro \"MACRO_1\" requires 2 arguments, but only 1 given" "" { target *-*-* } use_of_MACRO_1 } + /* { dg-begin-multiline-output "" } + MACRO_1(42); + ^ + { dg-end-multiline-output "" } */ + // { dg-error "'MACRO_1' was not declared in this scope" "" { target *-*-* } use_of_MACRO_1 } + /* { dg-begin-multiline-output "" } + MACRO_1(42); + ^~~~~~~ + { dg-end-multiline-output "" } */ + // { dg-bogus "had not yet been defined" "" { target *-*-* } use_of_MACRO_1 } +} + +#define MACRO_2(X,Y) +void test_2 () +{ + MACRO_2(1, 2, 3); // { dg-line "use_of_MACRO_2" } + // { dg-error "macro \"MACRO_2\" passed 3 arguments, but takes just 2" "" { target *-*-* } use_of_MACRO_2 } + /* { dg-begin-multiline-output "" } + MACRO_2(1, 2, 3); + ^ + { dg-end-multiline-output "" } */ + // { dg-error "'MACRO_2' was not declared in this scope" "" { target *-*-* } use_of_MACRO_2 } + /* { dg-begin-multiline-output "" } + MACRO_2(1, 2, 3); + ^~~~~~~ + { dg-end-multiline-output "" } */ + // { dg-bogus "had not yet been defined" "" { target *-*-* } use_of_MACRO_2 } +} + +#define MACRO_3 +void test_3 () +{ + MACRO_3 (42); +} + +#define MACRO_4(X,Y) +void test_4 () +{ + MACRO_4; // { dg-error "'MACRO_4' was not declared in this scope" } + /* { dg-begin-multiline-output "" } + MACRO_4; + ^~~~~~~ + { dg-end-multiline-output "" } */ +}