From patchwork Tue Oct 29 15:31:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 2003803 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Vn9Ut1kc; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XdDkc6lsDz1xxC for ; Wed, 30 Oct 2024 02:31:36 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B7A3D3858404 for ; Tue, 29 Oct 2024 15:31:34 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 6FFD03858C42 for ; Tue, 29 Oct 2024 15:31:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6FFD03858C42 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6FFD03858C42 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730215874; cv=none; b=cjw8gm3fvEv3baJQeT8Xoo2HTH8fYTpgcGmi3zkHRSVcVHNwvj4WH5YsS8gmJ4vEAnm80PSDdUiVsNfjEhcedh9snxJg02yKRRuHwBVdc5mh6JZG9H3G5vstoUy+6S+wKlVn6qoeM2zY5Qr7AQGCcPqqw9P6iI8y8k2+MPhnpdc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730215874; c=relaxed/simple; bh=OpQePXL2kDTVYWaP7iZTOvMqNONx4TqkskowCMxCwvQ=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=J23a3b3a1/bm/S4dVJFQvlK8Cp5bVIEIvI7xvsz02bSrtcd3Uh//w/1+tBZOhbN2PLrEoTye9+idIgYqwW+bckCgBf4JdzmsCauBRQx35oDXgPV6t4XVVN7Go6wuiSCFlx0noZvuSNVMSLMa1h31bojpVHiFeul7/3n3fgqmaFQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730215870; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YmC+Z6BlbTPHrznFYk6GXokULOHmIKqutLhOO9zbaRk=; b=Vn9Ut1kcdAJcSjKYphucoWzdKDu3jhHpFvhLNlTSpNLvB1io4RkRmNIypaaWwRAJgtNuBP IDU7UH1HtOeP1CJuI5381Hy24kWjzwMUjCY1hieggKgZUeRpT1HuKQe6LtvL3moWv1Gdsg Vh9zeSod+DwsGlVWAV5eeNr8NOQ9ddo= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-167-3DPKH2sxNBy23rprPZ_eQQ-1; Tue, 29 Oct 2024 11:31:07 -0400 X-MC-Unique: 3DPKH2sxNBy23rprPZ_eQQ-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CAF791955F68; Tue, 29 Oct 2024 15:31:05 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.224.16]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 27EBA19560A2; Tue, 29 Oct 2024 15:31:03 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 49TFV1gY3101711 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 29 Oct 2024 16:31:01 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 49TFV0qK3101710; Tue, 29 Oct 2024 16:31:00 +0100 Date: Tue, 29 Oct 2024 16:31:00 +0100 From: Jakub Jelinek To: Jason Merrill Cc: Patrick Palka , Nathaniel Shead , gcc-patches@gcc.gnu.org Subject: [PATCH] c++, v2: Attempt to implement C++26 P3034R1 - Module Declarations Shouldn't be Macros [PR114461] Message-ID: References: <86c05152-bd31-4da7-be35-429ca56bd3dc@redhat.com> MIME-Version: 1.0 In-Reply-To: <86c05152-bd31-4da7-be35-429ca56bd3dc@redhat.com> X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-0.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SOMETLD_ARE_BAD_TLD, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org On Fri, Oct 25, 2024 at 12:52:41PM -0400, Jason Merrill wrote: > This does seem like a hole in the wording. I think the clear intent is that > the name/partition must neither be macro-expanded nor come from macro > expansion. I'll defer filing the DR and figuring out the right wording for the standard to you/WG21. > > The patch below implements what is above described as the first variant > > of the first issue resolution, i.e. disables expansion of as many tokens > > as could be in the valid module name and module partition syntax, but > > as soon as it e.g. sees two adjacent identifiers, the second one can be > > macro expanded. So, effectively: > > #define SEMI ; > > export module SEMI > > used to be valid and isn't anymore, > > #define FOO bar > > export module FOO; > > isn't valid, > > #define COLON : > > export module COLON private; > > isn't valid, > > #define BAR baz > > export module foo.bar:baz.qux.BAR; > > isn't valid, > > Agreed. Ok. > > but > > #define BAZ .qux > > export module foo BAZ; > > or > > #define QUX [[]] > > export module foo QUX; > > or > > #define FREDDY :garply > > export module foo FREDDY; > > or > > #define GARPLY private > > module : GARPLY; > > etc. is. > > I think QUX is valid, but the others are intended to be invalid. I've changed the patch so that the BAZ and FREDDY cases above are also diagnosed as invalid, so cases where a module name or module partition name is followed by an identifier defined as object-like or function-like macro and where after macro expansion the first non-padding/comment token is dot or colon (so, either an object-like or function-like macro whose expansion starts with . or : or one which expands to nothing and . or : following that macro either directly or from some other macro expansion. E.g. one could have #define A [[vendor::attr(1 ? 2 #define B 3)]] export module foo.bar A : B; which I think ought to be valid and expanded as export module foo.bar [[vendor::attr(1 ? 2 : 3)]]; or #define A #define B baz export module foo.bar A : B; which would preprocess into export module foo.bar:baz; and I think that is against the intent of the paper where the quick scanners couldn't figure this out without actually performing preprocessing. Unfortunately, trying to enter macro context inside of cpp_maybe_module_directive doesn't seem to work well, so I've instead added a flag and let cpp_get_token_1 to diagnose it later (but still during preprocessing, because if going e.g. with -save-temps the distinction would be lost, so it feels undesirable to diagnose that during parsing, plus whether some token comes from a macro or not is currently only testable in the FE when not -fno-track-macro-expansion and see above testcase that the : or . actually might not come from a macro, yet there could be a macro expanding to nothing in between. I've kept the GARPLY case above as valid, I don't see the paper changing anything in that regard (sure, the : has to not come from macro so that the scanners can figure it out) and I think it isn't needed. > > --- gcc/testsuite/g++.dg/modules/dir-only-4.C.jj 2020-12-22 23:50:17.057972516 +0100 > > +++ gcc/testsuite/g++.dg/modules/dir-only-4.C 2024-08-08 09:33:09.454522024 +0200 > > @@ -1,8 +1,8 @@ > > // { dg-additional-options {-fmodules-ts -fpreprocessed -fdirectives-only} } > > -// { dg-module-cmi !foo } > > +// { dg-module-cmi !baz } > > module; > > #define foo baz > > -export module foo; > > +export module baz; > > class import {}; > > --- gcc/testsuite/g++.dg/modules/atom-preamble-2_a.C.jj 2020-12-22 23:50:17.055972539 +0100 > > +++ gcc/testsuite/g++.dg/modules/atom-preamble-2_a.C 2024-08-08 09:35:56.093364042 +0200 > > @@ -1,6 +1,6 @@ > > // { dg-additional-options "-fmodules-ts" } > > #define malcolm kevin > > -export module malcolm; > > +export module kevin; > > // { dg-module-cmi kevin } > > export class X; > > --- gcc/testsuite/g++.dg/modules/atom-preamble-4.C.jj 2020-12-22 23:50:17.055972539 +0100 > > +++ gcc/testsuite/g++.dg/modules/atom-preamble-4.C 2024-08-08 09:35:32.463670046 +0200 > > @@ -1,5 +1,5 @@ > > // { dg-additional-options "-fmodules-ts" } > > -#define NAME(X) X; > > +#define NAME(X) ; > > -export module NAME(bob) > > +export module bob NAME(bob) > > It looks like these tests were specifically testing patterns that this paper > makes ill-formed, and so we should check for errors instead of changing them > to be well-formed. Ok, changed dir-only-4.C and atom-preamble-4.C back to previous content + dg-error and added new tests with the changes in and not expecting error. I had to keep the atom-preamble-2_a.C change as is, because otherwise all of atom-preamble-2*.C tests FAIL. Here is a so far lightly tested patch, ok for trunk if it passes full bootstrap/regtest or do you want some further changes? 2024-10-29 Jakub Jelinek PR c++/114461 libcpp/ * include/cpplib.h: Implement C++26 P3034R1 - Module Declarations Shouldn’t be Macros (or more precisely its expected intent). (NO_DOT_COLON): Define. * internal.h (struct cpp_reader): Add diagnose_dot_colon_from_macro_p member. * lex.cc (cpp_maybe_module_directive): For pp-module, if module keyword is followed by CPP_NAME, ensure all CPP_NAME tokens possibly matching module name and module partition syntax aren't expanded and aren't defined as object-like macros. Verify first token after that doesn't start with open paren. If the next token after module name/partition is CPP_NAME defined as macro, set NO_DOT_COLON flag on it. * macro.cc (cpp_get_token_1): Set pfile->diagnose_dot_colon_from_macro_p if token to be expanded has NO_DOT_COLON bit set in flags. Before returning, if pfile->diagnose_dot_colon_from_macro_p is true and not returning CPP_PADDING or CPP_COMMENT and not during macro expansion preparation, set pfile->diagnose_dot_colon_from_macro_p to false and diagnose if returning CPP_DOT or CPP_COLON. gcc/testsuite/ * g++.dg/modules/cpp-7.C: New test. * g++.dg/modules/cpp-8.C: New test. * g++.dg/modules/cpp-9.C: New test. * g++.dg/modules/cpp-10.C: New test. * g++.dg/modules/cpp-11.C: New test. * g++.dg/modules/cpp-12.C: New test. * g++.dg/modules/cpp-13.C: New test. * g++.dg/modules/cpp-14.C: New test. * g++.dg/modules/cpp-15.C: New test. * g++.dg/modules/cpp-16.C: New test. * g++.dg/modules/cpp-17.C: New test. * g++.dg/modules/cpp-18.C: New test. * g++.dg/modules/cpp-19.C: New test. * g++.dg/modules/cpp-20.C: New test. * g++.dg/modules/pmp-4.C: New test. * g++.dg/modules/pmp-5.C: New test. * g++.dg/modules/pmp-6.C: New test. * g++.dg/modules/token-6.C: New test. * g++.dg/modules/token-7.C: New test. * g++.dg/modules/token-8.C: New test. * g++.dg/modules/token-9.C: New test. * g++.dg/modules/token-10.C: New test. * g++.dg/modules/token-11.C: New test. * g++.dg/modules/token-12.C: New test. * g++.dg/modules/token-13.C: New test. * g++.dg/modules/token-14.C: New test. * g++.dg/modules/token-15.C: New test. * g++.dg/modules/token-16.C: New test. * g++.dg/modules/dir-only-3.C: Expect an error. * g++.dg/modules/dir-only-4.C: Expect an error. * g++.dg/modules/dir-only-5.C: New test. * g++.dg/modules/atom-preamble-2_a.C: In export module malcolm; replace malcolm with kevin. * g++.dg/modules/atom-preamble-4.C: Expect an error. * g++.dg/modules/atom-preamble-5.C: New test. Jakub --- libcpp/include/cpplib.h.jj 2024-10-25 10:03:16.785374003 +0200 +++ libcpp/include/cpplib.h 2024-10-29 14:27:03.530521515 +0100 @@ -204,6 +204,9 @@ struct GTY(()) cpp_string { #define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend, set in c-lex.cc. */ #define COLON_SCOPE PURE_ZERO /* Adjacent colons in C < 23. */ +#define NO_DOT_COLON PURE_ZERO /* Set on CPP_NAME tokens whose expansion + shouldn't start with CPP_DOT or CPP_COLON + after optional CPP_PADDING. */ #define SP_DIGRAPH (1 << 8) /* # or ## token was a digraph. */ #define SP_PREV_WHITE (1 << 9) /* If whitespace before a ## operator, or before this token --- libcpp/internal.h.jj 2024-10-25 10:03:16.786373988 +0200 +++ libcpp/internal.h 2024-10-29 14:34:42.125244956 +0100 @@ -468,6 +468,10 @@ struct cpp_reader one. */ bool about_to_expand_macro_p; + /* True if the preprocessor should diagnose CPP_DOT or CPP_COLON + tokens as the first ones coming from macro expansion. */ + bool diagnose_dot_colon_from_macro_p; + /* Search paths for include files. */ struct cpp_dir *quote_include; /* "" */ struct cpp_dir *bracket_include; /* <> */ --- libcpp/lex.cc.jj 2024-10-25 10:03:16.786373988 +0200 +++ libcpp/lex.cc 2024-10-29 15:11:08.023890616 +0100 @@ -3604,6 +3604,78 @@ cpp_maybe_module_directive (cpp_reader * /* Maybe tell the tokenizer we expect a header-name down the road. */ pfile->state.directive_file_token = header_count; + + /* According to P3034R1, pp-module-name and pp-module-partition tokens + if any shouldn't be macro expanded and identifiers shouldn't be + defined as object-like macro. */ + if (!header_count && peek->type == CPP_NAME) + { + int state = 0; + do + { + cpp_token *tok = peek; + if (tok->type == CPP_NAME) + { + cpp_hashnode *node = tok->val.node.node; + /* Don't attempt to expand the token. */ + tok->flags |= NO_EXPAND; + if (_cpp_defined_macro_p (node) + && _cpp_maybe_notify_macro_use (pfile, node, + tok->src_loc) + && !cpp_fun_like_macro_p (node)) + { + if (state == 0) + cpp_error_with_line (pfile, CPP_DL_ERROR, + tok->src_loc, 0, + "module name %qs cannot " + "be an object-like macro", + NODE_NAME (node)); + else + cpp_error_with_line (pfile, CPP_DL_ERROR, + tok->src_loc, 0, + "module partition %qs cannot " + "be an object-like macro", + NODE_NAME (node)); + } + } + peek = _cpp_lex_direct (pfile); + backup++; + if (tok->type == CPP_NAME) + { + if (peek->type == CPP_DOT) + continue; + else if (peek->type == CPP_COLON && state == 0) + { + ++state; + continue; + } + else if (peek->type == CPP_OPEN_PAREN) + { + if (state == 0) + cpp_error_with_line (pfile, CPP_DL_ERROR, + peek->src_loc, 0, + "module name followed by %<(%>"); + else + cpp_error_with_line (pfile, CPP_DL_ERROR, + peek->src_loc, 0, + "module partition followed by " + "%<(%>"); + break; + } + else if (peek->type == CPP_NAME + && _cpp_defined_macro_p (peek->val.node.node)) + { + peek->flags |= NO_DOT_COLON; + break; + } + else + break; + } + else if (peek->type != CPP_NAME) + break; + } + while (true); + } } else { --- libcpp/macro.cc.jj 2024-10-25 10:03:16.788373960 +0200 +++ libcpp/macro.cc 2024-10-29 16:03:10.225312607 +0100 @@ -3076,6 +3076,9 @@ cpp_get_token_1 (cpp_reader *pfile, loca if (pfile->state.prevent_expansion) break; + if ((result->flags & NO_DOT_COLON) != 0) + pfile->diagnose_dot_colon_from_macro_p = true; + /* Conditional macros require that a predicate be evaluated first. */ if ((node->flags & NODE_CONDITIONAL) != 0) @@ -3226,6 +3229,20 @@ cpp_get_token_1 (cpp_reader *pfile, loca } } + if (pfile->diagnose_dot_colon_from_macro_p + && !pfile->about_to_expand_macro_p + && result->type != CPP_PADDING + && result->type != CPP_COMMENT) + { + if (result->type == CPP_DOT || result->type == CPP_COLON) + cpp_error_with_line (pfile, CPP_DL_ERROR, + result->src_loc, 0, + "%qc in module name or partition " + "comes from or after macro expansion", + result->type == CPP_DOT ? '.' : ':'); + pfile->diagnose_dot_colon_from_macro_p = false; + } + return result; } --- gcc/testsuite/g++.dg/modules/cpp-7.C.jj 2024-10-29 13:53:15.228616120 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-7.C 2024-10-29 14:45:11.319542826 +0100 @@ -0,0 +1,8 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define NAME(X) X; + +export module NAME(bob) // { dg-error "module name followed by '\\\('" } + +int i; --- gcc/testsuite/g++.dg/modules/cpp-8.C.jj 2024-10-29 13:53:15.250615813 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-8.C 2024-10-29 14:44:02.278497703 +0100 @@ -0,0 +1,7 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define bob fred; +export module bob; // { dg-error "module name 'bob' cannot be an object-like macro" } + +int i; --- gcc/testsuite/g++.dg/modules/cpp-9.C.jj 2024-10-29 13:53:15.250615813 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-9.C 2024-10-29 14:45:53.512959265 +0100 @@ -0,0 +1,7 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define bob fred; +export module foo.bob; // { dg-error "module name 'bob' cannot be an object-like macro" } + +int i; --- gcc/testsuite/g++.dg/modules/cpp-10.C.jj 2024-10-29 13:53:15.250615813 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-10.C 2024-10-29 14:45:45.528069701 +0100 @@ -0,0 +1,7 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define bob fred; +export module foo:bob; // { dg-error "module partition 'bob' cannot be an object-like macro" } + +int i; --- gcc/testsuite/g++.dg/modules/cpp-11.C.jj 2024-10-29 13:53:15.250615813 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-11.C 2024-10-29 14:45:20.844411089 +0100 @@ -0,0 +1,7 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define bob fred; +export module foo:bar.bob; // { dg-error "module partition 'bob' cannot be an object-like macro" } + +int i; --- gcc/testsuite/g++.dg/modules/cpp-12.C.jj 2024-10-29 15:37:32.043702670 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-12.C 2024-10-29 15:50:59.545468046 +0100 @@ -0,0 +1,7 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define baz .qux // { dg-error "'\\\.' in module name or partition comes from or after macro expansion" } +export module foo:bar baz; + +int i; --- gcc/testsuite/g++.dg/modules/cpp-13.C.jj 2024-10-29 15:38:21.892008287 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-13.C 2024-10-29 15:51:08.306346264 +0100 @@ -0,0 +1,7 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define baz :qux.garply // { dg-error "':' in module name or partition comes from or after macro expansion" } +export module foo.bar baz; + +int i; --- gcc/testsuite/g++.dg/modules/cpp-14.C.jj 2024-10-29 15:40:29.607229223 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-14.C 2024-10-29 15:40:43.249039193 +0100 @@ -0,0 +1,7 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define baz [[]] +export module foo.bar baz; + +int i; --- gcc/testsuite/g++.dg/modules/cpp-15.C.jj 2024-10-29 15:40:50.729934981 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-15.C 2024-10-29 15:47:52.610066467 +0100 @@ -0,0 +1,8 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define baz +#define qux +export module foo.bar baz . garply qux; // { dg-error "'\\\.' in module name or partition comes from or after macro expansion" } + +int i; --- gcc/testsuite/g++.dg/modules/cpp-16.C.jj 2024-10-29 15:41:44.169190577 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-16.C 2024-10-29 15:48:21.870659744 +0100 @@ -0,0 +1,8 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define baz +#define qux +export module foo.bar baz : garply qux; // { dg-error "':' in module name or partition comes from or after macro expansion" } + +int i; --- gcc/testsuite/g++.dg/modules/cpp-17.C.jj 2024-10-29 15:48:49.977269054 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-17.C 2024-10-29 15:49:21.493830972 +0100 @@ -0,0 +1,7 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define baz(x) x qux +export module foo:bar baz(.); // { dg-error "'\\\.' in module name or partition comes from or after macro expansion" } + +int i; --- gcc/testsuite/g++.dg/modules/cpp-18.C.jj 2024-10-29 15:48:52.688231371 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-18.C 2024-10-29 15:49:33.722660988 +0100 @@ -0,0 +1,7 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define baz(x) x qux.garply +export module foo.bar baz(:); // { dg-error "':' in module name or partition comes from or after macro expansion" } + +int i; --- gcc/testsuite/g++.dg/modules/cpp-19.C.jj 2024-10-29 15:48:55.852187394 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-19.C 2024-10-29 15:49:50.529427372 +0100 @@ -0,0 +1,8 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define baz(x) +#define qux(x) +export module foo.bar baz(.) . garply qux(:); // { dg-error "'\\\.' in module name or partition comes from or after macro expansion" } + +int i; --- gcc/testsuite/g++.dg/modules/cpp-20.C.jj 2024-10-29 15:48:58.555149822 +0100 +++ gcc/testsuite/g++.dg/modules/cpp-20.C 2024-10-29 15:50:04.487233357 +0100 @@ -0,0 +1,8 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +#define baz(x) +#define qux(x) +export module foo.bar baz(:) : garply qux(.); // { dg-error "':' in module name or partition comes from or after macro expansion" } + +int i; --- gcc/testsuite/g++.dg/modules/pmp-4.C.jj 2024-10-29 13:53:15.251615799 +0100 +++ gcc/testsuite/g++.dg/modules/pmp-4.C 2024-10-29 13:53:15.251615799 +0100 @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +export module bob; +// { dg-module-cmi bob } + +#define PRIVATE private + +module :PRIVATE; // { dg-message "sorry, unimplemented: private module fragment" } +int i; --- gcc/testsuite/g++.dg/modules/pmp-5.C.jj 2024-10-29 13:53:15.251615799 +0100 +++ gcc/testsuite/g++.dg/modules/pmp-5.C 2024-10-29 13:53:15.251615799 +0100 @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +export module bob; +// { dg-module-cmi bob } + +#define PRIVATE_SEMI private ; + +module :PRIVATE_SEMI // { dg-message "sorry, unimplemented: private module fragment" } +int i; --- gcc/testsuite/g++.dg/modules/pmp-6.C.jj 2024-10-29 13:53:15.251615799 +0100 +++ gcc/testsuite/g++.dg/modules/pmp-6.C 2024-10-29 13:53:15.251615799 +0100 @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +export module bob; +// { dg-module-cmi bob } + +#define SEMI ; + +module :private SEMI // { dg-message "sorry, unimplemented: private module fragment" } +int i; --- gcc/testsuite/g++.dg/modules/token-6.C.jj 2024-10-29 13:53:15.251615799 +0100 +++ gcc/testsuite/g++.dg/modules/token-6.C 2024-10-29 14:44:23.202208319 +0100 @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts" } + +#define bob fred +export module bob; +// { dg-error "module name 'bob' cannot be an object-like macro" "" { target *-*-* } .-1 } + +// { dg-module-cmi !bob } +// { dg-module-cmi !fred } +// { dg-prune-output "not writing module" } --- gcc/testsuite/g++.dg/modules/token-7.C.jj 2024-10-29 13:53:15.251615799 +0100 +++ gcc/testsuite/g++.dg/modules/token-7.C 2024-10-29 14:45:00.891687054 +0100 @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts" } + +#define bob fred +export module foo.bar.bob; +// { dg-error "module name 'bob' cannot be an object-like macro" "" { target *-*-* } .-1 } + +// { dg-module-cmi !foo.bar.bob } +// { dg-module-cmi !foo.bar.fred } +// { dg-prune-output "not writing module" } --- gcc/testsuite/g++.dg/modules/token-8.C.jj 2024-10-29 13:53:15.252615786 +0100 +++ gcc/testsuite/g++.dg/modules/token-8.C 2024-10-29 14:45:31.273266856 +0100 @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts" } + +#define bob fred +export module foo.bar:bob; +// { dg-error "module partition 'bob' cannot be an object-like macro" "" { target *-*-* } .-1 } + +// { dg-module-cmi !foo.bar:bob } +// { dg-module-cmi !foo.bar:fred } +// { dg-prune-output "not writing module" } --- gcc/testsuite/g++.dg/modules/token-9.C.jj 2024-10-29 13:53:15.252615786 +0100 +++ gcc/testsuite/g++.dg/modules/token-9.C 2024-10-29 14:44:11.577369096 +0100 @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts" } + +#define garply fred +export module foo.bar:baz.garply; +// { dg-error "module partition 'garply' cannot be an object-like macro" "" { target *-*-* } .-1 } + +// { dg-module-cmi !foo.bar:baz.garply } +// { dg-module-cmi !foo.bar:baz.fred } +// { dg-prune-output "not writing module" } --- gcc/testsuite/g++.dg/modules/token-10.C.jj 2024-10-29 13:53:15.252615786 +0100 +++ gcc/testsuite/g++.dg/modules/token-10.C 2024-10-29 13:53:15.252615786 +0100 @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +#define semi ; +export module foo.bar:baz.bob semi + +// { dg-module-cmi foo.bar:baz.bob } --- gcc/testsuite/g++.dg/modules/token-11.C.jj 2024-10-29 13:53:15.252615786 +0100 +++ gcc/testsuite/g++.dg/modules/token-11.C 2024-10-29 13:53:15.252615786 +0100 @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +#define attr [[]] +export module foo.bar:baz.bob attr ; + +// { dg-module-cmi foo.bar:baz.bob } --- gcc/testsuite/g++.dg/modules/token-12.C.jj 2024-10-29 13:53:15.252615786 +0100 +++ gcc/testsuite/g++.dg/modules/token-12.C 2024-10-29 13:53:15.252615786 +0100 @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +#define bob() fred +export module bob; + +// { dg-module-cmi bob } --- gcc/testsuite/g++.dg/modules/token-13.C.jj 2024-10-29 13:53:15.253615772 +0100 +++ gcc/testsuite/g++.dg/modules/token-13.C 2024-10-29 13:53:15.253615772 +0100 @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +#define bob() fred +export module foo.bar.bob; + +// { dg-module-cmi foo.bar.bob } --- gcc/testsuite/g++.dg/modules/token-14.C.jj 2024-10-29 13:53:15.253615772 +0100 +++ gcc/testsuite/g++.dg/modules/token-14.C 2024-10-29 13:53:15.253615772 +0100 @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +#define bob(n) fred +export module foo.bar:bob; + +// { dg-module-cmi foo.bar:bob } --- gcc/testsuite/g++.dg/modules/token-15.C.jj 2024-10-29 13:53:15.253615772 +0100 +++ gcc/testsuite/g++.dg/modules/token-15.C 2024-10-29 13:53:15.253615772 +0100 @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +#define bob() fred +export module foo.bar:baz.bob; + +// { dg-module-cmi foo.bar:baz.bob } --- gcc/testsuite/g++.dg/modules/token-16.C.jj 2024-10-29 13:53:15.253615772 +0100 +++ gcc/testsuite/g++.dg/modules/token-16.C 2024-10-29 14:44:38.975990154 +0100 @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts" } + +#define bob() fred +export module foo.bar:baz.bob (); +// { dg-error "module partition followed by '\\\('" "" { target *-*-* } .-1 } +// { dg-error "expected" "" { target *-*-* } .-2 } + +// { dg-module-cmi !foo.bar:baz.bob } +// { dg-module-cmi !foo.bar:baz.fred } --- gcc/testsuite/g++.dg/modules/dir-only-3.C.jj 2020-12-23 14:09:58.847107398 +0100 +++ gcc/testsuite/g++.dg/modules/dir-only-3.C 2024-10-29 14:44:48.230862156 +0100 @@ -7,10 +7,12 @@ # 32 "" 2 # 1 "dir-only-3.C" // { dg-additional-options {-fmodules-ts -fpreprocessed -fdirectives-only} } -// { dg-module-cmi foo } +// { dg-module-cmi !foo } module; #define foo baz export module foo; +// { dg-error "module name 'foo' cannot be an object-like macro" "" { target *-*-* } 5 } +// { dg-prune-output "not writing module" } class import {}; --- gcc/testsuite/g++.dg/modules/dir-only-4.C.jj 2024-08-30 09:09:46.603609137 +0200 +++ gcc/testsuite/g++.dg/modules/dir-only-4.C 2024-10-29 15:33:01.032477847 +0100 @@ -2,7 +2,7 @@ // { dg-module-cmi !foo } module; #define foo baz -export module foo; +export module foo; // { dg-error "module name 'foo' cannot be an object-like macro" } class import {}; --- gcc/testsuite/g++.dg/modules/dir-only-5.C.jj 2024-10-29 15:18:50.438386316 +0100 +++ gcc/testsuite/g++.dg/modules/dir-only-5.C 2024-10-29 13:53:15.282615367 +0100 @@ -0,0 +1,9 @@ +// { dg-additional-options {-fmodules-ts -fpreprocessed -fdirectives-only} } +// { dg-module-cmi !baz } +module; +#define foo baz +export module baz; + +class import {}; + +import x; // { dg-error "post-module-declaration" } --- gcc/testsuite/g++.dg/modules/atom-preamble-2_a.C.jj 2020-12-23 14:09:58.845107420 +0100 +++ gcc/testsuite/g++.dg/modules/atom-preamble-2_a.C 2024-10-29 13:53:15.298615144 +0100 @@ -1,6 +1,6 @@ // { dg-additional-options "-fmodules-ts" } #define malcolm kevin -export module malcolm; +export module kevin; // { dg-module-cmi kevin } export class X; --- gcc/testsuite/g++.dg/modules/atom-preamble-4.C.jj 2020-12-23 14:09:58.845107420 +0100 +++ gcc/testsuite/g++.dg/modules/atom-preamble-4.C 2024-10-29 15:31:55.292393604 +0100 @@ -3,3 +3,5 @@ export module NAME(bob) +// { dg-error "module name followed by '\\\('" "" { target *-*-* } .-2 } +// { dg-error "expected ';' before '\\\(' token" "" { target *-*-* } .-3 } --- gcc/testsuite/g++.dg/modules/atom-preamble-5.C.jj 2024-10-29 15:17:29.641522799 +0100 +++ gcc/testsuite/g++.dg/modules/atom-preamble-5.C 2024-10-29 13:53:15.299615130 +0100 @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +#define NAME(X) ; + +export module bob NAME(bob) +