From patchwork Tue Dec 22 20:41:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1420743 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Q0KZ/6V9; dkim-atps=neutral Received: from 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 RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D3k5s0kFcz9sVq for ; Mon, 28 Dec 2020 01:46:39 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id ABB7C386101E; Sun, 27 Dec 2020 14:46:33 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qt1-x833.google.com (mail-qt1-x833.google.com [IPv6:2607:f8b0:4864:20::833]) by sourceware.org (Postfix) with ESMTPS id 20EB53858031 for ; Tue, 22 Dec 2020 20:41:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 20EB53858031 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qt1-x833.google.com with SMTP id u21so9859749qtw.11 for ; Tue, 22 Dec 2020 12:41:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=N4wIJ1YYkZUf3UZaJbsakv8DMz8lFyNnZ7kNv6wBqjo=; b=Q0KZ/6V9OULS+mA5Gu0fBr2DtSQu6jt/ePdByO8whZ1/EFWoK/9KjdY0MfH4PUqOVU 5MZWr5AqRJhMP1dGf0AWLbmabG8SADJXbs4MaNlkcPSgtNN4U/94Daw9Lum40HcHqUV4 G7N42UL1Z7WoE120lXyDiiVxYPKSIWGD0PwizAAbsiIT+46zsam449GjHQSbxCNgNXHz lODN6GLAapofCU8GJU6oPePjzoFDePXPccfs0hvdSYsZxC9aU6b2IEaMMXCgBPdYCFHL m9oB0tCq3s9yAotCzfogaZZiZug4L2iXfDxXQcYSLHRD5wmZg5+Di/16grxO/9a6Es/f dqtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=N4wIJ1YYkZUf3UZaJbsakv8DMz8lFyNnZ7kNv6wBqjo=; b=gBCH8eGCjk+NhZ0y9h16dZB4kP3xIuYsvFRtmgUi1V8QmBIrdTiuijMBwRe0nzuvw2 xXrMRKyu/feSH48QJhTvjZ5VYVs/MQeOeD10iOvvOOUziJArgSQNpRVu004B+xjmtPWH 6SK87AwPjFAmNh0h6MyDkI02BpdohT1+gNz4lzpAm/GdPNMqUv0oYqK6R6rbwKvP64Ms CEt5YvAZTVfw9Oe2RDtdYfY5OIvPJwDjXM37OQ/QYwiRxKszA4l78/bF3iInNl1bXD5q KSJkJ9UbZfF55e7NAXpMMUrtRvuy9ns7O6FtupfPa3KZ92BEBWsKeK2k1kpIbqYGLlpZ 2rkQ== X-Gm-Message-State: AOAM530ZMcVgZsGC/KrrWDQFKrQHOpqfaCMMZqWjUR1VUddWObNIEf1i guhMH8OTlk7jJjOhS0Og6dc= X-Google-Smtp-Source: ABdhPJxaGXTWnjw8b3jIFhvUDPFhQhwq6ycyuF+FAOmZgjmUV+TkXqaUoQ5y22G3XW1PMDbJDVRQwg== X-Received: by 2002:a05:622a:303:: with SMTP id q3mr22806870qtw.24.1608669716539; Tue, 22 Dec 2020 12:41:56 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:3c47:94ca:3ae4:1cf? ([2620:10d:c091:480::1:f789]) by smtp.googlemail.com with ESMTPSA id n195sm6367243qke.20.2020.12.22.12.41.54 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 22 Dec 2020 12:41:55 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: c++: Module ICE fix Message-ID: <4f013332-789f-8d28-be96-8bfe8577abcf@acm.org> Date: Tue, 22 Dec 2020 15:41:53 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPAM_BODY, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-Mailman-Approved-At: Sun, 27 Dec 2020 14:46:32 +0000 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" A missing check for decl lang specific has made itself apparent. gcc/cp/ * module.cc (has_definition): Check DECL_LANG_SPECIFIC. (test in the next uber-patch) diff --git c/gcc/testsuite/g++.dg/modules/access-1_a.C w/gcc/testsuite/g++.dg/modules/access-1_a.C new file mode 100644 index 00000000000..241701728a2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/access-1_a.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } + +export module Foo; +// { dg-module-cmi Foo } + +export class Base +{ +public: + int m; +}; diff --git c/gcc/testsuite/g++.dg/modules/access-1_b.C w/gcc/testsuite/g++.dg/modules/access-1_b.C new file mode 100644 index 00000000000..454dea5332f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/access-1_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodules-ts } + +export module Bar; +// { dg-module-cmi Bar } + +import Foo; + +export class Derived : public Base +{ +private: + using Base::m; +}; diff --git c/gcc/testsuite/g++.dg/modules/access-1_c.C w/gcc/testsuite/g++.dg/modules/access-1_c.C new file mode 100644 index 00000000000..27b84c2ce1c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/access-1_c.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } + +import Bar; +import Foo; + +void foo (Derived *d) +{ + d->m = 1; // { dg-error "inaccessible within this context" } + static_cast (d)->m = 1; //ok +} diff --git c/gcc/testsuite/g++.dg/modules/adhoc-1_a.C w/gcc/testsuite/g++.dg/modules/adhoc-1_a.C new file mode 100644 index 00000000000..50067acbf13 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adhoc-1_a.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } +// { dg-module-cmi bob } + +export module bob; +export int massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea (int); + export void massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea (float); diff --git c/gcc/testsuite/g++.dg/modules/adhoc-1_b.C w/gcc/testsuite/g++.dg/modules/adhoc-1_b.C new file mode 100644 index 00000000000..59907a01d20 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adhoc-1_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts -fdiagnostics-show-caret" } + +import bob; +void foo () +{ + massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea (); +} + +// { dg-regexp "\n\[^\n]*adhoc-1_b.C:6:74: error: no matching function for call to 'massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea\\(\\)'\n massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(\\);\n \\^$" } +// { dg-regexp "\nIn module bob, imported at \[^\n]*adhoc-1_b.C:3:\n\[^\n]*adhoc-1_a.C:5:12: note: candidate: 'int massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea@bob\\(int\\)'\n export int massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(int\\);\n \\^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$" } +// { dg-regexp "\nIn module bob, imported at \[^\n]*adhoc-1_b.C:3:\n\[^\n]*adhoc-1_a.C:6:188: note: candidate: 'void massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea@bob\\(float\\)'\n\[ \t]*export void massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(float\\);\n\[ \t]*\\^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~?$" } +// For some reason dg-regexp inserts a blank line +// { dg-allow-blank-lines-in-output 1 } diff --git c/gcc/testsuite/g++.dg/modules/adl-1_a.C w/gcc/testsuite/g++.dg/modules/adl-1_a.C new file mode 100644 index 00000000000..d4a53cb9cb2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-1_a.C @@ -0,0 +1,13 @@ +// { dg-module-do run } +// { dg-additional-options -fmodules-ts } +export module worker; +// { dg-module-cmi worker } + +namespace details { + +export int fn (int x) +{ + return x; +} + +} diff --git c/gcc/testsuite/g++.dg/modules/adl-1_b.C w/gcc/testsuite/g++.dg/modules/adl-1_b.C new file mode 100644 index 00000000000..6cf123e41fb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-1_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options -fmodules-ts } +export module inter; +// { dg-module-cmi inter } + +import worker; + +namespace hidden { +export int fn (int x) +{ + return -x; +} +} + +export template +int TPL (T &t) +{ + return fn (t); +} diff --git c/gcc/testsuite/g++.dg/modules/adl-1_c.C w/gcc/testsuite/g++.dg/modules/adl-1_c.C new file mode 100644 index 00000000000..8be02e74937 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-1_c.C @@ -0,0 +1,57 @@ +// { dg-additional-options -fmodules-ts } + +import inter; + +namespace details +{ + +struct X +{ + + int m; + X (int m) : m(m) + { + } + + operator int () const + { + return m; + } +}; + +} + +namespace hidden +{ + +struct Y +{ + + int m; + Y (int m) : m(m) + { + } + + operator int () const + { + return m; + } +}; + +} + +int main () +{ + details::X x(2); + hidden::Y y(2); + + // details::fn@worker is visible from TPL@inter + if (TPL (x) != 2) // instantiate TPL(T&) + return 1; + + // hidden::fn@inter is visible from TPL@inter + if (TPL (y) != -2) // instantiate TPL(T&) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/adl-2_a.C w/gcc/testsuite/g++.dg/modules/adl-2_a.C new file mode 100644 index 00000000000..d8f481cad97 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-2_a.C @@ -0,0 +1,10 @@ +// { dg-module-do run } +// { dg-additional-options -fmodules-ts } +export module foo; +// { dg-module-cmi foo } + +export template +int TPL (T const &t) +{ + return frob (t); +} diff --git c/gcc/testsuite/g++.dg/modules/adl-2_b.C w/gcc/testsuite/g++.dg/modules/adl-2_b.C new file mode 100644 index 00000000000..60e794343ce --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-2_b.C @@ -0,0 +1,21 @@ +// { dg-additional-options -fmodules-ts } + +export module hidden; +// { dg-module-cmi hidden } + +export struct X +{ + int m; + + X(int m) :m(m) {} + + operator int () const + { + return m; + } +}; + +export int frob (int x) +{ + return x; +} diff --git c/gcc/testsuite/g++.dg/modules/adl-2_c.C w/gcc/testsuite/g++.dg/modules/adl-2_c.C new file mode 100644 index 00000000000..9c75b6d14a7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-2_c.C @@ -0,0 +1,17 @@ +// { dg-additional-options -fmodules-ts } + +import foo; +import hidden; + +int main () +{ + X x (2); + + if (frob (x) != 2) + return 1; + + if (TPL (x) != 2) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/adl-3_a.C w/gcc/testsuite/g++.dg/modules/adl-3_a.C new file mode 100644 index 00000000000..a2639789438 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-3_a.C @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodules-ts } +export module worker; +// { dg-module-cmi worker } + +namespace details { + +int fn (int x) +{ + return x; +} + +} diff --git c/gcc/testsuite/g++.dg/modules/adl-3_b.C w/gcc/testsuite/g++.dg/modules/adl-3_b.C new file mode 100644 index 00000000000..1f3011fdbb9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-3_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +export module inter; +// { dg-module-cmi inter } + +export template +int TPL (T &t) +{ + return fn (t); +} diff --git c/gcc/testsuite/g++.dg/modules/adl-3_c.C w/gcc/testsuite/g++.dg/modules/adl-3_c.C new file mode 100644 index 00000000000..c4dc0adc00c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-3_c.C @@ -0,0 +1,36 @@ +// { dg-additional-options -fmodules-ts } + +import inter; +import worker; + +namespace details +{ +struct X +{ + + int m; + X (int m) : m(m) + { + } + + operator int () const + { + return m; + } +}; + +} + +int main () +{ + details::X x(2); + + if (fn (x) != 2) // { dg-error "not declared in" } + return 1; + + // { dg-regexp "\n\[^\n]*adl-3_b.C:8:13: error: 'fn' was not declared in this scope$" } + if (TPL (x) != 2) // { dg-message "required from here" } + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/adl-4_a.C w/gcc/testsuite/g++.dg/modules/adl-4_a.C new file mode 100644 index 00000000000..5d956c057e2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-4_a.C @@ -0,0 +1,15 @@ +// { dg-additional-options -fmodules-ts } +export module inter; +// { dg-module-cmi inter } + +namespace hidden { +// not found via ADL +int fn (int x); + +} + +export template +int TPL (T &t) +{ + return fn (t); +} diff --git c/gcc/testsuite/g++.dg/modules/adl-4_b.C w/gcc/testsuite/g++.dg/modules/adl-4_b.C new file mode 100644 index 00000000000..aa1396f7ce2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-4_b.C @@ -0,0 +1,36 @@ +// { dg-additional-options -fmodules-ts } + +import inter; + +namespace hidden +{ + +struct Y +{ + + int m; + Y (int m) : m(m) + { + } + + operator int () const + { + return m; + } +}; + +} + +int main () +{ + hidden::Y y(2); + + // unexported hidden::fn@inter is not visible from TPL@inter + if (TPL (y) != -2) + return 2; + + return 0; +} + +// ADL fails +// { dg-regexp {[^\n]*/adl-4_a.C:14:[0-9]*: error: 'fn' was not declared in this scope\n} } diff --git c/gcc/testsuite/g++.dg/modules/adl-5_a.c w/gcc/testsuite/g++.dg/modules/adl-5_a.c new file mode 100644 index 00000000000..5b8692211d4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-5_a.c @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +export module foo; +// { dg-module-cmi foo } + +export template +int TPL (T const &t) +{ + return frob (t); +} diff --git c/gcc/testsuite/g++.dg/modules/adl-5_b.C w/gcc/testsuite/g++.dg/modules/adl-5_b.C new file mode 100644 index 00000000000..3c64cd4a75e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-5_b.C @@ -0,0 +1,22 @@ +// { dg-additional-options -fmodules-ts } + +export module hidden; +// { dg-module-cmi hidden } + +export struct X +{ + int m; + + X(int m) :m(m) {} + + operator int () const + { + return m; + } +}; + +// Not found via any ADL outside of module hidden +int frob (int x) +{ + return x; +} diff --git c/gcc/testsuite/g++.dg/modules/adl-5_c.C w/gcc/testsuite/g++.dg/modules/adl-5_c.C new file mode 100644 index 00000000000..e047aec4b1a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-5_c.C @@ -0,0 +1,17 @@ +// { dg-additional-options -fmodules-ts } + +module hidden; +import foo; + +int frob () +{ + X x (2); + + if (frob (x) != 2) + return 1; + + if (TPL (x) != 2) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/adl-5_d.C w/gcc/testsuite/g++.dg/modules/adl-5_d.C new file mode 100644 index 00000000000..9c75b6d14a7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/adl-5_d.C @@ -0,0 +1,17 @@ +// { dg-additional-options -fmodules-ts } + +import foo; +import hidden; + +int main () +{ + X x (2); + + if (frob (x) != 2) + return 1; + + if (TPL (x) != 2) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/alias-1_a.H w/gcc/testsuite/g++.dg/modules/alias-1_a.H new file mode 100644 index 00000000000..8c5683608ad --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/alias-1_a.H @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodule-header -isystem [srcdir]" } +// { dg-module-cmi {} } + +#ifndef ALIAS_1_A +#define ALIAS_1_A + +int frob (); + +#endif diff --git c/gcc/testsuite/g++.dg/modules/alias-1_b.C w/gcc/testsuite/g++.dg/modules/alias-1_b.C new file mode 100644 index 00000000000..b3d7c2df353 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/alias-1_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module -isystem [srcdir]" } + +// Alias at the header file. We have one CMI file +import "alias-1_a.H"; +import ; + +int main () +{ + frob (); +} + +// { dg-final { scan-lang-dump-times {CMI is } 1 module } } diff --git c/gcc/testsuite/g++.dg/modules/alias-1_c.C w/gcc/testsuite/g++.dg/modules/alias-1_c.C new file mode 100644 index 00000000000..6f9f1aa06c0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/alias-1_c.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts -isystem [srcdir]" } +// { dg-module-cmi bob } + +export module bob; +import "alias-1_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/alias-1_d.C w/gcc/testsuite/g++.dg/modules/alias-1_d.C new file mode 100644 index 00000000000..9b481e5b185 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/alias-1_d.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts -isystem [srcdir]" } +// { dg-module-cmi kevin } + +export module kevin; +import ; diff --git c/gcc/testsuite/g++.dg/modules/alias-1_e.C w/gcc/testsuite/g++.dg/modules/alias-1_e.C new file mode 100644 index 00000000000..862ae32882f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/alias-1_e.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -isystem [srcdir]" } + +import bob; +import kevin; diff --git c/gcc/testsuite/g++.dg/modules/alias-1_f.C w/gcc/testsuite/g++.dg/modules/alias-1_f.C new file mode 100644 index 00000000000..4c694d1a903 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/alias-1_f.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module -isystem [srcdir]" } + +import kevin; +import bob; diff --git c/gcc/testsuite/g++.dg/modules/alias-2_a.H w/gcc/testsuite/g++.dg/modules/alias-2_a.H new file mode 100644 index 00000000000..1befe85cf49 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/alias-2_a.H @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodule-header -isystem [srcdir]/sys" } +// { dg-module-cmi {} } +// { dg-module-headers test sys/alias-2_a.H } +#ifndef ALIAS_2_A +#define ALIAS_2_A + +int frob (); + +#endif diff --git c/gcc/testsuite/g++.dg/modules/alias-2_b.C w/gcc/testsuite/g++.dg/modules/alias-2_b.C new file mode 100644 index 00000000000..00eff590e3b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/alias-2_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module -isystem [srcdir]/sys" } + +// These find different headers +import "alias-2_a.H"; +import ; + +int main () +{ + frob (); + frob (1); +} + +// { dg-final { scan-lang-dump-times {CMI is} 2 module } } diff --git c/gcc/testsuite/g++.dg/modules/align-type-1_a.C w/gcc/testsuite/g++.dg/modules/align-type-1_a.C new file mode 100644 index 00000000000..71240341469 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/align-type-1_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +export using aint = __attribute__ ((aligned(16))) int; + + diff --git c/gcc/testsuite/g++.dg/modules/align-type-1_b.C w/gcc/testsuite/g++.dg/modules/align-type-1_b.C new file mode 100644 index 00000000000..8372e6f3e1b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/align-type-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } + +import foo; + +struct B +{ + aint m; +}; + +static_assert (alignof (B) == 16); diff --git c/gcc/testsuite/g++.dg/modules/ambig-1_a.C w/gcc/testsuite/g++.dg/modules/ambig-1_a.C new file mode 100644 index 00000000000..fbb3db2ac47 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ambig-1_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +export module One; +// { dg-module-cmi One } + +export int foo (); +export char bax (); +export int quux (float); + + diff --git c/gcc/testsuite/g++.dg/modules/ambig-1_b.C w/gcc/testsuite/g++.dg/modules/ambig-1_b.C new file mode 100644 index 00000000000..c1de9192323 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ambig-1_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } +import One; + +int foo (); // { dg-error "conflicts with import" } +int bax (); // { dg-error "ambiguating new declaration" } +int quux (int); diff --git c/gcc/testsuite/g++.dg/modules/anon-1_a.C w/gcc/testsuite/g++.dg/modules/anon-1_a.C new file mode 100644 index 00000000000..e56b85ce720 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/anon-1_a.C @@ -0,0 +1,14 @@ +// { dg-additional-options -fmodules-ts } + +export module anon; +// { dg-module-cmi anon } + +export struct foo +{ + enum {bob}; + union + { + int i; + float f; + }; +}; diff --git c/gcc/testsuite/g++.dg/modules/anon-1_b.C w/gcc/testsuite/g++.dg/modules/anon-1_b.C new file mode 100644 index 00000000000..66d25053049 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/anon-1_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options -fmodules-ts } + +export module namer; +// { dg-module-cmi namer } + +import anon; + +export inline int &get_int (foo &obj) +{ + return obj.i; +} + +export inline float &get_float (foo &obj) +{ + return obj.f; +} + + diff --git c/gcc/testsuite/g++.dg/modules/anon-1_c.C w/gcc/testsuite/g++.dg/modules/anon-1_c.C new file mode 100644 index 00000000000..cbe89e15ed9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/anon-1_c.C @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodules-ts } + +import namer; +import anon; + +int main () +{ + foo obj; + int *ip = &get_int (obj); + float *fp = &get_float (obj); + + return !((void *)ip == (void *)fp); +} diff --git c/gcc/testsuite/g++.dg/modules/anon-2.h w/gcc/testsuite/g++.dg/modules/anon-2.h new file mode 100644 index 00000000000..81c793c7ffc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/anon-2.h @@ -0,0 +1,6 @@ + + +struct __pthread_cond_s +{ + union {}; +}; diff --git c/gcc/testsuite/g++.dg/modules/anon-2_a.H w/gcc/testsuite/g++.dg/modules/anon-2_a.H new file mode 100644 index 00000000000..6861c194fce --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/anon-2_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "anon-2.h" diff --git c/gcc/testsuite/g++.dg/modules/anon-2_b.C w/gcc/testsuite/g++.dg/modules/anon-2_b.C new file mode 100644 index 00000000000..24bb61b5f14 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/anon-2_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } + +#include "anon-2.h" +import "anon-2_a.H"; + diff --git c/gcc/testsuite/g++.dg/modules/atom-decl-0_a.C w/gcc/testsuite/g++.dg/modules/atom-decl-0_a.C new file mode 100644 index 00000000000..d226f32cea1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-decl-0_a.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +export module thing; +// { dg-module-cmi "thing" } + +export int baz (); diff --git c/gcc/testsuite/g++.dg/modules/atom-decl-0_b.C w/gcc/testsuite/g++.dg/modules/atom-decl-0_b.C new file mode 100644 index 00000000000..8ca006d64ee --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-decl-0_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +import thing; + +void bink () +{ + baz (); +} diff --git c/gcc/testsuite/g++.dg/modules/atom-decl-0_c.C w/gcc/testsuite/g++.dg/modules/atom-decl-0_c.C new file mode 100644 index 00000000000..96e74956e90 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-decl-0_c.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } +export module pop; +// { dg-module-cmi "pop" } +export import thing; + +void bink (); + +void bonk () +{ + baz (); + bink (); +} diff --git c/gcc/testsuite/g++.dg/modules/atom-decl-2.C w/gcc/testsuite/g++.dg/modules/atom-decl-2.C new file mode 100644 index 00000000000..b463dc8e214 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-decl-2.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } +export module thing; +int i; +import baz; // { dg-error "must be contiguous" } + +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/atom-decl-3.C w/gcc/testsuite/g++.dg/modules/atom-decl-3.C new file mode 100644 index 00000000000..6eb6e6bd93f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-decl-3.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } +int i; +import bazza; +// { dg-error "failed to read" "" { target *-*-* } 0 } +// { dg-prune-output "fatal error:" } +// { dg-prune-output "compilation terminated" } diff --git c/gcc/testsuite/g++.dg/modules/atom-pragma-1.C w/gcc/testsuite/g++.dg/modules/atom-pragma-1.C new file mode 100644 index 00000000000..133382e8886 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-pragma-1.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } +export module foo; +// { dg-module-cmi foo } + +#pragma bob +int i; diff --git c/gcc/testsuite/g++.dg/modules/atom-pragma-3.C w/gcc/testsuite/g++.dg/modules/atom-pragma-3.C new file mode 100644 index 00000000000..b95b2c8ad75 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-pragma-3.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } + +export module foo; +// { dg-module-cmi !foo } +; + +#pragma pack(2) +import baz; // { dg-error "must be contiguous" } + +int i; + +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/atom-preamble-1.C w/gcc/testsuite/g++.dg/modules/atom-preamble-1.C new file mode 100644 index 00000000000..1161d41b561 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-preamble-1.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +#define EXPORT export // { dg-error "only occur after a module" } +EXPORT module bob; // { dg-error "does not name a type" } +// { dg-message "not recognized as" "" { target *-*-* } .-1 } + diff --git c/gcc/testsuite/g++.dg/modules/atom-preamble-2_a.C w/gcc/testsuite/g++.dg/modules/atom-preamble-2_a.C new file mode 100644 index 00000000000..02fbd84afff --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-preamble-2_a.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } +#define malcolm kevin +export module malcolm; +// { dg-module-cmi kevin } + +export class X; diff --git c/gcc/testsuite/g++.dg/modules/atom-preamble-2_b.C w/gcc/testsuite/g++.dg/modules/atom-preamble-2_b.C new file mode 100644 index 00000000000..a97d9758fd2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-preamble-2_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } +#if 1 +export module bob; +// { dg-module-cmi bob } +#endif + +import kevin; + +X *f; + diff --git c/gcc/testsuite/g++.dg/modules/atom-preamble-2_c.C w/gcc/testsuite/g++.dg/modules/atom-preamble-2_c.C new file mode 100644 index 00000000000..d3804c2b0bc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-preamble-2_c.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } +#pragma bob + +import kevin; + +X *f; diff --git c/gcc/testsuite/g++.dg/modules/atom-preamble-2_d.C w/gcc/testsuite/g++.dg/modules/atom-preamble-2_d.C new file mode 100644 index 00000000000..0c3b290499a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-preamble-2_d.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } +import kevin; + +#if 1 +#if 1 +import kevin; +#endif +#elif 1 +int i; +#endif + +int j; // end here diff --git c/gcc/testsuite/g++.dg/modules/atom-preamble-2_e.C w/gcc/testsuite/g++.dg/modules/atom-preamble-2_e.C new file mode 100644 index 00000000000..074f8ebadb4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-preamble-2_e.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } +import kevin; + +#if 0 +#if 1 +import kevin; +#endif +#elif 1 +import kevin; +#endif + +int i; // end here diff --git c/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C w/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C new file mode 100644 index 00000000000..28e54b808b2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +export module stuart; +// { dg-module-cmi !stuart } + +# 6 "atom-preamble-2_f.C" 1 +import kevin; // { dg-error "not be from header" } +# 8 "" 2 + +import kevin; // ok +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/atom-preamble-3.C w/gcc/testsuite/g++.dg/modules/atom-preamble-3.C new file mode 100644 index 00000000000..74dba7d23a6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-preamble-3.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +#define import import +import malcolm; // { dg-error "object-like macro" } +// { dg-error "failed to read" "" { target *-*-* } 0 } + +// { dg-prune-output "compilation terminated" } +// { dg-prune-output "fatal error:" } diff --git c/gcc/testsuite/g++.dg/modules/atom-preamble-4.C w/gcc/testsuite/g++.dg/modules/atom-preamble-4.C new file mode 100644 index 00000000000..21a8d57da65 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/atom-preamble-4.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +#define NAME(X) X; + +export module NAME(bob) + diff --git c/gcc/testsuite/g++.dg/modules/auto-1.h w/gcc/testsuite/g++.dg/modules/auto-1.h new file mode 100644 index 00000000000..f8ae751df32 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/auto-1.h @@ -0,0 +1,19 @@ + +template auto frob (T t) +{ + return t; +} + +struct Bob +{ + operator auto () + { + return 0; + } +}; + +inline auto foo () +{ + return frob (1) + int (Bob ()); +} + diff --git c/gcc/testsuite/g++.dg/modules/auto-1_a.H w/gcc/testsuite/g++.dg/modules/auto-1_a.H new file mode 100644 index 00000000000..4d3bc77dbb1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/auto-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "auto-1.h" diff --git c/gcc/testsuite/g++.dg/modules/auto-1_b.C w/gcc/testsuite/g++.dg/modules/auto-1_b.C new file mode 100644 index 00000000000..96350662fed --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/auto-1_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "auto-1.h" +import "auto-1_a.H"; + +int bar () +{ + return foo () + frob (0u); +} + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/auto-2.h w/gcc/testsuite/g++.dg/modules/auto-2.h new file mode 100644 index 00000000000..4759ab8bbc1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/auto-2.h @@ -0,0 +1,13 @@ + +template +struct _RangeAdaptor +{ + constexpr _RangeAdaptor(const _Callable &) { } +}; + +template +_RangeAdaptor(_Callable) -> _RangeAdaptor<_Callable>; + +template +inline constexpr _RangeAdaptor elements = [] (auto&& __r) {}; + diff --git c/gcc/testsuite/g++.dg/modules/auto-2_a.H w/gcc/testsuite/g++.dg/modules/auto-2_a.H new file mode 100644 index 00000000000..46bd74697a5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/auto-2_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header -fconcepts" } +// { dg-module-cmi {} } + +#include "auto-2.h" diff --git c/gcc/testsuite/g++.dg/modules/auto-2_b.C w/gcc/testsuite/g++.dg/modules/auto-2_b.C new file mode 100644 index 00000000000..5ed882f7416 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/auto-2_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts -fconcepts -fdump-lang-module-alias -fno-module-lazy" } + +#include "auto-2.h" +import "auto-2_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/bad-mapper-1.C w/gcc/testsuite/g++.dg/modules/bad-mapper-1.C new file mode 100644 index 00000000000..7ed75b824b4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bad-mapper-1.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts -fmodule-mapper=|this-will-not-work" } +import unique1.bob; +// { dg-error "-:failed exec.*mapper.* .*this-will-not-work" "" { target *-*-* } 0 } +// { dg-prune-output "fatal error:" } +// { dg-prune-output "failed to read" } +// { dg-prune-output "compilation terminated" } diff --git c/gcc/testsuite/g++.dg/modules/bad-mapper-2.C w/gcc/testsuite/g++.dg/modules/bad-mapper-2.C new file mode 100644 index 00000000000..f35d16bace3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bad-mapper-2.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts -fmodule-mapper=not-a-host:3838" } +import unique2.bob; +// { dg-error "failed .* mapper 'not-a-host" "" { target *-*-* } 0 } +// { dg-prune-output "fatal error:" } +// { dg-prune-output "failed to read" } +// { dg-prune-output "compilation terminated" } diff --git c/gcc/testsuite/g++.dg/modules/bad-mapper-3.C w/gcc/testsuite/g++.dg/modules/bad-mapper-3.C new file mode 100644 index 00000000000..9dab332ccb2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bad-mapper-3.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts -fmodule-mapper=localhost:172477262" } +import unique3.bob; +// { dg-error {failed connecting mapper 'localhost:172477262'} "" { target *-*-* } 0 } +// { dg-prune-output "fatal error:" } +// { dg-prune-output "failed to read" } +// { dg-prune-output "compilation terminated" } diff --git c/gcc/testsuite/g++.dg/modules/ben-1.map w/gcc/testsuite/g++.dg/modules/ben-1.map new file mode 100644 index 00000000000..182183ad089 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ben-1.map @@ -0,0 +1,3 @@ +$root . +module:import partitions/module:import.mod +module module.mod diff --git c/gcc/testsuite/g++.dg/modules/ben-1_a.C w/gcc/testsuite/g++.dg/modules/ben-1_a.C new file mode 100644 index 00000000000..7e9b5661026 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ben-1_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -fmodule-mapper=[srcdir]/ben-1.map" } +// { dg-additional-files ben-1.map } + +export module module:import; +// { dg-module-cmi =partitions/module:import.mod } + +export int b() { + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/ben-1_b.C w/gcc/testsuite/g++.dg/modules/ben-1_b.C new file mode 100644 index 00000000000..e16fa2fc857 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ben-1_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts -fmodule-mapper=[srcdir]/ben-1.map" } +// { dg-additional-files ben-1.map } + +export module module; +// { dg-module-cmi =module.mod } +export import :import; + +export int c () +{ + return b (); +} diff --git c/gcc/testsuite/g++.dg/modules/bfield-1_a.C w/gcc/testsuite/g++.dg/modules/bfield-1_a.C new file mode 100644 index 00000000000..15b8cb6c54a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bfield-1_a.C @@ -0,0 +1,15 @@ +// { dg-additional-options -fmodules-ts } +export module foo; +// { dg-module-cmi foo } + +export struct timex +{ + int a; + int :32; + int :32; + int :32; + int :32; + int :32; + int :32; +}; + diff --git c/gcc/testsuite/g++.dg/modules/bfield-1_b.C w/gcc/testsuite/g++.dg/modules/bfield-1_b.C new file mode 100644 index 00000000000..6c8dae6e29e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bfield-1_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodules-ts } +import foo; + +timex v = {1}; diff --git c/gcc/testsuite/g++.dg/modules/bfield-2_a.C w/gcc/testsuite/g++.dg/modules/bfield-2_a.C new file mode 100644 index 00000000000..5329e62da3d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bfield-2_a.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +export struct ting +{ + int a; + int b : 3; + int c : 5; +}; diff --git c/gcc/testsuite/g++.dg/modules/bfield-2_b.C w/gcc/testsuite/g++.dg/modules/bfield-2_b.C new file mode 100644 index 00000000000..737173697c7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bfield-2_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodules-ts } +import foo; + +ting v = {1, 2, 3}; diff --git c/gcc/testsuite/g++.dg/modules/bool-1.h w/gcc/testsuite/g++.dg/modules/bool-1.h new file mode 100644 index 00000000000..80f0ec161cc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bool-1.h @@ -0,0 +1,8 @@ +typedef signed char __v16qs __attribute__ ((__vector_size__ (16))); + + +inline auto +_mm_cmplt_epi8 (__v16qs __A, __v16qs __B) +{ + return __A < __B; +} diff --git c/gcc/testsuite/g++.dg/modules/bool-1_a.H w/gcc/testsuite/g++.dg/modules/bool-1_a.H new file mode 100644 index 00000000000..3b4232c1d08 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bool-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options {-fmodule-header -Wno-psabi} } +// { dg-module-cmi {} } + +#include "bool-1.h" diff --git c/gcc/testsuite/g++.dg/modules/bool-1_b.H w/gcc/testsuite/g++.dg/modules/bool-1_b.H new file mode 100644 index 00000000000..d22e1d93286 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bool-1_b.H @@ -0,0 +1,5 @@ +// { dg-additional-options {-fmodule-header -fno-module-lazy -Wno-psabi} } +// { dg-module-cmi {} } + +#include "bool-1.h" +import "bool-1_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/bool-1_c.C w/gcc/testsuite/g++.dg/modules/bool-1_c.C new file mode 100644 index 00000000000..01b08775191 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bool-1_c.C @@ -0,0 +1,8 @@ +// { dg-additional-options {-fmodules-ts -Wno-psabi} } + +import "bool-1_b.H"; + +void frob (signed char __attribute__ ((__vector_size__ (16))) arg) +{ + _mm_cmplt_epi8 (arg, arg); +} diff --git c/gcc/testsuite/g++.dg/modules/bug-1_a.C w/gcc/testsuite/g++.dg/modules/bug-1_a.C new file mode 100644 index 00000000000..b828b7b8bc6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bug-1_a.C @@ -0,0 +1,9 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } +export module One; +// { dg-module-cmi "One" } + +export int Frob (int a) +{ + return -a; +} diff --git c/gcc/testsuite/g++.dg/modules/bug-1_b.C w/gcc/testsuite/g++.dg/modules/bug-1_b.C new file mode 100644 index 00000000000..7b5baeb9276 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/bug-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } +import One; + +int main () +{ + if (Frob (2) != -2) + return 1; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/builtin-1_a.C w/gcc/testsuite/g++.dg/modules/builtin-1_a.C new file mode 100644 index 00000000000..6d0731a727d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-1_a.C @@ -0,0 +1,18 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks-alias-uid" } +export module builtin; +// { dg-module-cmi builtin } + +export inline void ary_del (int *ptr) +{ + delete[] ptr; +} + +export inline void scalar_del (int *ptr) +{ + delete ptr; +} + +// { dg-final { scan-lang-dump {Wrote GMF:-[0-9]* function_decl:'::operator delete'@builtin} module } } +// { dg-final { scan-lang-dump {Wrote GMF:-[0-9]* function_decl:'::operator delete \[\]'@builtin} module } } + +// { dg-final { scan-lang-dump {Writing named:-[0-9]* function_decl:'::operator delete'\n *Wrote[^\n]*\n *Writing:-[0-9]*'s named merge key \(decl\) function_decl:'::operator delete'} module } } diff --git c/gcc/testsuite/g++.dg/modules/builtin-1_b.C w/gcc/testsuite/g++.dg/modules/builtin-1_b.C new file mode 100644 index 00000000000..e9f73485661 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-1_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-alias" } +import builtin; + +int main () +{ + ary_del (nullptr); + scalar_del (nullptr); + return 0; +} + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) function_decl:'::operator delete \[\]'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) function_decl:'::operator delete'} module } } diff --git c/gcc/testsuite/g++.dg/modules/builtin-2.C w/gcc/testsuite/g++.dg/modules/builtin-2.C new file mode 100644 index 00000000000..f9de98fda9b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-2.C @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodules-ts } + +extern "C" +{ + extern int printf (const char *__restrict __format, ...); +} + diff --git c/gcc/testsuite/g++.dg/modules/builtin-3_b.C w/gcc/testsuite/g++.dg/modules/builtin-3_b.C new file mode 100644 index 00000000000..93489bddba4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-3_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-alias" } +import builtins; + +int main () +{ + length (""); + count (1, "", "", nullptr); +} + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) function_decl:'::__builtin_strlen'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) type_decl:'::__builtin_va_list'} module { target { x86_64-*-linux* } } } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(new\) type_decl:'::va_list'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(new\) type_decl:'::__gnuc_va_list'} module } } diff --git c/gcc/testsuite/g++.dg/modules/builtin-4_a.H w/gcc/testsuite/g++.dg/modules/builtin-4_a.H new file mode 100644 index 00000000000..f7bc6aff639 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-4_a.H @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +void* operator new(__SIZE_TYPE__); +void* operator new[](__SIZE_TYPE__); + +void operator delete (void*) noexcept; +void operator delete[](void*) noexcept; + diff --git c/gcc/testsuite/g++.dg/modules/builtin-4_b.C w/gcc/testsuite/g++.dg/modules/builtin-4_b.C new file mode 100644 index 00000000000..1d780e6a80f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-4_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +import "builtin-4_a.H"; + +int main () +{ + operator delete (operator new (10)); + operator delete[] (operator new[] (10)); +} + +// { dg-final { scan-lang-dump {named merge key \(matched\) function_decl:'::operator new'} module } } +// { dg-final { scan-lang-dump {named merge key \(matched\) function_decl:'::operator delete'} module } } +// { dg-final { scan-lang-dump {named merge key \(matched\) function_decl:'::operator new \[\]'} module } } +// { dg-final { scan-lang-dump {named merge key \(matched\) function_decl:'::operator delete \[\]'} module } } diff --git c/gcc/testsuite/g++.dg/modules/builtin-5_a.H w/gcc/testsuite/g++.dg/modules/builtin-5_a.H new file mode 100644 index 00000000000..735d32388d2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-5_a.H @@ -0,0 +1,3 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } +extern "C" int printf (char const *, ...); diff --git c/gcc/testsuite/g++.dg/modules/builtin-5_b.C w/gcc/testsuite/g++.dg/modules/builtin-5_b.C new file mode 100644 index 00000000000..bfaa64f9b55 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-5_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-alias" } + +import "builtin-5_a.H"; + +void foo () +{ + printf ("bob\n"); +} + +extern "C" int printf (char const *, int); + +// { dg-regexp {[^\n]*builtin-5_b.C:10:[0-9]*: error: conflicting declaration of C function 'int printf\(const char\*, int\)'\nIn module [^\n]*builtin-5_a.H, imported at [^\n]*builtin-5_b.C:3:\n[^\n]*builtin-5_a.H:3:[0-9]*: note: previous declaration 'int printf\(const char\*, ...\)'} } + +// { dg-final { scan-lang-dump {Read:-1's named merge key \(matched\) function_decl:'::printf'} module } } diff --git c/gcc/testsuite/g++.dg/modules/builtin-6_a.H w/gcc/testsuite/g++.dg/modules/builtin-6_a.H new file mode 100644 index 00000000000..b3263bc9ba7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-6_a.H @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +extern "C" { + +static double sin (double) +{ + // extra small angle approximation :) + return 0.0; +} + +} diff --git c/gcc/testsuite/g++.dg/modules/builtin-6_b.C w/gcc/testsuite/g++.dg/modules/builtin-6_b.C new file mode 100644 index 00000000000..80f8dc64a20 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-6_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + + +import "builtin-6_a.H"; + +int main () +{ + return sin (0.0); +} diff --git c/gcc/testsuite/g++.dg/modules/builtin-7_a.H w/gcc/testsuite/g++.dg/modules/builtin-7_a.H new file mode 100644 index 00000000000..a98a7b71092 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-7_a.H @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodule-header } +// { dg-module_cmi {} } + +extern "C" +{ +extern double nan(const char *); +inline long double nanl(const char * __x) { return nan(__x); } +} diff --git c/gcc/testsuite/g++.dg/modules/builtin-7_b.C w/gcc/testsuite/g++.dg/modules/builtin-7_b.C new file mode 100644 index 00000000000..28514571ce6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/builtin-7_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +import "builtin-7_a.H"; + +void f () +{ + nanl (""); +} diff --git c/gcc/testsuite/g++.dg/modules/by-name-1.C w/gcc/testsuite/g++.dg/modules/by-name-1.C new file mode 100644 index 00000000000..44eb4478d13 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/by-name-1.C @@ -0,0 +1,15 @@ +// check internals by name unless SCC +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } + +export module frob; +// { dg-module-cmi frob } + +class X +{ + int i; +}; + +export X *f (); + +// { dg-final { scan-lang-dump {Wrote purview:-[0-9]* type_decl:'::X'} "module" } } +// { dg-final { scan-lang-dump {Indirect:-[0-9]* decl's type record_type:'::X'} "module" } } diff --git c/gcc/testsuite/g++.dg/modules/cexpr-1_a.C w/gcc/testsuite/g++.dg/modules/cexpr-1_a.C new file mode 100644 index 00000000000..b9c4b1692f0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cexpr-1_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } +export module Const; +// { dg-module-cmi "Const" } + +export constexpr int SQ (int b) +{ + return b * b; +} diff --git c/gcc/testsuite/g++.dg/modules/cexpr-1_b.C w/gcc/testsuite/g++.dg/modules/cexpr-1_b.C new file mode 100644 index 00000000000..30566110e02 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cexpr-1_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts" } +import Const; + +static_assert (SQ(88) == 88 * 88, "waaa!"); diff --git c/gcc/testsuite/g++.dg/modules/cexpr-2_a.C w/gcc/testsuite/g++.dg/modules/cexpr-2_a.C new file mode 100644 index 00000000000..632a4e3a485 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cexpr-2_a.C @@ -0,0 +1,19 @@ +// { dg-additional-options "-fmodules-ts" } +export module sqrt; +// { dg-module-cmi "sqrt" } + +export constexpr unsigned sqrt (unsigned X, unsigned x = 1) +{ + // Newton-Raphson, not binary restoring + // x <= x - f(x)/f'(x) + // f(x) = x^2 - X + // f'(x) = 2x + // x <= x - (x^2 - X) / 2x + // x <= x - x/2 + X/2x + // x <= x/2 + X/2x + // x <= 1/2(x + X/x) + unsigned nx = (x + X/x) / 2; + if (nx != x) + nx = sqrt (X, nx); + return nx; +} diff --git c/gcc/testsuite/g++.dg/modules/cexpr-2_b.C w/gcc/testsuite/g++.dg/modules/cexpr-2_b.C new file mode 100644 index 00000000000..6a589aeb235 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cexpr-2_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts" } +import sqrt; + +static_assert (sqrt(81) == 9, "waaa!"); diff --git c/gcc/testsuite/g++.dg/modules/circ-1_a.C w/gcc/testsuite/g++.dg/modules/circ-1_a.C new file mode 100644 index 00000000000..fa56c78b703 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/circ-1_a.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +export module Bob; +// { dg-module-cmi Bob } + +export int bob (); diff --git c/gcc/testsuite/g++.dg/modules/circ-1_b.C w/gcc/testsuite/g++.dg/modules/circ-1_b.C new file mode 100644 index 00000000000..9174c1553ab --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/circ-1_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +export module Kevin; +// { dg-module-cmi Kevin } + +import Bob; + +export int kevin (); diff --git c/gcc/testsuite/g++.dg/modules/circ-1_c.C w/gcc/testsuite/g++.dg/modules/circ-1_c.C new file mode 100644 index 00000000000..cea17d7a2e0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/circ-1_c.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts" } +export module Bob; // { dg-message "declared here" } +// No need to dg-module-cmi + +import Kevin; +// { dg-error "failed to read" "" { target *-*-* } 0 } +// { dg-error "cannot import module" "" { target *-*-* } 0 } +// { dg-prune-output "fatal error:" } +// { dg-prune-output "compilation terminated" } diff --git c/gcc/testsuite/g++.dg/modules/circ-1_d.C w/gcc/testsuite/g++.dg/modules/circ-1_d.C new file mode 100644 index 00000000000..b6f6b7ddd32 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/circ-1_d.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } +module; +import Kevin; + +export module Bob; // { dg-error "module already imported" } +// { dg-message "imported here" "Kevin.nms:" { target *-*-* } 0 } diff --git c/gcc/testsuite/g++.dg/modules/class-1_a.C w/gcc/testsuite/g++.dg/modules/class-1_a.C new file mode 100644 index 00000000000..6463719cae2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-1_a.C @@ -0,0 +1,15 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } +export module One; +// { dg-module-cmi "One" } + +namespace Bob +{ + struct X; + export struct Y { + unsigned a; + unsigned b; + }; +} + +export void copy (Bob::Y *, const Bob::Y *); diff --git c/gcc/testsuite/g++.dg/modules/class-1_b.C w/gcc/testsuite/g++.dg/modules/class-1_b.C new file mode 100644 index 00000000000..5eac51da073 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-1_b.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts" } +module One; + +struct Bob::X +{ + int i; +}; + + +int x = sizeof (Bob::X); + +void copy (Bob::Y *dst, Bob::Y const *src) +{ + dst->a = src->a; + dst->b = src->b; +} diff --git c/gcc/testsuite/g++.dg/modules/class-1_c.C w/gcc/testsuite/g++.dg/modules/class-1_c.C new file mode 100644 index 00000000000..8e23c4f2db6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-1_c.C @@ -0,0 +1,35 @@ +// { dg-additional-options "-fmodules-ts" } +import One; + +int y = sizeof (Bob::Y); + +unsigned Foo (Bob::Y *ptr) +{ + return ptr->a + ptr->b; +} + +int main () +{ + if (y != 2 * sizeof (int)) + return 1; + + unsigned pun[4]; + pun[0] = 0xdeadbeef; + pun[1] = 0xfeedface; + pun[2] = 0x8badf00d; + pun[3] = 0xcafed00d; + + copy ((Bob::Y *)pun, (Bob::Y *)&pun[2]); + + if (pun[0] != 0x8badf00d) + return 2; + if (pun[1] != 0xcafed00d) + return 3; + if (pun[2] != 0x8badf00d) + return 4; + + if (Foo ((Bob::Y *)&pun[1]) != 0xcafed00d + 0x8badf00d) + return 5; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/class-2_a.C w/gcc/testsuite/g++.dg/modules/class-2_a.C new file mode 100644 index 00000000000..04f11cd8c8f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-2_a.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts" } +// This sequence is for errors + +export module One; +// { dg-module-cmi "One" } + +namespace Bob +{ + struct X; + export struct Y { + unsigned a; + unsigned b; + }; +} + +export void copy (Bob::Y *, const Bob::Y *); diff --git c/gcc/testsuite/g++.dg/modules/class-2_b.C w/gcc/testsuite/g++.dg/modules/class-2_b.C new file mode 100644 index 00000000000..0f8edb87095 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-2_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts" } +import One; + +int z = sizeof (Bob::X); // { dg-error "not a member of .Bob." } diff --git c/gcc/testsuite/g++.dg/modules/class-3_a.C w/gcc/testsuite/g++.dg/modules/class-3_a.C new file mode 100644 index 00000000000..c775f7b589c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-3_a.C @@ -0,0 +1,15 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } +export module One; +// { dg-module-cmi "One" } + +export struct X +{ + X (int, int); + X (int a_) + : a(a_), b (a_ << 16) + { + } + int a; + int b; +}; diff --git c/gcc/testsuite/g++.dg/modules/class-3_b.C w/gcc/testsuite/g++.dg/modules/class-3_b.C new file mode 100644 index 00000000000..0e07e888753 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-3_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } +export module Two; + +export import One; + +export inline void Frob (X &q) +{ + q.b = q.a; +} + +// { dg-final { scan-lang-dump {Wrote import:-1 type_decl:'::X@One:.'} module } } +// { dg-final { scan-lang-dump {Indirect:-2 decl's type record_type:'::X@One:.'} module } } +// { dg-final { scan-lang-dump {Wrote import:-[0-9]* type_decl:'::X@One:.'@One} module } } +// { dg-final { scan-lang-dump {Indirect:-[0-9]* decl's type record_type:'::X@One:.'} module } } +// { dg-final { scan-lang-dump {Wrote import:-[0-9]* type_decl:'::X@One:.'@One} module } } +// { dg-final { scan-lang-dump {Indirect:-[0-9]* decl's type record_type:'::X@One:.'} module } } +// { dg-final { scan-lang-dump {Wrote member:-[0-9]* field_decl:'::X@One:.::a'} module } } +// { dg-final { scan-lang-dump {Wrote member:-[0-9]* field_decl:'::X@One:.::b'} module } } diff --git c/gcc/testsuite/g++.dg/modules/class-3_c.C w/gcc/testsuite/g++.dg/modules/class-3_c.C new file mode 100644 index 00000000000..6b82d1e7ffb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-3_c.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +module One; + +X::X (int a_, int b_) + : a (a_), b (b_) +{ +} diff --git c/gcc/testsuite/g++.dg/modules/class-3_d.C w/gcc/testsuite/g++.dg/modules/class-3_d.C new file mode 100644 index 00000000000..0710941d5ed --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-3_d.C @@ -0,0 +1,25 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } +import Two; + +int main () +{ + X x (0xdead, 0xbeef); + + if (x.a != 0xdead || x.b != 0xbeef) + return 1; + + Frob (x); + if (x.b != 0xdead) + return 2; + + X y (0xcafe); + if (y.a != 0xcafe || y.b != 0xcafe << 16) + return 3; + + return 0; +} + +// { dg-final { scan-lang-dump {Imported:-1 type_decl:'::X@One:.'@One} module } } +// { dg-final { scan-lang-dump {Indirect:-2 decl's type record_type:'::X@One:.'} module } } +// { dg-final { scan-lang-dump {Read member:-[0-9]* field_decl:'::X@One:.::a'} module } } +// { dg-final { scan-lang-dump {Read member:-[0-9]* field_decl:'::X@One:.::b'} module } } diff --git c/gcc/testsuite/g++.dg/modules/class-4_a.C w/gcc/testsuite/g++.dg/modules/class-4_a.C new file mode 100644 index 00000000000..a9810ab3360 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-4_a.C @@ -0,0 +1,25 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } +export module One; +// { dg-module-cmi "One" } + +export struct base +{ + int b; + + base (int b_) + : b (b_) + { + } + +}; + +export struct derived : base +{ + int d; + + derived (int b_, int d_) + : base (b_), d (d_) + { + } +}; diff --git c/gcc/testsuite/g++.dg/modules/class-4_b.C w/gcc/testsuite/g++.dg/modules/class-4_b.C new file mode 100644 index 00000000000..1cd39984052 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-4_b.C @@ -0,0 +1,15 @@ +// { dg-additional-options "-fmodules-ts" } +import One; + +int main () +{ + base b (0xfeed); + if (!(b.b == 0xfeed)) + return 1; + + derived d (0xcafe, 0xbeef); + if (!(d.b == 0xcafe && d.d == 0xbeef)) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/class-5_a.C w/gcc/testsuite/g++.dg/modules/class-5_a.C new file mode 100644 index 00000000000..417cb6b115c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-5_a.C @@ -0,0 +1,16 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } +export module One; +// { dg-module-cmi "One" } + +export struct base +{ + int b; + + base (int b_) + : b (b_) + { + } + + virtual int getter () const; +}; diff --git c/gcc/testsuite/g++.dg/modules/class-5_b.C w/gcc/testsuite/g++.dg/modules/class-5_b.C new file mode 100644 index 00000000000..89db01c3be7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-5_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +module One; + +int base::getter () const +{ + return b; +} diff --git c/gcc/testsuite/g++.dg/modules/class-5_c.C w/gcc/testsuite/g++.dg/modules/class-5_c.C new file mode 100644 index 00000000000..ee3250d7bed --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-5_c.C @@ -0,0 +1,17 @@ +// { dg-additional-options "-fmodules-ts" } +import One; + +int vcall (base *ptr) +{ + return ptr->getter (); +} + +int main () +{ + base b (0xfeed); + + if (!(vcall (&b) == 0xfeed)) + return 1; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/class-6_a.C w/gcc/testsuite/g++.dg/modules/class-6_a.C new file mode 100644 index 00000000000..9c117c944b8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-6_a.C @@ -0,0 +1,30 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } +export module One; +// { dg-module-cmi "One" } + +export struct base +{ + int b; + + base (int b_) + : b (b_) + { + } + + virtual int getter () const; +}; + +export struct pad +{ + int pad; + virtual ~pad (); +}; + +export struct derived : pad, virtual base +{ + derived (int v) + :base (v) + { + } +}; diff --git c/gcc/testsuite/g++.dg/modules/class-6_b.C w/gcc/testsuite/g++.dg/modules/class-6_b.C new file mode 100644 index 00000000000..1a49ced4b1c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-6_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts" } +module One; + +pad::~pad () +{ +} + +int base::getter () const +{ + return b; +} diff --git c/gcc/testsuite/g++.dg/modules/class-6_c.C w/gcc/testsuite/g++.dg/modules/class-6_c.C new file mode 100644 index 00000000000..4d3abf92697 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-6_c.C @@ -0,0 +1,17 @@ +// { dg-additional-options "-fmodules-ts" } +import One; + +int vcall (derived *ptr) +{ + return ptr->getter (); +} + +int main () +{ + derived b (0xfeed); + + if (!(vcall (&b) == 0xfeed)) + return 1; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/class-7_a.C w/gcc/testsuite/g++.dg/modules/class-7_a.C new file mode 100644 index 00000000000..20fd54bb8d5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-7_a.C @@ -0,0 +1,19 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } +export module One; +// { dg-module-cmi "One" } + +export struct base +{ + long long b; + + base (int b_) + :b (b_) + { + } + + base () + :b(99) + { + } +}; diff --git c/gcc/testsuite/g++.dg/modules/class-7_b.C w/gcc/testsuite/g++.dg/modules/class-7_b.C new file mode 100644 index 00000000000..3ed936f0a49 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-7_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts" } +export module Two; +// { dg-module-cmi "Two" } +import One; + +export struct middle : virtual base +{ + long long m; + + middle (int b_, int m_) + : base (b_), m (m_) + { + } +}; diff --git c/gcc/testsuite/g++.dg/modules/class-7_c.C w/gcc/testsuite/g++.dg/modules/class-7_c.C new file mode 100644 index 00000000000..d1f2f56cb93 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-7_c.C @@ -0,0 +1,39 @@ +// { dg-additional-options "-fmodules-ts" } +import One; +import Two; + +struct derived : middle +{ + long long d; + + derived (int b_, int m_, int d_) + : middle (b_, m_), d (d_) + { + } +}; + +int check (derived *d) +{ + if ((char *)&d->b != (char *)&d->d + sizeof (long long)) + return 3; + if ((char *)&d->d != (char *)&d->m + sizeof (long long)) + return 4; + return 0; +} + + +int main () +{ + middle m (1, 2); + + + if (m.b != 1 || m.m != 2) + return 1; + + derived d (1, 2, 3); + + if (d.b != 99 || d.m != 2 || d.d != 3) + return 2; + + return check (&d); +} diff --git c/gcc/testsuite/g++.dg/modules/class-8_a.C w/gcc/testsuite/g++.dg/modules/class-8_a.C new file mode 100644 index 00000000000..53caa5c780d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-8_a.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +class A; + +class B +{ +}; diff --git c/gcc/testsuite/g++.dg/modules/class-8_b.C w/gcc/testsuite/g++.dg/modules/class-8_b.C new file mode 100644 index 00000000000..0bb01ac6a33 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/class-8_b.C @@ -0,0 +1,23 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module} } +module foo; + +// completes class A from interface +class A +{ +}; + +void bill () +{ + A a; +} + +// redeclaration of class B{} from interface +class B; + +void bob () +{ + B b; +} + +// { dg-final { scan-lang-dump {Lazily binding '::A'@'foo' section:} module } } +// { dg-final { scan-lang-dump {Lazily binding '::B'@'foo' section:} module } } diff --git c/gcc/testsuite/g++.dg/modules/clone-1_a.C w/gcc/testsuite/g++.dg/modules/clone-1_a.C new file mode 100644 index 00000000000..43c4bbd8d31 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/clone-1_a.C @@ -0,0 +1,18 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +template +struct basic_string +{ + template basic_string(); +}; + +inline basic_string +to_string () +{ + basic_string __str; + + return __str; +} diff --git c/gcc/testsuite/g++.dg/modules/clone-1_b.C w/gcc/testsuite/g++.dg/modules/clone-1_b.C new file mode 100644 index 00000000000..a013b9bdf28 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/clone-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +void frob () +{ + to_string (); +} diff --git c/gcc/testsuite/g++.dg/modules/concept-1_a.C w/gcc/testsuite/g++.dg/modules/concept-1_a.C new file mode 100644 index 00000000000..1b4d83108cd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-1_a.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -fconcepts" } + +export module foo; +// { dg-module-cmi foo } + +export template +requires (!!sizeof (bool (T{}))) +T f1 (T x) +{ return x; } + diff --git c/gcc/testsuite/g++.dg/modules/concept-1_b.C w/gcc/testsuite/g++.dg/modules/concept-1_b.C new file mode 100644 index 00000000000..d6542e6dc73 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-1_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts -fconcepts" } + +import foo; + +struct X {}; + +void foo (int i, X &x) +{ + f1 (i); // ok + f1 (x); // { dg-error "no match" } +} + +// { dg-regexp {[^\n]*concept-1_a.C:7:[0-9]*: error: invalid cast[^\n]*\n} } diff --git c/gcc/testsuite/g++.dg/modules/concept-2_a.C w/gcc/testsuite/g++.dg/modules/concept-2_a.C new file mode 100644 index 00000000000..b1d477def38 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-2_a.C @@ -0,0 +1,18 @@ +// { dg-additional-options "-fmodules-ts -fconcepts" } + +export module foo; +// { dg-module-cmi foo } + +export template +requires (sizeof (T) == 1) + char f1 (T x) { return 0; } + +export template +requires (sizeof (T) != 1) + int f1 (T x) { return 0; } + +void foo (int i, char c) +{ + static_assert (sizeof (f1 (i)) == sizeof (int)); + static_assert (sizeof (f1 (c)) == sizeof (char)); +} diff --git c/gcc/testsuite/g++.dg/modules/concept-2_b.C w/gcc/testsuite/g++.dg/modules/concept-2_b.C new file mode 100644 index 00000000000..af0ab3ad88e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-2_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -fconcepts" } + +import foo; + +void foo (int i, char c) +{ + static_assert (sizeof (f1 (i)) == sizeof (int)); + static_assert (sizeof (f1 (c)) == sizeof (char)); +} diff --git c/gcc/testsuite/g++.dg/modules/concept-3_a.C w/gcc/testsuite/g++.dg/modules/concept-3_a.C new file mode 100644 index 00000000000..36fc0861428 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-3_a.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts -std=c++2a" } + +export module foo; +// { dg-module-cmi foo } + +namespace foo +{ +export template +concept Addable = requires(_Tp& __t) + { + __t + __t; + }; +} diff --git c/gcc/testsuite/g++.dg/modules/concept-3_b.C w/gcc/testsuite/g++.dg/modules/concept-3_b.C new file mode 100644 index 00000000000..46bfe039956 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-3_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts -std=c++2a" } + +import foo; + +template T Add (T a, T b) +{ + return a + b; +} + +void frob () +{ + Add (1, 2); + Add ((int *)0, (int *)0); // { dg-error "no match" } +} diff --git c/gcc/testsuite/g++.dg/modules/concept-4.H w/gcc/testsuite/g++.dg/modules/concept-4.H new file mode 100644 index 00000000000..66d12017a7c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-4.H @@ -0,0 +1,18 @@ +// { dg-additional-options "-std=c++2a -fmodule-header" } +// { dg-module-cmi {} } + +template +inline constexpr bool disable = false; + +template +concept sized = true; + +template +class TPL +{ +}; + +template +requires (!sized) +inline constexpr bool disable> += true; diff --git c/gcc/testsuite/g++.dg/modules/concept-5.h w/gcc/testsuite/g++.dg/modules/concept-5.h new file mode 100644 index 00000000000..1b049f5f1be --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-5.h @@ -0,0 +1,7 @@ +template +requires (sizeof (T) == 1) +constexpr int f1 (T x) { return 1; } + +template +requires (sizeof (T) != 1) +constexpr int f1 (T x) { return 0; } diff --git c/gcc/testsuite/g++.dg/modules/concept-5_a.H w/gcc/testsuite/g++.dg/modules/concept-5_a.H new file mode 100644 index 00000000000..f38febea861 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-5_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header -fconcepts" } +// { dg-module-cmi {} } + +#include "concept-5.h" diff --git c/gcc/testsuite/g++.dg/modules/concept-5_b.C w/gcc/testsuite/g++.dg/modules/concept-5_b.C new file mode 100644 index 00000000000..6a196d8088d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-5_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -fconcepts -fdump-lang-module-alias" } + +#include "concept-5.h" +import "concept-5_a.H"; + +static_assert (f1 ('a') == 1); +static_assert (f1 (0xa) == 0); + +// { dg-final { scan-lang-dump-times {named merge key \(matched\) template_decl:'::template f1'} 2 module } } +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/concept-6.h w/gcc/testsuite/g++.dg/modules/concept-6.h new file mode 100644 index 00000000000..0e98c98727a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-6.h @@ -0,0 +1,19 @@ + +template +struct Base +{ + Base (const _Callable &) + requires true + {} +}; + +template +struct Derived : Base<_Callable> +{ + using Base<_Callable>::Base; +}; + +template +Derived (_Callable) -> Derived<_Callable>; + +inline Derived all = [] (auto&& __r) {}; diff --git c/gcc/testsuite/g++.dg/modules/concept-6_a.H w/gcc/testsuite/g++.dg/modules/concept-6_a.H new file mode 100644 index 00000000000..e677531c5f0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-6_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header -fconcepts" } +// { dg-module-cmi {} } + +#include "concept-6.h" diff --git c/gcc/testsuite/g++.dg/modules/concept-6_b.C w/gcc/testsuite/g++.dg/modules/concept-6_b.C new file mode 100644 index 00000000000..4c2058d8993 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/concept-6_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fconcepts -fdump-lang-module-alias -fno-module-lazy" } + +#include "concept-6.h" +import "concept-6_a.H"; + +// { dg-final { scan-lang-dump-times {named merge key \(matched\) function_decl:'::Derived<::._anon_0>::__ct '} 6 module } } +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/constrained-partial-1_a.C w/gcc/testsuite/g++.dg/modules/constrained-partial-1_a.C new file mode 100644 index 00000000000..5a5482efc45 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/constrained-partial-1_a.C @@ -0,0 +1,38 @@ +// { dg-additional-options "-fmodules-ts -std=c++20" } + +export module M; +// { dg-module-cmi M } + +export template +struct traits +{ + static constexpr int variant = 0; +}; + +// #2 +template +requires requires { typename T2::element_type; } +struct traits +{ + using type = typename T2::element_type; + static constexpr int variant = 2; +}; + + +// #1 +template +struct traits +{ + using type = T1; + static constexpr int variant = 1; +}; + + +// #3 +template +requires requires { typename T3::value_type; } +struct traits +{ + using type = typename T3::value_type; + static constexpr int variant = 3; +}; diff --git c/gcc/testsuite/g++.dg/modules/constrained-partial-1_b.C w/gcc/testsuite/g++.dg/modules/constrained-partial-1_b.C new file mode 100644 index 00000000000..bbbbab54c0e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/constrained-partial-1_b.C @@ -0,0 +1,31 @@ +// { dg-additional-options "-fmodules-ts -std=c++20" } + +import M; + +struct Variant0 +{ +}; + + +struct Variant2 +{ + using element_type = double; +}; + +struct Variant3 +{ + using value_type = float; +}; + +void f() +{ + using v0 = traits; + using v1 = traits; + using v2 = traits; + using v3 = traits; + + static_assert (v0::variant == 0); + static_assert (v1::variant == 1); + static_assert (v2::variant == 2); + static_assert (v3::variant == 3); +} diff --git c/gcc/testsuite/g++.dg/modules/convop-1_a.C w/gcc/testsuite/g++.dg/modules/convop-1_a.C new file mode 100644 index 00000000000..d0edec85c28 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/convop-1_a.C @@ -0,0 +1,12 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } +export module frob; +// { dg-module-cmi "frob" } + +export struct A +{ + operator int () + { + return 0; + } +}; diff --git c/gcc/testsuite/g++.dg/modules/convop-1_b.C w/gcc/testsuite/g++.dg/modules/convop-1_b.C new file mode 100644 index 00000000000..65350eee208 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/convop-1_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts" } +import frob; + +int main () +{ + A a; + + if (static_cast (a)) + return 1; + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/cpp-1.C w/gcc/testsuite/g++.dg/modules/cpp-1.C new file mode 100644 index 00000000000..2ad9637c8fb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-1.C @@ -0,0 +1,14 @@ +// { dg-do preprocess } + +module bob; +#if 1 +export import stuart; +#else +import kevin; +#endif +import gru; +#define EXPORT +EXPORT import mabel; +int i; + +// { dg-final { scan-file cpp-1.i "cpp-1.C\"\n\n\nmodule bob;\n\nexport import stuart;\n\n\n\nimport gru;\n\n import mabel;\n" } } diff --git c/gcc/testsuite/g++.dg/modules/cpp-2_a.H w/gcc/testsuite/g++.dg/modules/cpp-2_a.H new file mode 100644 index 00000000000..391843fb654 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-2_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } +#define STRING_H +#define NOPE diff --git c/gcc/testsuite/g++.dg/modules/cpp-2_b.H w/gcc/testsuite/g++.dg/modules/cpp-2_b.H new file mode 100644 index 00000000000..34c138d407f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-2_b.H @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +#define STDIO_H +#define think THIS IS STDIO +#define CLOSE ]] diff --git c/gcc/testsuite/g++.dg/modules/cpp-2_c.C w/gcc/testsuite/g++.dg/modules/cpp-2_c.C new file mode 100644 index 00000000000..c6e02b7800a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-2_c.C @@ -0,0 +1,17 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } + +module bob; +#pragma GCC unused +import "./cpp-2_b.H" [[ CLOSE ]]; +import "cpp-2_a.H" [[ CLOSE; +int i; +#ifndef NOPE +import nope; +#endif +think + +// { dg-final { scan-file cpp-2_c.i {cpp-2_c.C"\n\n\n\nmodule bob;\n#pragma GCC unused\nimport "[^\n]*\./cpp-2_b.H" \[\[ CLOSE ]];\nimport "[^\n]*cpp-2_a.H" \[\[ ]];\n} } } +// { dg-final { scan-file cpp-2_c.i "int i;" } } +// { dg-final { scan-file-not cpp-2_c.i "import *nope;" } } +// { dg-final { scan-file cpp-2_c.i "THIS IS STDIO\n" } } diff --git c/gcc/testsuite/g++.dg/modules/cpp-3.C w/gcc/testsuite/g++.dg/modules/cpp-3.C new file mode 100644 index 00000000000..3aa0c6ec5f6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-3.C @@ -0,0 +1,9 @@ +// { dg-do preprocess } + +#define NAME(X) X; + +export module NAME(bob) + +int i; +// { dg-final { scan-file cpp-3.i "\nexport module bob;\n" } } +// { dg-final { scan-file cpp-3.i "\nint i;\n" } } diff --git c/gcc/testsuite/g++.dg/modules/cpp-4.C w/gcc/testsuite/g++.dg/modules/cpp-4.C new file mode 100644 index 00000000000..6c194312311 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-4.C @@ -0,0 +1,10 @@ +// { dg-do preprocess } + +#if 1 +#include "cpp-4.h" +#endif + +// { dg-final { scan-file cpp-4.i "/cpp-4.h\\\" 1" } } +// { dg-final { scan-file cpp-4.i "/cpp-4.C\\\" 2" } } +// { dg-final { scan-file cpp-4.i "import x;\n" } } +// { dg-final { scan-file cpp-4.i "int" } } diff --git c/gcc/testsuite/g++.dg/modules/cpp-4.h w/gcc/testsuite/g++.dg/modules/cpp-4.h new file mode 100644 index 00000000000..aec9547ed46 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-4.h @@ -0,0 +1,4 @@ +#if 1 +import x; +int i; // end here in middle of #if (ok) +#endif diff --git c/gcc/testsuite/g++.dg/modules/cpp-5_a.H w/gcc/testsuite/g++.dg/modules/cpp-5_a.H new file mode 100644 index 00000000000..3941ee817c1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-5_a.H @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +#ifndef AA +#define AA + +#define Q 0 + +#endif diff --git c/gcc/testsuite/g++.dg/modules/cpp-5_b.C w/gcc/testsuite/g++.dg/modules/cpp-5_b.C new file mode 100644 index 00000000000..504e792b9b2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-5_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +// missing semicolon +import "cpp-5_a.H" // { dg-error "expected" } + +int main () +{ +} diff --git c/gcc/testsuite/g++.dg/modules/cpp-5_c.C w/gcc/testsuite/g++.dg/modules/cpp-5_c.C new file mode 100644 index 00000000000..e0a78a516ae --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-5_c.C @@ -0,0 +1,10 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts" } +#define Q 0 +#undef Q + +import "cpp-5_a.H"; + +Q + +// { dg-final { scan-file cpp-5_c.i {\nimport "[^\n]*cpp-5_a.H";\n\n0\n} } } diff --git c/gcc/testsuite/g++.dg/modules/cpp-6_a.H w/gcc/testsuite/g++.dg/modules/cpp-6_a.H new file mode 100644 index 00000000000..0bb1f41629f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-6_a.H @@ -0,0 +1,3 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } +#define bibity cpp-6_b.H diff --git c/gcc/testsuite/g++.dg/modules/cpp-6_b.H w/gcc/testsuite/g++.dg/modules/cpp-6_b.H new file mode 100644 index 00000000000..2d5bcccffb0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-6_b.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#define bobity cpp-6_b diff --git c/gcc/testsuite/g++.dg/modules/cpp-6_c.C w/gcc/testsuite/g++.dg/modules/cpp-6_c.C new file mode 100644 index 00000000000..f9b1e2d68b7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/cpp-6_c.C @@ -0,0 +1,18 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts -isystem [srcdir]" } + +#define empty +#define nop(X) X + +ONE bibity bobity +import ; +TWO bibity bobity +import empty nop(); +THREE bibity bobity +import empty ; +FOUR bibity bobity + +// { dg-final { scan-file cpp-6_c.i {ONE bibity bobity\n} } } +// { dg-final { scan-file cpp-6_c.i {TWO cpp-6_b.H bobity\n} } } +// { dg-final { scan-file cpp-6_c.i {THREE cpp-6_b.H cpp-6_b\n} } } +// { dg-final { scan-file cpp-6_c.i {FOUR cpp-6_b.H cpp-6_b\n} } } diff --git c/gcc/testsuite/g++.dg/modules/debug-1_a.C w/gcc/testsuite/g++.dg/modules/debug-1_a.C new file mode 100644 index 00000000000..b0f1763bb98 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/debug-1_a.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts -g" } + +export module frob; +// { dg-module-cmi frob } + +export struct thingy +{ + virtual void X () + { + thingy w; + } +}; diff --git c/gcc/testsuite/g++.dg/modules/debug-1_b.C w/gcc/testsuite/g++.dg/modules/debug-1_b.C new file mode 100644 index 00000000000..7fca87b6aeb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/debug-1_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts -g" } + +import frob; + +struct thongy : thingy +{ + void X () + { + thongy w; + } +}; diff --git c/gcc/testsuite/g++.dg/modules/decomp-1_a.C w/gcc/testsuite/g++.dg/modules/decomp-1_a.C new file mode 100644 index 00000000000..07506c9956f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/decomp-1_a.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts -std=c++2a" } +export module foo; +// { dg-module-cmi foo } + +struct tuple { int a, b, c;}; + +tuple maker (); + +export inline int bob () +{ + auto [a, b, c] = maker (); + + return a + b + c; +} diff --git c/gcc/testsuite/g++.dg/modules/decomp-1_b.C w/gcc/testsuite/g++.dg/modules/decomp-1_b.C new file mode 100644 index 00000000000..709c333fd58 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/decomp-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -std=c++2a" } +import foo; + +void x () +{ + bob (); +} + diff --git c/gcc/testsuite/g++.dg/modules/deferred-1.h w/gcc/testsuite/g++.dg/modules/deferred-1.h new file mode 100644 index 00000000000..dc0fd782a80 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/deferred-1.h @@ -0,0 +1,12 @@ +template +struct _Iterator +{ +private: + static void mover (const _Iterator &arg = {}) noexcept (noexcept (arg)); + +public: + _Iterator() = default; + + friend void move (const _Iterator &arg2) noexcept (noexcept (mover (arg2))) + {} +}; diff --git c/gcc/testsuite/g++.dg/modules/deferred-1_a.H w/gcc/testsuite/g++.dg/modules/deferred-1_a.H new file mode 100644 index 00000000000..88e6fab6a3a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/deferred-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "deferred-1.h" diff --git c/gcc/testsuite/g++.dg/modules/deferred-1_b.C w/gcc/testsuite/g++.dg/modules/deferred-1_b.C new file mode 100644 index 00000000000..5f75aec0a24 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/deferred-1_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "deferred-1.h" +import "deferred-1_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/dep-1_a.C w/gcc/testsuite/g++.dg/modules/dep-1_a.C new file mode 100644 index 00000000000..766f4368ee6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/dep-1_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -MD" } + +export module m:part; +// { dg-module-cmi m:part } + +// All The Backslashes! +// { dg-final { scan-file dep-1_a.d {\nm\\:part\.c\+\+m: gcm.cache/m-part\.gcm} } } +// { dg-final { scan-file dep-1_a.d {\ngcm.cache/m-part\.gcm:| dep-1_a\.o} } } +// { dg-final { scan-file dep-1_a.d {\n\.PHONY: m\\:part\.c\+\+m} } } diff --git c/gcc/testsuite/g++.dg/modules/dep-1_b.C w/gcc/testsuite/g++.dg/modules/dep-1_b.C new file mode 100644 index 00000000000..138832f709e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/dep-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -MD" } +export module m; +// { dg-module-cmi m } + +export import :part; +// { dg-final { scan-file dep-1_b.d {\ndep-1_b\.s gcm.cache/m\.gcm: m\\:part\.c\+\+m} } } +// { dg-final { scan-file dep-1_b.d {\nm\.c\+\+m: gcm.cache/m\.gcm} } } +// { dg-final { scan-file dep-1_b.d {\n\.PHONY: m\.c\+\+m} } } +// { dg-final { scan-file dep-1_b.d {\ngcm.cache/m\.gcm:| dep-1_b.o} } } +// { dg-final { scan-file dep-1_b.d {\nCXX_IMPORTS \+= m\\:part\.c\+\+m} } } diff --git c/gcc/testsuite/g++.dg/modules/dep-2.C w/gcc/testsuite/g++.dg/modules/dep-2.C new file mode 100644 index 00000000000..5e112c62350 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/dep-2.C @@ -0,0 +1,12 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts -MD" } + +module m:part; +// { dg-module-cmi !m:part } + +// All The Backslashes! +// { dg-final { scan-file dep-2.d {\nm\\:part\.c\+\+m: gcm.cache/m-part\.gcm} } } +// { dg-final { scan-file dep-2.d {\ngcm.cache/m\\:part\.gcm:| dep-2\.o} } } +// { dg-final { scan-file dep-2.d {\n\.PHONY: m\\:part\.c\+\+m} } } + +// { dg-final { scan-file dep-2.i {\nmodule m:part;\n} } } diff --git c/gcc/testsuite/g++.dg/modules/dep-3.C w/gcc/testsuite/g++.dg/modules/dep-3.C new file mode 100644 index 00000000000..f0f883e86e3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/dep-3.C @@ -0,0 +1,9 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts -MD -Mno-modules" } + +module m:part; +// { dg-module-cmi !m:part } + +// All The Backslashes! +// { dg-final { scan-file-not dep-3.d {part\.gcm} } } +// { dg-final { scan-file-not dep-3.d {part\.c\+\+m} } } diff --git c/gcc/testsuite/g++.dg/modules/dir-only-1.C w/gcc/testsuite/g++.dg/modules/dir-only-1.C new file mode 100644 index 00000000000..d035b5f3def --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/dir-only-1.C @@ -0,0 +1,16 @@ +// { dg-do preprocess } +// { dg-additional-options -fdirectives-only } + +#define major NO NOT ME + +#ifdef major +# undef major +#else +# error major not initially defined +#endif + +#ifdef major +# error major still defined +#endif + +// { dg-final { scan-file dir-only-1.i "#undef major\n" } } diff --git c/gcc/testsuite/g++.dg/modules/dir-only-2_a.H w/gcc/testsuite/g++.dg/modules/dir-only-2_a.H new file mode 100644 index 00000000000..3ed0de5d7b1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/dir-only-2_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#define X 1 diff --git c/gcc/testsuite/g++.dg/modules/dir-only-2_b.C w/gcc/testsuite/g++.dg/modules/dir-only-2_b.C new file mode 100644 index 00000000000..0691f76ae36 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/dir-only-2_b.C @@ -0,0 +1,28 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts -fdirectives-only -isystem [srcdir]" } +// a comment +module; // line +frob +export +import foo; // line +import 7; + +im\ +port \ +sing; +// comment +import "dir-only-2_a.H"; +import ; +X +#if !X +#error "no X!" +#endif +export module bob; + +export import q; + +// { dg-final { scan-file dir-only-2_b.i {// a comment\nmodule ;\nfrob} } } +// { dg-final { scan-file dir-only-2_b.i {frob\nexport\nimport foo;\nimport 7;} } } +// { dg-final { scan-file dir-only-2_b.i {import "[^\n]*/dir-only-2_a.H";\nimport "[^\n]*/dir-only-2_a.H";\nX} } } +// { dg-final { scan-file dir-only-2_b.i {export module bob;\n\nexport import q;} } } +// { dg-final { scan-file dir-only-2_b.i {import sing;\n\n\n// comment} } } diff --git c/gcc/testsuite/g++.dg/modules/dir-only-3.C w/gcc/testsuite/g++.dg/modules/dir-only-3.C new file mode 100644 index 00000000000..6e3af8da45d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/dir-only-3.C @@ -0,0 +1,18 @@ +# 0 "dir-only-3.C" +# 1 "" +# 1 "" +# 31 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 + +# 32 "" 2 +# 1 "dir-only-3.C" +// { dg-additional-options {-fmodules-ts -fpreprocessed -fdirectives-only} } +// { dg-module-cmi foo } +module; +#define foo baz +export module foo; + +class import {}; + +import +x; diff --git c/gcc/testsuite/g++.dg/modules/dir-only-4.C w/gcc/testsuite/g++.dg/modules/dir-only-4.C new file mode 100644 index 00000000000..80d6461e81f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/dir-only-4.C @@ -0,0 +1,10 @@ +// { dg-additional-options {-fmodules-ts -fpreprocessed -fdirectives-only} } +// { dg-module-cmi !foo } +module; +#define foo baz +export module foo; + +class import {}; + +import x; // { dg-error "post-module-declaration" } + // { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/dir-recovery.C w/gcc/testsuite/g++.dg/modules/dir-recovery.C new file mode 100644 index 00000000000..90794b96882 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/dir-recovery.C @@ -0,0 +1,9 @@ +// { dg-additional-options {-fmodules-ts -fpreprocessed} } +module; + +; export module Hello; // { dg-error "global module fragment" } +// { dg-error "after a module interface" "" { target *-*-* } .-1 } +// { dg-error "not name a type" "" { target *-*-* } .-2 } +// { dg-message "not recognized as a module control-line" "" { target *-*-* } .-3 } + +void SayHello (); diff --git c/gcc/testsuite/g++.dg/modules/enum-1_a.C w/gcc/testsuite/g++.dg/modules/enum-1_a.C new file mode 100644 index 00000000000..53e2ac88f20 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-1_a.C @@ -0,0 +1,30 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } +export module enUm; +// { dg-module-cmi "enUm" } + +export enum Bill +{ + Zero, + One, + Three = 3 +}; + +export enum class Ben +{ + Zero, + Two = 2, + Three +}; + +export inline Ben func1 () +{ + return Ben::Three; +} + +export inline Ben func2 () +{ + return Ben (4); +} + +// { dg-final { scan-lang-dump-times {Written enum value '::Ben::Three'} 2 module } } diff --git c/gcc/testsuite/g++.dg/modules/enum-1_b.C w/gcc/testsuite/g++.dg/modules/enum-1_b.C new file mode 100644 index 00000000000..4b8c647e1b6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-1_b.C @@ -0,0 +1,22 @@ +// { dg-additional-options "-fmodules-ts" } +import enUm; + +Bill x = Three; +Ben y = Ben::Three; + +int main () +{ + if (x != 3) + return 1; + + if (int (y) != 3) + return 2; + + if (int (func1 ()) != 3) + return 3; + + if (int (func2 ()) != 4) + return 4; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/enum-2_a.C w/gcc/testsuite/g++.dg/modules/enum-2_a.C new file mode 100644 index 00000000000..9e5e42a3b2e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-2_a.C @@ -0,0 +1,21 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +export struct X +{ + enum q + { + frob + }; +}; + +export template struct TPL +{ + enum p + { + u, + v = I + }; +}; diff --git c/gcc/testsuite/g++.dg/modules/enum-2_b.C w/gcc/testsuite/g++.dg/modules/enum-2_b.C new file mode 100644 index 00000000000..4e0aed48806 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-2_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +import foo; + +int i = X::frob; + +int k = TPL<2>::v; + +static_assert (!TPL<1>::u); diff --git c/gcc/testsuite/g++.dg/modules/enum-3_a.C w/gcc/testsuite/g++.dg/modules/enum-3_a.C new file mode 100644 index 00000000000..514bdd012ae --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-3_a.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } +// from https://godbolt.org/beta/z/V45BSw + +export module m0; +// { dg-module-cmi m0 } +namespace m0_ns +{ +template struct s0 { + enum t { a }; +}; +} diff --git c/gcc/testsuite/g++.dg/modules/enum-3_b.C w/gcc/testsuite/g++.dg/modules/enum-3_b.C new file mode 100644 index 00000000000..073611ca559 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-3_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodules-ts } +module m0; + +static_assert (!m0_ns::s0::a); diff --git c/gcc/testsuite/g++.dg/modules/enum-4_a.C w/gcc/testsuite/g++.dg/modules/enum-4_a.C new file mode 100644 index 00000000000..96880b469cd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-4_a.C @@ -0,0 +1,17 @@ +// { dg-additional-options -fmodules-ts } + +export module bob; +// { dg-module-cmi bob } + +export template +struct same +{ + enum { value = 0 }; +}; + +template +struct same +{ + enum { value = 1 }; +}; + diff --git c/gcc/testsuite/g++.dg/modules/enum-4_b.C w/gcc/testsuite/g++.dg/modules/enum-4_b.C new file mode 100644 index 00000000000..0f88fa1ddd2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-4_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } + +import bob; + +static_assert (same::value == 0); +static_assert (same::value == 1); diff --git c/gcc/testsuite/g++.dg/modules/enum-5_a.H w/gcc/testsuite/g++.dg/modules/enum-5_a.H new file mode 100644 index 00000000000..1f2e84faad1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-5_a.H @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +enum +{ + Zero, +}; diff --git c/gcc/testsuite/g++.dg/modules/enum-5_b.C w/gcc/testsuite/g++.dg/modules/enum-5_b.C new file mode 100644 index 00000000000..385c1d35c85 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-5_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodules-ts } +import "enum-5_a.H"; + +int i = Zero; diff --git c/gcc/testsuite/g++.dg/modules/enum-6_a.H w/gcc/testsuite/g++.dg/modules/enum-6_a.H new file mode 100644 index 00000000000..066904686bf --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-6_a.H @@ -0,0 +1,10 @@ +// { dg-module-do run } +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +enum { _S_chunk_size = 7 }; + +template T getter () +{ + return _S_chunk_size; +} diff --git c/gcc/testsuite/g++.dg/modules/enum-6_b.C w/gcc/testsuite/g++.dg/modules/enum-6_b.C new file mode 100644 index 00000000000..04c1ee28b5f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-6_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +import "enum-6_a.H"; + +int main () +{ + return !(getter () == 7); +} diff --git c/gcc/testsuite/g++.dg/modules/enum-7.C w/gcc/testsuite/g++.dg/modules/enum-7.C new file mode 100644 index 00000000000..8cf31a9f804 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-7.C @@ -0,0 +1,20 @@ +// { dg-additional-options -fmodules-ts } + +// ICE getting template info of a function-scope enum + +template void adl (T) {} + +template +void frob (T arg) +{ + enum class case_conv {none}; + + case_conv x = case_conv::none; + + adl (x); +} + +void foo () +{ + frob (1); +} diff --git c/gcc/testsuite/g++.dg/modules/enum-8_a.H w/gcc/testsuite/g++.dg/modules/enum-8_a.H new file mode 100644 index 00000000000..90ccb914341 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-8_a.H @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodule-header } + +enum : char +{ + Foo = 1, +}; diff --git c/gcc/testsuite/g++.dg/modules/enum-8_b.H w/gcc/testsuite/g++.dg/modules/enum-8_b.H new file mode 100644 index 00000000000..021ad173fbd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-8_b.H @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodule-header } + +enum : int +{ + Foo = 2, +}; diff --git c/gcc/testsuite/g++.dg/modules/enum-8_c.C w/gcc/testsuite/g++.dg/modules/enum-8_c.C new file mode 100644 index 00000000000..d14469b533a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-8_c.C @@ -0,0 +1,5 @@ +// { dg-additional-options {-fmodules-ts -fno-module-lazy} } + +export module Char; + +import "enum-8_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/enum-8_d.C w/gcc/testsuite/g++.dg/modules/enum-8_d.C new file mode 100644 index 00000000000..665077325de --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-8_d.C @@ -0,0 +1,11 @@ +// { dg-additional-options {-fmodules-ts -fno-module-lazy -fdump-lang-module-alias} } + +import "enum-8_b.H"; + +import Char; + + +// { dg-final { scan-lang-dump {Read:-1's enum merge key \(new\) type_decl:'#null#'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(new\) const_decl:'::._anon_0@[^\n]*/enum-8_b.H:1::Foo'} module } } +// { dg-final { scan-lang-dump {Read:-1's enum merge key \(new\) type_decl:'#null#'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(new\) const_decl:'::._anon_1@[^\n]*/enum-8_a.H:2::Foo'} module } } diff --git c/gcc/testsuite/g++.dg/modules/enum-bad-1_a.H w/gcc/testsuite/g++.dg/modules/enum-bad-1_a.H new file mode 100644 index 00000000000..2d8a7baf451 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-bad-1_a.H @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodule-header } + +// { dg-module-cmi {} } + +enum ONE {A}; +enum {TWO, THREE}; +enum FOUR {B = 5}; +enum FIVE {C, D, E}; diff --git c/gcc/testsuite/g++.dg/modules/enum-bad-1_b.C w/gcc/testsuite/g++.dg/modules/enum-bad-1_b.C new file mode 100644 index 00000000000..b01cd66a14d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/enum-bad-1_b.C @@ -0,0 +1,26 @@ +// { dg-additional-options {-fmodules-ts} } + +enum ONE {Q}; +enum {TWO, DREI}; +enum FOUR {B = 3}; +enum FIVE {C, D}; + +import "enum-bad-1_a.H"; + + + + + + +ONE one; +// { dg-regexp {In module [^\n]*enum-bad-1_a.H, imported at [^\n]*enum-bad-1_b.C:8:\n[^\n]*enum-bad-1_a.H:5:6: error: definition of 'enum ONE' does not match\n[^\n]*enum-bad-1_b.C:3:6: note: existing definition 'enum ONE'\nIn module [^\n]*enum-bad-1_a.H, imported at [^\n]*enum-bad-1_b.C:8:\n[^\n]*enum-bad-1_a.H:5:11: note: ... this enumerator 'A'\n[^\n]*enum-bad-1_b.C:3:11: note: enumerator 'Q' does not match ...\n[^\n]*enum-bad-1_b.C:15:1: note: during load of binding '::ONE'\n} } + +int i = TWO; +// { dg-regexp {In module [^\n]*enum-bad-1_a.H, imported at [^\n]*enum-bad-1_b.C:8:\n[^\n]*enum-bad-1_a.H:6:6: error: definition of 'enum' does not match\n[^\n]*enum-bad-1_b.C:4:6: note: existing definition 'enum'\nIn module [^\n]*enum-bad-1_a.H, imported at [^\n]*enum-bad-1_b.C:8:\n[^\n]*enum-bad-1_a.H:6:12: note: ... this enumerator 'THREE'\n[^\n]*enum-bad-1_b.C:4:12: note: enumerator 'DREI' does not match ...\n[^\n]*enum-bad-1_b.C:18:9: note: during load of binding '::TWO'\n} } + +FOUR four; +// { dg-regexp {In module [^\n]*enum-bad-1_a.H, imported at [^\n]*enum-bad-1_b.C:8:\n[^\n]*enum-bad-1_a.H:7:6: error: definition of 'enum FOUR' does not match\n[^\n]*enum-bad-1_b.C:5:6: note: existing definition 'enum FOUR'\nIn module [^\n]*enum-bad-1_a.H, imported at [^\n]*enum-bad-1_b.C:8:\n[^\n]*enum-bad-1_a.H:7:12: note: ... this enumerator 'B'\n[^\n]*enum-bad-1_b.C:5:12: note: enumerator 'B' does not match ...\n[^\n]*enum-bad-1_b.C:21:1: note: during load of binding '::FOUR'\n} } + +FIVE five; +// { dg-regexp {In module [^\n]*enum-bad-1_a.H, imported at [^\n]*enum-bad-1_b.C:8:\n[^\n]*enum-bad-1_a.H:8:6: error: definition of 'enum FIVE' does not match\n[^\n]*enum-bad-1_b.C:6:6: note: existing definition 'enum FIVE'\nIn module [^\n]*enum-bad-1_a.H, imported at [^\n]*enum-bad-1_b.C:8:\n[^\n]*enum-bad-1_a.H:8:18: note: additional enumerators beginning with 'E'\n[^\n]*enum-bad-1_b.C:24:1: note: during load of binding '::FIVE'\n} } + diff --git c/gcc/testsuite/g++.dg/modules/err-1_a.C w/gcc/testsuite/g++.dg/modules/err-1_a.C new file mode 100644 index 00000000000..1f7ddecc6ad --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/err-1_a.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } +export module Foo; +// { dg-module-cmi "Foo" } + +export int Frob (int, int, long); +export int Frob (int, long, int); diff --git c/gcc/testsuite/g++.dg/modules/err-1_b.C w/gcc/testsuite/g++.dg/modules/err-1_b.C new file mode 100644 index 00000000000..6d5609c11d6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/err-1_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +export module Bar; +// { dg-module-cmi "Bar" } + +export int Frob (long, int, int); diff --git c/gcc/testsuite/g++.dg/modules/err-1_c.C w/gcc/testsuite/g++.dg/modules/err-1_c.C new file mode 100644 index 00000000000..3a93cc6d18b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/err-1_c.C @@ -0,0 +1,22 @@ +// { dg-additional-options "-fmodules-ts" } +import Foo; + +void One () +{ + Frob (0, 0, 0L); + Frob (0, 0L, 0); + Frob (0L, 0, 0); // { dg-error "ambiguous" } + // { dg-regexp {candidate: 'int Frob@Foo\(int, long int, int\)'} } + // { dg-regexp {candidate: 'int Frob@Foo\(int, int, long int\)'} } +} + +import Bar; + +void Two () +{ + Frob (0L, 0, 0); + Frob (0, 0, 0); // { dg-error "ambiguous" } + // { dg-regexp {candidate: 'int Frob@Foo\(int, long int, int\)'} } + // { dg-regexp {candidate: 'int Frob@Foo\(int, int, long int\)'} } + // { dg-regexp {candidate: 'int Frob@Bar\(long int, int, int\)'} } +} diff --git c/gcc/testsuite/g++.dg/modules/err-1_d.C w/gcc/testsuite/g++.dg/modules/err-1_d.C new file mode 100644 index 00000000000..eb6b4ba7c99 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/err-1_d.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts" } +import Foo; +import Bar; + + +void Three () +{ + Frob (0L, 0, 0); + + Frob (0, 0, 0); // { dg-error "ambiguous" } + // { dg-regexp {candidate: 'int Frob@Foo\(int, long int, int\)'} } + // { dg-regexp {candidate: 'int Frob@Foo\(int, int, long int\)'} } + // { dg-regexp {candidate: 'int Frob@Bar\(long int, int, int\)'} } +} diff --git c/gcc/testsuite/g++.dg/modules/except-1.C w/gcc/testsuite/g++.dg/modules/except-1.C new file mode 100644 index 00000000000..6135c8feb7a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/except-1.C @@ -0,0 +1,18 @@ +// { dg-additional-options -fmodules-ts } +export module bill; +// { dg-module-cmi bill } + +// Make sure no deferred parse exception spec detritus remains + +template +class bob +{ + void frob () noexcept(T::frob ()); + template void frobber (int) noexcept (T::frob ()); +}; + + +class bill +{ + template void frobbest (int) noexcept (U::frob ()); +}; diff --git c/gcc/testsuite/g++.dg/modules/except-2.h w/gcc/testsuite/g++.dg/modules/except-2.h new file mode 100644 index 00000000000..38355ec8b47 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/except-2.h @@ -0,0 +1,42 @@ + +// Causes the CMI to have instantiated a deferred noexept spec that +// the textually included file has not. + +typedef long unsigned int size_t; + + +template +struct integral_constant +{ + static constexpr _Tp value = __v; + typedef integral_constant<_Tp, __v> type; +}; +template +constexpr _Tp integral_constant<_Tp, __v>::value; + +template +struct _Tuple_impl : _Head +{ + _Tuple_impl(_Tuple_impl&& __in) + noexcept (integral_constant(*(_Head *) (0))))>::type::value); +}; + +template +struct __uniq_ptr_impl +{ + __uniq_ptr_impl (__uniq_ptr_impl&& __u) noexcept + : _M_t(static_cast <_Tuple_impl<_Dp> &&>(__u._M_t)) + {} + + _Tuple_impl<_Dp> _M_t; +}; + +struct _Impl_deleter {}; + +typedef __uniq_ptr_impl<_Impl_deleter> up; + +inline void frob (up && p) +{ + up _M_cmpts (static_cast (p)); +} diff --git c/gcc/testsuite/g++.dg/modules/except-2_a.H w/gcc/testsuite/g++.dg/modules/except-2_a.H new file mode 100644 index 00000000000..966169ceae0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/except-2_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "except-2.h" diff --git c/gcc/testsuite/g++.dg/modules/except-2_b.C w/gcc/testsuite/g++.dg/modules/except-2_b.C new file mode 100644 index 00000000000..78ed8f8be9d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/except-2_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } + +#include "except-2.h" +import "except-2_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/except-3.h w/gcc/testsuite/g++.dg/modules/except-3.h new file mode 100644 index 00000000000..8bf0f84d590 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/except-3.h @@ -0,0 +1,24 @@ + +template +struct is_nothrow_move_constructible +{ + static constexpr bool value = false; +}; + +template +struct _Tuple_impl +{ + _Tuple_impl () noexcept(is_nothrow_move_constructible<_Head>::value) + { } +}; + +template +void TPL (_Tuple_impl &) noexcept +{ + _Tuple_impl m; +} + +inline void foo (_Tuple_impl &p) +{ + TPL (p); +} diff --git c/gcc/testsuite/g++.dg/modules/except-3_a.H w/gcc/testsuite/g++.dg/modules/except-3_a.H new file mode 100644 index 00000000000..2f9f00e6222 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/except-3_a.H @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } +// We end up with instantiated noexcept specs in the CMI data matching +// textually loaded fns with uninstantiated ones. Have to propagate, +// not reinstantiate. +#include "except-3.h" diff --git c/gcc/testsuite/g++.dg/modules/except-3_b.C w/gcc/testsuite/g++.dg/modules/except-3_b.C new file mode 100644 index 00000000000..0cb84725b5a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/except-3_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "except-3.h" +import "except-3_a.H"; + +// { dg-final { scan-lang-dump-times {merge key \(new\) function_decl:'::_Tuple_impl::__[cd]t '} 3 module } } +// { dg-final { scan-lang-dump-times {Propagating instantiated noexcept to '::_Tuple_impl::__ct '} 1 module } } diff --git c/gcc/testsuite/g++.dg/modules/exp-xlate-1_a.H w/gcc/testsuite/g++.dg/modules/exp-xlate-1_a.H new file mode 100644 index 00000000000..2079f90c5b4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/exp-xlate-1_a.H @@ -0,0 +1,5 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#define PROTECT 1 +int foo (); diff --git c/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C w/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C new file mode 100644 index 00000000000..3295a6af050 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodules-ts } +export module evil; +// { dg-module-cmi !evil } + +export // { dg-error "not part of following" } +#include "exp-xlate-1_a.H" // { dg-error "must be contiguous" } +// { dg-prune-output {not writing module} } diff --git c/gcc/testsuite/g++.dg/modules/export-1.C w/gcc/testsuite/g++.dg/modules/export-1.C new file mode 100644 index 00000000000..8ca696ebee0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/export-1.C @@ -0,0 +1,22 @@ +// { dg-additional-options -fmodules-ts } + +export module frob; +// { dg-module-cmi !frob } + +int x (); +export int x (); // { dg-error "conflicting exporting declaration" } + +int y; +export extern int y; // { dg-error "conflicting exporting declaration" } + +typedef int z; +export typedef int z; // { dg-error "conflicting exporting declaration" } + +template int f (T); +export template int f (T); // { dg-error "conflicting exporting declaration" } + +// doesn't go via duplicate_decls so we miss this for now +class A; +export class A; // { dg-error "conflicting exporting declaration" "" { xfail *-*-* } } + +// { dg-warning "due to errors" "" { target *-*-* } 0 } diff --git c/gcc/testsuite/g++.dg/modules/extern-tpl-1_a.H w/gcc/testsuite/g++.dg/modules/extern-tpl-1_a.H new file mode 100644 index 00000000000..93afc4eecfe --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/extern-tpl-1_a.H @@ -0,0 +1,23 @@ +// { dg-module-do link } +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template struct TPL +{ + int Source () + { + return I; + } +}; + +extern template class TPL<1>; + +struct Foo +{ + TPL<1> m; + + Foo () {m.Source ();}; + +}; + +static Foo __ioinit; diff --git c/gcc/testsuite/g++.dg/modules/extern-tpl-1_b.C w/gcc/testsuite/g++.dg/modules/extern-tpl-1_b.C new file mode 100644 index 00000000000..f3c0dc483c3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/extern-tpl-1_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options {-fmodules-ts -fmodule-mapper=|@g++-mapper-server} } + +// Have to textually include, because we currently get confused about +// the explicit instantiations and think they conflict +#include "extern-tpl-1_a.H" + +template class TPL<1>; diff --git c/gcc/testsuite/g++.dg/modules/extern-tpl-1_c.C w/gcc/testsuite/g++.dg/modules/extern-tpl-1_c.C new file mode 100644 index 00000000000..d1b6cb6562f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/extern-tpl-1_c.C @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodules-ts } + +import "extern-tpl-1_a.H"; + +int main () +{ +} diff --git c/gcc/testsuite/g++.dg/modules/extern-tpl-2_a.H w/gcc/testsuite/g++.dg/modules/extern-tpl-2_a.H new file mode 100644 index 00000000000..a90d50ec6f8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/extern-tpl-2_a.H @@ -0,0 +1,13 @@ +// { dg-module-do link } +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template struct TPL +{ + int Source () + { + return I; + } +}; + +extern template class TPL<1>; diff --git c/gcc/testsuite/g++.dg/modules/extern-tpl-2_b.H w/gcc/testsuite/g++.dg/modules/extern-tpl-2_b.H new file mode 100644 index 00000000000..5f9875c814a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/extern-tpl-2_b.H @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } +import "extern-tpl-2_a.H"; + +struct Foo +{ + TPL<1> m; + + Foo () {m.Source ();}; + +}; + +static Foo __ioinit; diff --git c/gcc/testsuite/g++.dg/modules/extern-tpl-2_c.C w/gcc/testsuite/g++.dg/modules/extern-tpl-2_c.C new file mode 100644 index 00000000000..b73ec6e8cfc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/extern-tpl-2_c.C @@ -0,0 +1,5 @@ +// { dg-additional-options -fmodules-ts } + +import "extern-tpl-2_a.H"; + +template class TPL<1>; diff --git c/gcc/testsuite/g++.dg/modules/extern-tpl-2_d.C w/gcc/testsuite/g++.dg/modules/extern-tpl-2_d.C new file mode 100644 index 00000000000..25a977fb0ca --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/extern-tpl-2_d.C @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodules-ts } + +import "extern-tpl-2_b.H"; + +int main () +{ +} diff --git c/gcc/testsuite/g++.dg/modules/flag-1_a.C w/gcc/testsuite/g++.dg/modules/flag-1_a.C new file mode 100644 index 00000000000..9f733203067 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/flag-1_a.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -std=c++17" } +export module opt; + +// { dg-module-cmi opt } diff --git c/gcc/testsuite/g++.dg/modules/flag-1_b.C w/gcc/testsuite/g++.dg/modules/flag-1_b.C new file mode 100644 index 00000000000..32bfd82f1a1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/flag-1_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -std=c++2a" } + +// { dg-error "language dialect differs" "" { target *-*-* } 0 } + +import opt; + +// { dg-error "failed to read" "" { target *-*-* } 0 } +// { dg-prune-output "compilation terminated" } +// { dg-prune-output "fatal error" } diff --git c/gcc/testsuite/g++.dg/modules/fn-inline-1_a.C w/gcc/testsuite/g++.dg/modules/fn-inline-1_a.C new file mode 100644 index 00000000000..13e717bb394 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/fn-inline-1_a.C @@ -0,0 +1,21 @@ +// { dg-require-weak "" } +// { dg-additional-options "-fmodules-ts" } +export module bob; +// { dg-module-cmi "bob" } + +export inline int frob (int a) +{ + return -a; +} + +inline int frob (int s, int a) +{ + while (s--) + a <<= 1; + return a; +} + +export int Frob (int s, int a); + +// { dg-final { scan-assembler-not "_Z4frobi:" } } +// { dg-final { scan-assembler-not "_ZW3bobE4frobii:" } } diff --git c/gcc/testsuite/g++.dg/modules/fn-inline-1_b.C w/gcc/testsuite/g++.dg/modules/fn-inline-1_b.C new file mode 100644 index 00000000000..72de1a9a514 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/fn-inline-1_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts" } +module bob; + +int Frob (int n, int a) +{ + return frob (n, a); +} + +// { dg-final { scan-assembler "_ZW3bobE4frobii:" } } +// { dg-final { scan-assembler ".weak(_definition)?\[\t ]*_?_ZW3bobE4frobii" } } +// { dg-final { scan-assembler "_Z4Frobii:" } } diff --git c/gcc/testsuite/g++.dg/modules/fn-inline-1_c.C w/gcc/testsuite/g++.dg/modules/fn-inline-1_c.C new file mode 100644 index 00000000000..55a7aaa26b4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/fn-inline-1_c.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts" } +import bob; + +int main () +{ + if (frob (2) != -2) + return 1; + if (Frob (0, 2) != 2) + return 1; + if (Frob (2, 2) != 8) + return 1; + return 0; +} + +// { dg-final { scan-assembler "_Z4frobi:" } } +// { dg-final { scan-assembler ".weak(_definition)?\[\t ]*_?_Z4frobi" } } diff --git c/gcc/testsuite/g++.dg/modules/freeze-1_a.C w/gcc/testsuite/g++.dg/modules/freeze-1_a.C new file mode 100644 index 00000000000..f05dd3da163 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/freeze-1_a.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +export module bob; +// { dg-module-cmi "bob" } + +export void bob (); diff --git c/gcc/testsuite/g++.dg/modules/freeze-1_b.C w/gcc/testsuite/g++.dg/modules/freeze-1_b.C new file mode 100644 index 00000000000..36d1323c2f3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/freeze-1_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +export module stuart; +// { dg-module-cmi "stuart" } + +export void stuart (); diff --git c/gcc/testsuite/g++.dg/modules/freeze-1_c.C w/gcc/testsuite/g++.dg/modules/freeze-1_c.C new file mode 100644 index 00000000000..3941d30bb33 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/freeze-1_c.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +export module kevin; +// { dg-module-cmi "kevin" } + +export void kevin (); diff --git c/gcc/testsuite/g++.dg/modules/freeze-1_d.C w/gcc/testsuite/g++.dg/modules/freeze-1_d.C new file mode 100644 index 00000000000..faeae148567 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/freeze-1_d.C @@ -0,0 +1,21 @@ +// { dg-additional-options "-fmodules-ts --param lazy-modules=1 -fdump-lang-module" } + +import bob; +import stuart; +import kevin; + +int main () +{ + stuart (); + bob (); + kevin (); + + return 0; +} + +// { dg-final { scan-lang-dump {Freezing 'bob.[^']*'} module } } +// { dg-final { scan-lang-dump {Freezing 'stuart.[^']*'} module } } +// { dg-final { scan-lang-dump {Freezing 'kevin.[^']*'} module } } +// { dg-final { scan-lang-dump {Defrosting 'bob.[^']*'} module } } +// { dg-final { scan-lang-dump {Defrosting 'stuart.[^']*'} module } } +// { dg-final { scan-lang-dump {Defrosting 'kevin.[^']*'} module } } diff --git c/gcc/testsuite/g++.dg/modules/friend-1_a.C w/gcc/testsuite/g++.dg/modules/friend-1_a.C new file mode 100644 index 00000000000..2cfab400be7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/friend-1_a.C @@ -0,0 +1,37 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } + +export module bob; +// { dg-module-cmi bob } + +export struct peeker +{ + static int peek (void *); +}; + + +export class hidey +{ +protected: + int key; + +public: + hidey (int key) :key (key) + { + } + + friend class peeker; +}; + +export class secret : public hidey +{ +public: + secret (int key) : hidey (key) + { + } +}; + +// hidey, peeker & secret are all in different clusters + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::peeker'\n( \[.\]=[^\n]*'\n)* \[.\]=binding '::peeker'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::hidey'\n( \[.\]=[^\n]*'\n)* \[.\]=binding '::hidey'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::secret'\n( \[.\]=[^\n]*'\n)* \[.\]=binding '::secret'} module } } diff --git c/gcc/testsuite/g++.dg/modules/friend-1_b.C w/gcc/testsuite/g++.dg/modules/friend-1_b.C new file mode 100644 index 00000000000..380bbc54b91 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/friend-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +module bob; + +int peeker::peek (void *data) +{ + return reinterpret_cast (data)->key; +} + +// { dg-final { scan-lang-dump {Class '::hidey@bob:.' befriending record_type:'::peeker@bob:.'} module } } diff --git c/gcc/testsuite/g++.dg/modules/friend-1_c.C w/gcc/testsuite/g++.dg/modules/friend-1_c.C new file mode 100644 index 00000000000..2fb2988aa7f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/friend-1_c.C @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodules-ts } + +import bob; + +int main () +{ + secret s (5); + + if (peeker::peek (&s) != 5) + return 1; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/friend-2_a.C w/gcc/testsuite/g++.dg/modules/friend-2_a.C new file mode 100644 index 00000000000..ed329d42bb3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/friend-2_a.C @@ -0,0 +1,16 @@ +// { dg-additional-options -fmodules-ts } + +export module bink; +// { dg-module-cmi bink } + +class pusher +{ + friend void frob (pusher *){} +public: + pusher (){} +}; + +inline void grabber (pusher *p) +{ + frob (p); +} diff --git c/gcc/testsuite/g++.dg/modules/friend-2_b.C w/gcc/testsuite/g++.dg/modules/friend-2_b.C new file mode 100644 index 00000000000..27034c709d5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/friend-2_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options -fmodules-ts } + +module bink; + +struct other {}; + +void f (pusher *p, other *q) +{ + grabber (p); + + frob (p); // ok, found by ADL + + frob (q); // { dg-error "not declared" } +} diff --git c/gcc/testsuite/g++.dg/modules/friend-3.C w/gcc/testsuite/g++.dg/modules/friend-3.C new file mode 100644 index 00000000000..48320eba46a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/friend-3.C @@ -0,0 +1,34 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi !foo } + +namespace bob { + +export void corge (); +void grault (); + +export class Q +{ + friend void foo (); + friend void bar (); + friend void corge (); + friend void grault (); +}; + +export void foo (); +void bar (); // exported + +class R +{ + friend void quux (); + friend void toto (); + friend void corge (); + friend void grault (); +}; + +export void quux (); // { dg-error "conflicting export" } +void toto (); // not exported + +} +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/friend-4_a.C w/gcc/testsuite/g++.dg/modules/friend-4_a.C new file mode 100644 index 00000000000..d9559c6577e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/friend-4_a.C @@ -0,0 +1,33 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +namespace bob { + +export void corge (); +void grault (); + +export class Q +{ + friend void foo (); + friend void bar (); + friend void corge (); + friend void grault (); + friend void xyzzy (Q); +}; + +export void foo (); +void bar (); // exported + +class R +{ + friend void toto (); + friend void corge (); + friend void grault (); + friend void xyzzy (R); +}; + +void toto (); // not exported +export R getR (); +} diff --git c/gcc/testsuite/g++.dg/modules/friend-4_b.C w/gcc/testsuite/g++.dg/modules/friend-4_b.C new file mode 100644 index 00000000000..759dbb5c73b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/friend-4_b.C @@ -0,0 +1,19 @@ +// { dg-additional-options -fmodules-ts } + +import foo; + +using namespace bob; + +void doit () +{ + corge (); + foo (); + bar (); + + grault (); // { dg-error "not declared" } + toto (); // { dg-error "not declared" } + xyzzy (); // { dg-error "not declared" } + + xyzzy (getR); // ADL + xyzzy (Q{}); // ADL +} diff --git c/gcc/testsuite/g++.dg/modules/friend-5_a.C w/gcc/testsuite/g++.dg/modules/friend-5_a.C new file mode 100644 index 00000000000..4d005a876ec --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/friend-5_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } +// From Andrew Sutton + +export module foo; +// { dg-module-cmi foo } +export class A { + friend class B; +}; diff --git c/gcc/testsuite/g++.dg/modules/friend-5_b.C w/gcc/testsuite/g++.dg/modules/friend-5_b.C new file mode 100644 index 00000000000..f043d7a340d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/friend-5_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } +// From Andrew Sutton + +export module bar; +import foo; + +class B { // { dg-error "in a different module" } + B() { object.value = 42; } + A object; +}; +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/gc-1_a.C w/gcc/testsuite/g++.dg/modules/gc-1_a.C new file mode 100644 index 00000000000..5ee20c9e063 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gc-1_a.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts --param ggc-min-expand=0 --param ggc-min-heapsize=0" } + +export module bob; +// { dg-module-cmi bob } + +export int bob (); + +void frink () +{ +} diff --git c/gcc/testsuite/g++.dg/modules/gc-1_b.C w/gcc/testsuite/g++.dg/modules/gc-1_b.C new file mode 100644 index 00000000000..d6ff09caaae --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gc-1_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts" } +export module stuart; + +export int stuart (); diff --git c/gcc/testsuite/g++.dg/modules/gc-1_c.C w/gcc/testsuite/g++.dg/modules/gc-1_c.C new file mode 100644 index 00000000000..289a9995e65 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gc-1_c.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts" } +export module kevin; + +export int kevin (); diff --git c/gcc/testsuite/g++.dg/modules/gc-1_d.C w/gcc/testsuite/g++.dg/modules/gc-1_d.C new file mode 100644 index 00000000000..a27e5d46603 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gc-1_d.C @@ -0,0 +1,28 @@ +// { dg-additional-options "-fmodules-ts --param ggc-min-expand=0 --param ggc-min-heapsize=0" } + +import bob; +import stuart; +import kevin; + +void frob () +{ +} + +void stuart (int); + +void quux () +{ + bob (); +} + +void toto () +{ + stuart (1); +} + +void fido () +{ + stuart (); + kevin (); +} + diff --git c/gcc/testsuite/g++.dg/modules/gc-2.map w/gcc/testsuite/g++.dg/modules/gc-2.map new file mode 100644 index 00000000000..58963bdb32d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gc-2.map @@ -0,0 +1,2 @@ +$root . +frob map-1_a.nms diff --git c/gcc/testsuite/g++.dg/modules/gc-2_a.C w/gcc/testsuite/g++.dg/modules/gc-2_a.C new file mode 100644 index 00000000000..a006fb394cb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gc-2_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts --param ggc-min-expand=0 --param ggc-min-heapsize=0 -fno-module-lazy -fmodule-mapper=[srcdir]/gc-2.map" } +// { dg-additional-files map-1.map } + +// Make sure the module hash table survives GC + +// { dg-module-cmi "=map-1_a.nms" } +export module frob; + +int thing; diff --git c/gcc/testsuite/g++.dg/modules/global-1_a.C w/gcc/testsuite/g++.dg/modules/global-1_a.C new file mode 100644 index 00000000000..68e18e35342 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/global-1_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +module; +# 4 "gmf" 1 +int bar (); +# 6 "" 2 +export module thing; +// { dg-module-cmi "thing" } + +export int baz (); diff --git c/gcc/testsuite/g++.dg/modules/global-1_b.C w/gcc/testsuite/g++.dg/modules/global-1_b.C new file mode 100644 index 00000000000..9a67fb17f20 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/global-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } +import thing; + +void bink () +{ + baz (); + bar (); // { dg-error "not declared" "" } +} diff --git c/gcc/testsuite/g++.dg/modules/gmf-1_a.C w/gcc/testsuite/g++.dg/modules/gmf-1_a.C new file mode 100644 index 00000000000..a340e3fd716 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gmf-1_a.C @@ -0,0 +1,19 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } + +module; + +# 6 "std" 1 +template +class basic_string_view +{ +public: + basic_string_view(const char* __str) noexcept; +}; + +# 14 "" 2 +export module hello; +// { dg-module-cmi hello } +export void greeter (basic_string_view const &name) +{ + +} diff --git c/gcc/testsuite/g++.dg/modules/gmf-1_b.C w/gcc/testsuite/g++.dg/modules/gmf-1_b.C new file mode 100644 index 00000000000..7162d2d1f11 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gmf-1_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +import hello; +int main (void) +{ + greeter ("world"); + return 0; +} + +// { dg-final { scan-lang-dump {Reading definition of '::template basic_string_view@hello:1'} module } } +// { dg-final { scan-lang-dump {Read declaration of '::basic_string_view@hello:1'} module } } +// { dg-final { scan-lang-dump {Read declaration of '::greeter@hello:1'} module } } diff --git c/gcc/testsuite/g++.dg/modules/gmf-2_a.H w/gcc/testsuite/g++.dg/modules/gmf-2_a.H new file mode 100644 index 00000000000..4318b166557 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gmf-2_a.H @@ -0,0 +1,10 @@ +// { dg-module-do run } +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#define MACRO(X) X + +inline int frob (int x) +{ + return x + 2; +} diff --git c/gcc/testsuite/g++.dg/modules/gmf-2_b.C w/gcc/testsuite/g++.dg/modules/gmf-2_b.C new file mode 100644 index 00000000000..15fafd6f78b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gmf-2_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options -fmodules-ts } +module; + +import "gmf-2_a.H"; + +export module Foo; +// { dg-module-cmi Foo } + +export inline int MACRO (fn) (int i) +{ + return frob (i); +} + +export int (MACRO) (int i); diff --git c/gcc/testsuite/g++.dg/modules/gmf-2_c.C w/gcc/testsuite/g++.dg/modules/gmf-2_c.C new file mode 100644 index 00000000000..4b4acc650ea --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gmf-2_c.C @@ -0,0 +1,14 @@ +// { dg-additional-options -fmodules-ts } +module Foo; + +// We see no frob from primary's GMF +int frob (int x) +{ + return fn (-x); +} + +// We see no macro from primary's GMF +int MACRO (int i) +{ + return frob (i); +} diff --git c/gcc/testsuite/g++.dg/modules/gmf-2_d.C w/gcc/testsuite/g++.dg/modules/gmf-2_d.C new file mode 100644 index 00000000000..357c8e81404 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gmf-2_d.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +import Foo; + +// We see no MACRO + +int main () +{ + return !(MACRO (5) == -3); +} diff --git c/gcc/testsuite/g++.dg/modules/gvar_a.C w/gcc/testsuite/g++.dg/modules/gvar_a.C new file mode 100644 index 00000000000..2855b33e250 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gvar_a.C @@ -0,0 +1,15 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +module; +# 3 __FILE__ 1 + +int v1; + +# 9 "" 2 +export module b; +// { dg-module-cmi b } + +export inline auto get () +{ + return v1; +} + diff --git c/gcc/testsuite/g++.dg/modules/gvar_b.C w/gcc/testsuite/g++.dg/modules/gvar_b.C new file mode 100644 index 00000000000..e53e3f2d5c4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/gvar_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +import b; + +int main () +{ + get (); +} diff --git c/gcc/testsuite/g++.dg/modules/hdr-1_a.H w/gcc/testsuite/g++.dg/modules/hdr-1_a.H new file mode 100644 index 00000000000..4ce045b7153 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/hdr-1_a.H @@ -0,0 +1,10 @@ +// { dg-additional-options {-fmodule-header -fdump-lang-module-blocks} } + +// { dg-module-cmi {} } + +class frob; + +template class FROB; + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl declaration '::frob'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl declaration '::template FROB'} module } } diff --git c/gcc/testsuite/g++.dg/modules/hdr-1_b.H w/gcc/testsuite/g++.dg/modules/hdr-1_b.H new file mode 100644 index 00000000000..6817f938e1c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/hdr-1_b.H @@ -0,0 +1,21 @@ +// { dg-additional-options {-fmodule-header -fdump-lang-module-blocks} } + +// { dg-module-cmi {} } + +import "hdr-1_a.H"; + +class frob +{ +public: + int field; +}; + +template +class FROB +{ +public: + static constexpr int val = J; +}; + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::frob'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::template FROB'} module } } diff --git c/gcc/testsuite/g++.dg/modules/hdr-1_c.C w/gcc/testsuite/g++.dg/modules/hdr-1_c.C new file mode 100644 index 00000000000..f8fa0934a58 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/hdr-1_c.C @@ -0,0 +1,14 @@ +// { dg-additional-options {-fmodules-ts} } + +import "hdr-1_b.H"; + +int foo (frob *p) +{ + return p->field; +} + +int foo (FROB<2> *p) +{ + return p->val; +} + diff --git c/gcc/testsuite/g++.dg/modules/hdr-init-1_a.H w/gcc/testsuite/g++.dg/modules/hdr-init-1_a.H new file mode 100644 index 00000000000..25cbf3fc616 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/hdr-init-1_a.H @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +int bob (); + +static int var = bob (); diff --git c/gcc/testsuite/g++.dg/modules/hdr-init-1_b.H w/gcc/testsuite/g++.dg/modules/hdr-init-1_b.H new file mode 100644 index 00000000000..25cbf3fc616 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/hdr-init-1_b.H @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +int bob (); + +static int var = bob (); diff --git c/gcc/testsuite/g++.dg/modules/hdr-init-1_c.C w/gcc/testsuite/g++.dg/modules/hdr-init-1_c.C new file mode 100644 index 00000000000..efcc4854314 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/hdr-init-1_c.C @@ -0,0 +1,24 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-alias} } + +import "hdr-init-1_a.H"; +import "hdr-init-1_b.H"; + +int bob () +{ + static int i; + + return ++i; +} + +int main () +{ + return !(var == 1); +} + +// { dg-final { scan-lang-dump-times {Reading 1 initializers} 2 module } } + +// { dg-final { scan-lang-dump {Read:-1's named merge key \(new\) var_decl:'::var'} module } } +// { dg-final { scan-lang-dump-times {Reading definition var_decl '::var@[^\n]*/hdr-init-1_a.H:1'} 2 module } } + +// { dg-final { scan-lang-dump {Read:-1's named merge key \(matched\) var_decl:'::var'} module } } + diff --git c/gcc/testsuite/g++.dg/modules/horcrux-1_a.C w/gcc/testsuite/g++.dg/modules/horcrux-1_a.C new file mode 100644 index 00000000000..ff548d039ea --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/horcrux-1_a.C @@ -0,0 +1,17 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +template +struct integral_constant +{}; + +template +using __bool_constant = integral_constant; + +template +struct __is_constructible_impl + : public __bool_constant<__is_constructible(_Tp, _Args...)> +{ }; + diff --git c/gcc/testsuite/g++.dg/modules/horcrux-1_b.C w/gcc/testsuite/g++.dg/modules/horcrux-1_b.C new file mode 100644 index 00000000000..842bf413585 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/horcrux-1_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +int main () +{ + __is_constructible_impl x; + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/ice-1.C w/gcc/testsuite/g++.dg/modules/ice-1.C new file mode 100644 index 00000000000..128734d31e6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ice-1.C @@ -0,0 +1,3 @@ +// { dg-additional-options "-fmodules-ts" } +// we ICED on malformed preambles ending at EOF. +import bob // { dg-error "expected" } diff --git c/gcc/testsuite/g++.dg/modules/imp-inline-1_a.C w/gcc/testsuite/g++.dg/modules/imp-inline-1_a.C new file mode 100644 index 00000000000..56bbbdd0456 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-inline-1_a.C @@ -0,0 +1,37 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } + +module; + +# 6 __FILE__ 1 +struct Bob +{ + // inline + static auto frob () + { + } +}; + +# 14 "" 2 + +export module Foo; +// { dg-module-cmi Foo } + +export struct Bill +{ + // not inline + static auto dob () + { + } + static inline auto frob () + { + } +}; + +export inline auto GMF () +{ + return Bob::frob (); +} + +// { dg-final { scan-assembler-not {_ZN3Bob4frobEv:} } } +// { dg-final { scan-assembler-not {_ZN4Bill4frobEv:} } } +// { dg-final { scan-assembler {_ZN4Bill3dobEv:} } } diff --git c/gcc/testsuite/g++.dg/modules/imp-inline-1_b.C w/gcc/testsuite/g++.dg/modules/imp-inline-1_b.C new file mode 100644 index 00000000000..c127f7005a3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-inline-1_b.C @@ -0,0 +1,22 @@ +// { dg-additional-options "-fmodules-ts -fno-inline" } + +import Foo; + +int main () +{ + GMF (); + Bill::dob (); + Bill::frob (); + + return 0; +} + +// { dg-final { scan-assembler {_ZN3Bob4frobEv:} } } +// { dg-final { scan-assembler {_ZN4Bill4frobEv:} } } +// { dg-final { scan-assembler-not {_ZN4Bill3dobEv:} } } +// { dg-final { scan-assembler {_Z3GMFv:} } } + +// { dg-final { scan-assembler {call[ \t]+_?_ZN3Bob4frobEv} { target i?86-*-* x86_64-*-* } } } +// { dg-final { scan-assembler {call[ \t]+_?_Z3GMFv} { target i?86-*-* x86_64-*-* } } } +// { dg-final { scan-assembler {call[ \t]+_?_ZN4Bill3dobEv} { target i?86-*-* x86_64-*-* } } } +// { dg-final { scan-assembler {call[ \t]+_?_ZN4Bill4frobEv} { target i?86-*-* x86_64-*-* } } } diff --git c/gcc/testsuite/g++.dg/modules/imp-member-1_a.C w/gcc/testsuite/g++.dg/modules/imp-member-1_a.C new file mode 100644 index 00000000000..4798ce5fb56 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-member-1_a.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } +export module A; +// { dg-module-cmi A } + +struct M +{ + M (){} +}; + +export struct C +{ + M m; + // lazy implicit ctor +}; + +// { dg-final { scan-lang-dump-not {'::C::__ct '} module } } diff --git c/gcc/testsuite/g++.dg/modules/imp-member-1_b.C w/gcc/testsuite/g++.dg/modules/imp-member-1_b.C new file mode 100644 index 00000000000..849cf3c5be4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-member-1_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } +export module B; +// { dg-module-cmi B } +export import A; + +export struct D +{ + C c; + + // ctor causes C::C to exist, and we need to put it in out CMI + inline D (){} +}; + +// { dg-final { scan-lang-dump {\[.*\]=decl definition '::C@A:1::__ct '} module } } diff --git c/gcc/testsuite/g++.dg/modules/imp-member-1_c.C w/gcc/testsuite/g++.dg/modules/imp-member-1_c.C new file mode 100644 index 00000000000..b354ca8cf98 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-member-1_c.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks-alias" } +import B; + +void fn () +{ + D d; // reads in C::C implicit ctor +} + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(new\) function_decl:'::C@A:.::__ct '\n} module } } +// { dg-final { scan-lang-dump {Adding implicit member '::C@A:.::__ct @B:.} module } } diff --git c/gcc/testsuite/g++.dg/modules/imp-member-1_d.C w/gcc/testsuite/g++.dg/modules/imp-member-1_d.C new file mode 100644 index 00000000000..c7f3158c80d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-member-1_d.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } +import B; + +void fn () +{ + C c; // creates C::C implicitly (we never read B's version) +} + +// { dg-final { scan-lang-dump-not {Read:-1's named merge key \([a-z]*\) function_decl:'::C@A:.::__ct '\n} module } } +// { dg-final { scan-lang-dump-not {Adding implicit member '::C@A:.::__ct @B:.} module } } diff --git c/gcc/testsuite/g++.dg/modules/imp-member-1_e.C w/gcc/testsuite/g++.dg/modules/imp-member-1_e.C new file mode 100644 index 00000000000..b771850583f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-member-1_e.C @@ -0,0 +1,15 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks-alias" } +import B; + +void fn () +{ + C c; // created C::C implicitly +} + +void fn2 () +{ + D d; // merges implicit C::C +} + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) function_decl:'::C@A:.::__ct '\n} module } } +// { dg-final { scan-lang-dump-not {Adding implicit member '::C@A:.::__ct @B:.} module } } diff --git c/gcc/testsuite/g++.dg/modules/imp-member-2_a.C w/gcc/testsuite/g++.dg/modules/imp-member-2_a.C new file mode 100644 index 00000000000..8d4d8396975 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-member-2_a.C @@ -0,0 +1,28 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } +// A more complete imp-member test +export module A; +// { dg-module-cmi A } + +struct M +{ + M (){} + M (M const &){} + M (M &&){} + ~M (){} + M &operator=(M const &){ return *this;} + M &operator=(M &&){ return *this;} +}; + +export struct C +{ + M m; + // lazy implicit ctors, dtors, assop +}; + +// C doesn't contain a lot +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::C'\n \[1\]=decl declaration '::C::C'\n \[2\]=binding '::C'\n} module } } + +// particularly not ... +// { dg-final { scan-lang-dump-not {'::C::__ct '} module } } +// { dg-final { scan-lang-dump-not {'::C::__dt '} module } } +// { dg-final { scan-lang-dump-not {'::C::operator= '} module } } diff --git c/gcc/testsuite/g++.dg/modules/imp-member-2_b.C w/gcc/testsuite/g++.dg/modules/imp-member-2_b.C new file mode 100644 index 00000000000..09795af0093 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-member-2_b.C @@ -0,0 +1,21 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } +export module B; +// { dg-module-cmi B } +export import A; + +export struct D +{ + C c; + + // cause all C's implicit members to exist, and we need to put it in out CMI + inline D (){} + inline D (D const &v) : c (v.c) {} + inline D (D &&v) : c (static_cast (v.c)) {} + inline ~D () {} + inline D &operator= (D const &v) { c = v.c; return *this;} + inline D &operator= (D &&v) { c =static_cast (v.c); return *this;} +}; + +// { dg-final { scan-lang-dump-times {\[0\]=decl definition '::C@A:1::__dt '} 1 module } } +// { dg-final { scan-lang-dump-times {\[0\]=decl definition '::C@A:1::__ct '} 3 module } } +// { dg-final { scan-lang-dump-times {\[0\]=decl definition '::C@A:1::operator='} 2 module } } diff --git c/gcc/testsuite/g++.dg/modules/imp-member-2_c.C w/gcc/testsuite/g++.dg/modules/imp-member-2_c.C new file mode 100644 index 00000000000..bb6b5dee5d9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-member-2_c.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks-alias" } +import B; + +void fn () +{ + D d; // reads in C::C implicits +} + +// { dg-final { scan-lang-dump-times {Read:-[0-9]*'s named merge key \(new\) function_decl:'::C@A:.::__dt '\n} 1 module } } +// { dg-final { scan-lang-dump-times {Adding implicit member '::C@A:.::__dt @B:.} 1 module } } +// { dg-final { scan-lang-dump-times {Read:-[0-9]*'s named merge key \(new\) function_decl:'::C@A:.::__ct '\n} 3 module } } +// { dg-final { scan-lang-dump-times {Adding implicit member '::C@A:.::__ct @B:.} 3 module } } +// { dg-final { scan-lang-dump-times {Read:-[0-9]*'s named merge key \(new\) function_decl:'::C@A:.::operator='\n} 2 module } } +// { dg-final { scan-lang-dump-times {Adding implicit member '::C@A:.::operator=@B:.} 2 module } } diff --git c/gcc/testsuite/g++.dg/modules/imp-member-3.H w/gcc/testsuite/g++.dg/modules/imp-member-3.H new file mode 100644 index 00000000000..d26b13ce0e2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/imp-member-3.H @@ -0,0 +1,16 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +class bad_optional_access +{ +public: + + virtual ~bad_optional_access() noexcept = default; // { dg-bogus "" } +}; + +inline void +__throw_bad_optional_access() +{ + throw bad_optional_access (); +} + diff --git c/gcc/testsuite/g++.dg/modules/import-1_a.C w/gcc/testsuite/g++.dg/modules/import-1_a.C new file mode 100644 index 00000000000..b42153cd08d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/import-1_a.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +export module Bar; +// { dg-module-cmi "Bar" } + +export void Quux (int); diff --git c/gcc/testsuite/g++.dg/modules/import-1_b.C w/gcc/testsuite/g++.dg/modules/import-1_b.C new file mode 100644 index 00000000000..ec15856805e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/import-1_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +export module Baz; +// { dg-module-cmi "Baz" } + +export void Quux (int, int); diff --git c/gcc/testsuite/g++.dg/modules/import-1_c.C w/gcc/testsuite/g++.dg/modules/import-1_c.C new file mode 100644 index 00000000000..b01aa5e9d2b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/import-1_c.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } +// { dg-final { scan-lang-dump "Writing exported import:.->. Baz" "module" } } +// { dg-final { scan-lang-dump "Writing exported import:.->. Bar" "module" } } + +export module Foo; +// { dg-module-cmi "Foo" } + +export import Bar; +export import Baz; + diff --git c/gcc/testsuite/g++.dg/modules/import-1_d.C w/gcc/testsuite/g++.dg/modules/import-1_d.C new file mode 100644 index 00000000000..45e63401f4a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/import-1_d.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +export module Foop; +// { dg-module-cmi "Foop" } + +import Bar; + +export int Thing (); diff --git c/gcc/testsuite/g++.dg/modules/import-1_e.C w/gcc/testsuite/g++.dg/modules/import-1_e.C new file mode 100644 index 00000000000..ae7cce2e4b9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/import-1_e.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +import Foo; + +int main () +{ + Quux (1); // from Bar + Quux (1, 2); // from Baz + return 0; +} + +// { dg-final { scan-lang-dump "Found exported import:1 Bar->1" "module" } } +// { dg-final { scan-lang-dump "Found exported import:2 Baz->2" "module" } } diff --git c/gcc/testsuite/g++.dg/modules/import-1_f.C w/gcc/testsuite/g++.dg/modules/import-1_f.C new file mode 100644 index 00000000000..8dbe9c02dfb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/import-1_f.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } +module Foop; + +int Thing () +{ + Quux (1); // from Bar + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/import-1_g.C w/gcc/testsuite/g++.dg/modules/import-1_g.C new file mode 100644 index 00000000000..556ba80c2c3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/import-1_g.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts" } +import Foop; + +int main () +{ + Thing (); + Quux (1); // { dg-error "not declared" } + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/import-2.C w/gcc/testsuite/g++.dg/modules/import-2.C new file mode 100644 index 00000000000..86a14941a44 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/import-2.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } +// Don't segfault on missing module BMI + +// { dg-module-cmi "!bob" } +// { dg-module-cmi "!bill" } + +import bill; +// { dg-regexp "In module imported at \[^\n]*import-2.C:7:.:\nbill: error: failed to read compiled module: \[^\n]*\n" } + +// { dg-prune-output "fatal error:" } +// { dg-prune-output "compilation terminated" } + diff --git c/gcc/testsuite/g++.dg/modules/inc-xlate-1.map w/gcc/testsuite/g++.dg/modules/inc-xlate-1.map new file mode 100644 index 00000000000..f2429bf3386 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inc-xlate-1.map @@ -0,0 +1,2 @@ + + diff --git c/gcc/testsuite/g++.dg/modules/inc-xlate-1_a.H w/gcc/testsuite/g++.dg/modules/inc-xlate-1_a.H new file mode 100644 index 00000000000..cd906a5b40c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inc-xlate-1_a.H @@ -0,0 +1,15 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#ifndef _STDARG_H +#define _STDARG_H +#ifdef __cplusplus +extern "C" { +#endif + + extern void frob (); + +#ifdef __cplusplus +} +#endif +#endif diff --git c/gcc/testsuite/g++.dg/modules/inc-xlate-1_b.H w/gcc/testsuite/g++.dg/modules/inc-xlate-1_b.H new file mode 100644 index 00000000000..50b27efa7ef --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inc-xlate-1_b.H @@ -0,0 +1,21 @@ +// { dg-do preprocess } +// { dg-additional-options -fmodule-header } + +#ifndef _STDIO_H +#define _STDIO_H +#ifdef __cplusplus +extern "C" { +#endif + + // Yes, inside extern "C" block :( + #include "inc-xlate-1_a.H" + #ifndef _STDARG_H + #error barf + #endif + +#ifdef __cplusplus +} +#endif +#endif + +// { dg-final { scan-file inc-xlate-1_b.i {import "[^\n]*inc-xlate-1_a.H" \[\[__translated\]\];\n} } } diff --git c/gcc/testsuite/g++.dg/modules/inc-xlate-1_c.C w/gcc/testsuite/g++.dg/modules/inc-xlate-1_c.C new file mode 100644 index 00000000000..e1247e645d0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inc-xlate-1_c.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +extern "C" { + #include "inc-xlate-1_a.H" +} + +int main () +{ + frob (); + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C w/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C new file mode 100644 index 00000000000..f33c464bee9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts -fmodule-mapper=|@g++-mapper-server\\ -t\\ [srcdir]/inc-xlate-1.map" } +export module bad; +#include "inc-xlate-1_a.H" // { dg-error "not be include-translated" } + +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/indirect-1_a.C w/gcc/testsuite/g++.dg/modules/indirect-1_a.C new file mode 100644 index 00000000000..f2417172fdc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-1_a.C @@ -0,0 +1,41 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +// indirect references to import. Non-template cases + +export module foo; +// { dg-module-cmi foo } + +namespace foo { + + export int frob (int i) + { + return i; + } + + + export class X + { + int i; + + public: + X (int i) :i(i) { } + operator int () const { return i; } + }; + + export class Y : public virtual X + { + int j; + public: + Y (int i, int j) : X(i), j(j){} + virtual int frob () const; + }; + + int Y::frob () const + { + return *this + j; + } + + export enum Plain {A, B, C, D}; + export enum class Scoped {A, B, C, D}; +} diff --git c/gcc/testsuite/g++.dg/modules/indirect-1_b.C w/gcc/testsuite/g++.dg/modules/indirect-1_b.C new file mode 100644 index 00000000000..c450fa9481c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-1_b.C @@ -0,0 +1,54 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } + +export module bar; +// { dg-module-cmi bar } + +import foo; + +namespace bar +{ + export int frob (int i = foo::frob (0)) + { + return i; + } + + export int quux (int i = foo::X (0) ) + { + return i; + } + + export class Z : public foo::Y + { + public: + Z (int i, int j) : X(i), Y(i, j) + { + } + }; + + export constexpr auto Plain_One (bool b) { return b ? foo::B : foo::C; } + export constexpr auto Scoped_One (bool b) { return b ? foo::Scoped::B + : foo::Scoped::C; } + + export extern auto const Plain_Const_Three = foo::D; + export extern auto const Scoped_Const_Three = foo::Scoped::D; +} + +// { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::frob'@'foo' section:} module } } +// { dg-final { scan-lang-dump-not {namespace:-[0-9]* namespace_decl:'::foo'} module } } +// { dg-final { scan-lang-dump {Wrote import:-[0-9]* function_decl:'::foo@foo:.::frob@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::X'@'foo' section:} module } } +// { dg-final { scan-lang-dump {Wrote import:-[0-9]* type_decl:'::foo@foo:.::X@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::Y'@'foo' section:} module } } +// { dg-final { scan-lang-dump {Wrote import:-[0-9]* type_decl:'::foo@foo:.::Y@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::B'@'foo' section:} module } } +// { dg-final { scan-lang-dump-not {Lazily binding '::foo@foo:.::C@foo:.'@'foo' section:} module } } +// { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::Scoped'@'foo' section:} module } } +// { dg-final { scan-lang-dump-not {Lazily binding '::foo@foo:.::Scoped@foo:.::[ABCD]'@'foo' section:} module } } + +// { dg_final { scan-lang-dump {Wrote named import:-[0-9]* const_decl:'::foo::Plain@\(foo\)::C'@foo} module } } +// { dg_final { scan-lang-dump {Wrote named import:-[0-9]* const_decl:'::foo::Plain@\(foo\)::B'@foo} module } } +// { dg_final { scan-lang-dump {Wrote named import:-[0-9]* const_decl:'::foo::Scoped@\(foo\)::C'@foo} module } } +// { dg_final { scan-lang-dump {Wrote named import:-[0-9]* const_decl:'::foo::Scoped@\(foo\)::B'@foo} module } } diff --git c/gcc/testsuite/g++.dg/modules/indirect-1_c.C w/gcc/testsuite/g++.dg/modules/indirect-1_c.C new file mode 100644 index 00000000000..73d5974c846 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-1_c.C @@ -0,0 +1,49 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } +import bar; + + +int main () +{ + if (bar::frob ()) + return 1; + if (bar::quux ()) + return 2; + + if (bar::Z (1, 2).frob () != 3) + return 3; + + static_assert (bar::Plain_One (true) == 1); + static_assert (bar::Plain_One (false) == 2); + static_assert (int (bar::Scoped_One (true)) == 1); + static_assert (int (bar::Scoped_One (false)) == 2); + + static_assert (bar::Plain_Const_Three == 3); + static_assert (int (bar::Scoped_Const_Three) == 3); + + return 0; +} + +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::frob'@'bar' section:} module } } +// { dg-final { scan-lang-dump {>Loading entity foo\[14\] section:4} module } } +// { dg-final { scan-lang-dump {Named:-[0-9]* namespace_decl:'::foo@foo:1'@foo} module } } +// { dg-final { scan-lang-dump {Imported:-[0-9]* function_decl:'::foo@foo:.::frob@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::quux'@'bar' section:} module } } +// { dg-final { scan-lang-dump {>Loading entity foo\[1\] section:1} module } } +// { dg-final { scan-lang-dump {Imported:-[0-9]* type_decl:'::foo@foo:.::X@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::Z'@'bar' section:} module } } +// { dg-final { scan-lang-dump {>Loading entity foo\[8\] section:2} module } } +// { dg-final { scan-lang-dump {Imported:-[0-9]* type_decl:'::foo@foo:.::Y@foo:.'@foo} module } } +// { dg-final { scan-lang-dump {Read member:-[0-9]* field_decl:'::foo@foo:.::Y@foo:.::_vptr.Y'} module } } +// { dg-final { scan-lang-dump {Imported:-[0-9]* function_decl:'::foo@foo:.::Y@foo:.::frob@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::Plain_One'@'bar' section:} module } } +// { dg-final { scan-lang-dump {>Loading entity foo\[13\] section:3} module } } +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::Scoped_One'@'bar' section} module } } +// { dg-final { scan-lang-dump {>Loading entity foo\[15\] section:5} module } } +// { dg-final { scan-lang-dump-not {Lazily binding '::foo@foo:.::[ABC]'@'foo' section:} module } } +// { dg-final { scan-lang-dump-not {Lazily binding '::foo@foo:.::Scoped@\(foo\)::[ABC]'@'foo' section:} module } } + +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::Plain_Const_Three'@'bar' section:} module } } +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::Scoped_Const_Three'@'bar' section} module } } diff --git c/gcc/testsuite/g++.dg/modules/indirect-2_a.C w/gcc/testsuite/g++.dg/modules/indirect-2_a.C new file mode 100644 index 00000000000..20febb935b1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-2_a.C @@ -0,0 +1,24 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +// indirect references to import, simple templates + +export module foo; +// { dg-module-cmi foo } + +namespace foo +{ + export template int frob () + { + return I; + } + + export template class X + { + int i = I; + + public: + operator int () const { return i; } + }; +} + diff --git c/gcc/testsuite/g++.dg/modules/indirect-2_b.C w/gcc/testsuite/g++.dg/modules/indirect-2_b.C new file mode 100644 index 00000000000..16e060a2210 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-2_b.C @@ -0,0 +1,31 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks-alias-uid" } +export module bar; +// { dg-module-cmi bar } + +import foo; + +namespace bar +{ + export int frob (int i = foo::frob<0> ()) + { + return i; + } + + export int quux (int i = foo::X<0> ()) + { + return i; + } +} + +// { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::frob'@'foo' section} module } } +// { dg-final { scan-lang-dump {Wrote import:-[0-9]* template_decl:'::foo@foo:.::template frob@foo:.'@foo} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s decl spec merge key \(specialization\) function_decl:'::foo@foo:.::frob<0x0>'} module } } + +// { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::X'@'foo' section:} module } } +// { dg-final { scan-lang-dump {Wrote import:-[0-9]* template_decl:'::foo@foo:.::template X@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::X<0x0>'\n \[1\]=specialization declaration '::foo@foo:.::X<0x0>::__conv_op <0x0>'\n \[2\]=specialization declaration '::foo@foo:.::X<0x0>::X<0x0>'\n( \[.\]=[^\n]* '\n)*} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s type spec merge key \(specialization\) type_decl:'::foo@foo:.::X<0x0>'} module } } +// { dg-final { scan-lang-dump {Depset:. specialization entity:. type_decl:'::foo@foo:.::X<0x0>'} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s type spec merge key \(specialization\) type_decl:'::foo@foo:.::X<0x0>'} module } } +// { dg-final { scan-lang-dump {Wrote purview:-[0-9]* type_decl:'::foo@foo:.::X<0x0>'} module } } diff --git c/gcc/testsuite/g++.dg/modules/indirect-2_c.C w/gcc/testsuite/g++.dg/modules/indirect-2_c.C new file mode 100644 index 00000000000..a5cf44ba785 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-2_c.C @@ -0,0 +1,25 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } +import bar; + +int main () +{ + + if (bar::frob ()) + return 1; + + if (bar::quux ()) + return 2; + + return 0; +} + +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::frob'@'bar' section:} module } } +// { dg-final { scan-lang-dump {>Loading entity foo\[4\] section:2} module } } +// { dg-final { scan-lang-dump {Imported:-[0-9]* template_decl:'::foo@foo:.::template frob@foo:.'@foo} module } } +// { dg-final { scan-lang-dump-not {Wrote mergeable} module } } + + +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::quux'@'bar' section:} module } } +// { dg-final { scan-lang-dump {>Loading entity foo\[1\] section:1} module } } +// { dg-final { scan-lang-dump {Imported:-[0-9]* template_decl:'::foo@foo:.::template X@foo:.'@foo} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]* function_decl:'::foo@foo:.::frob<0x0>'} module } } diff --git c/gcc/testsuite/g++.dg/modules/indirect-3_a.C w/gcc/testsuite/g++.dg/modules/indirect-3_a.C new file mode 100644 index 00000000000..fad9ecf1548 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-3_a.C @@ -0,0 +1,23 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +// indirect references to import, template member non-template or +// non-template member of template cases + +export module foo; +// { dg-module-cmi foo } + +namespace foo +{ + export class X + { + public: + template int frob () const { return I; } + }; + + export template class TPL + { + public: + int frob () const { return I; } + }; +} diff --git c/gcc/testsuite/g++.dg/modules/indirect-3_b.C w/gcc/testsuite/g++.dg/modules/indirect-3_b.C new file mode 100644 index 00000000000..5bdfc1d36a8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-3_b.C @@ -0,0 +1,30 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks-uid-alias" } +export module bar; +// { dg-module-cmi bar } + +import foo; + +namespace bar +{ + export int quux (int i = foo::X().frob<0> ()) + { + return i; + } + + export int toto (int i = foo::TPL<0>().frob ()) + { + return i; + } +} + +// { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::X'@'foo' section} module } } +// { dg-final { scan-lang-dump {Wrote import:-[0-9]* template_decl:'::foo@foo:.::X@foo:.::template frob@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::TPL'@'foo' section} module } } +// { dg-final { scan-lang-dump {Wrote import:-[0-9]* template_decl:'::foo@foo:.::template TPL@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::TPL<0x0>'\n \[1\]=specialization declaration '::foo@foo:.::TPL<0x0>::TPL<0x0>'\n( \[.\]=[^\n]* '\n)* \[.\]=decl definition '::foo@foo:.::TPL<0x0>::frob<0x0>'\n} module } } + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::X@foo:.::frob<0x0>'} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s type spec merge key \(specialization\) type_decl:'::foo@foo:.::TPL<0x0>'} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s decl spec merge key \(specialization\) function_decl:'::foo@foo:.::X@foo:.::frob<0x0>'} module } } diff --git c/gcc/testsuite/g++.dg/modules/indirect-3_c.C w/gcc/testsuite/g++.dg/modules/indirect-3_c.C new file mode 100644 index 00000000000..9c5cb230ad2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-3_c.C @@ -0,0 +1,24 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } +import bar; + +int main () +{ + + if (bar::quux ()) + return 1; + + if (bar::toto ()) + return 2; + + return 0; +} + +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::quux'@'bar' section:} module } } +// { dg-final { scan-lang-dump {>Loading entity foo\[5\] section:2} module } } +// { dg-final { scan-lang-dump {Imported:-[0-9]* template_decl:'::foo@foo:.::X@foo:.::template frob@foo:.'@foo} module } } +// { dg-final { scan-lang-dump-not {Instantiation:-[0-9]* function_decl:'::foo::X@foo:.::frob@.()<0x0>'} module } } + +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::toto'@'bar' section:} module } } +// { dg-final { scan-lang-dump {>Loading entity foo\[1\] section:1} module } } +// { dg-final { scan-lang-dump {Imported:-[0-9]* template_decl:'::foo@foo:.::template TPL@foo:.'@foo} module } } +// { dg-final { scan-lang-dump {Reading definition type_decl '::foo@foo:.::TPL@bar:.<0x0>'} module } } diff --git c/gcc/testsuite/g++.dg/modules/indirect-4_a.C w/gcc/testsuite/g++.dg/modules/indirect-4_a.C new file mode 100644 index 00000000000..44f4b660a6e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-4_a.C @@ -0,0 +1,20 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +// indirect references to import, template member of template case + +export module foo; +// { dg-module-cmi foo } + +namespace foo +{ + export template class TPL + { + public: + template int frob () const + { + return I + J; + } + }; +} + diff --git c/gcc/testsuite/g++.dg/modules/indirect-4_b.C w/gcc/testsuite/g++.dg/modules/indirect-4_b.C new file mode 100644 index 00000000000..8c51ce8097b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-4_b.C @@ -0,0 +1,22 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks-alias-uid" } +export module bar; +// { dg-module-cmi bar } + +import foo; + +namespace bar +{ + export int quux (int i = foo::TPL<1> ().frob<2> ()) + { + return i; + } +} + +// { dg-final { scan-lang-dump {Lazily binding '::foo@foo:.::TPL'@'foo' section:} module } } +// { dg-final { scan-lang-dump {Wrote import:-[0-9]* template_decl:'::foo@foo:.::template TPL@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::TPL<0x1>'\n \[1\]=specialization declaration '::foo@foo:.::TPL<0x1>::template frob<#unnamed#>'\n \[2\]=specialization declaration '::foo@foo:.::TPL<0x1>::TPL<0x1>'\n( \[.\]=[^\n]* '\n)*} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::foo@foo:.::TPL<0x1>::frob<0x2>'} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s type spec merge key \(specialization\) type_decl:'::foo@foo:.::TPL<0x1>'} module } } +// { dg-final { scan-lang-dump {Wrote purview:-[0-9]* type_decl:'::foo@foo:.::TPL<0x1>'} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s decl spec merge key \(specialization\) function_decl:'::foo@foo:.::TPL<0x1>::frob<0x2>'} module } } diff --git c/gcc/testsuite/g++.dg/modules/indirect-4_c.C w/gcc/testsuite/g++.dg/modules/indirect-4_c.C new file mode 100644 index 00000000000..7efcc115e71 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/indirect-4_c.C @@ -0,0 +1,17 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid-alias" } +import bar; + +int main () +{ + if (bar::quux () != 3) + return 1; + + return 0; +} + +// { dg-final { scan-lang-dump {Lazily binding '::bar@bar:.::quux'@'bar' section:} module } } +// { dg-final { scan-lang-dump {>Loading entity foo\[2\] section:1} module } } +// { dg-final { scan-lang-dump {Imported:-[0-9]* template_decl:'::foo@foo:.::template TPL@foo:.'@foo} module } } + +// { dg-final { scan-lang-dump {Reading definition function_decl '::foo@foo:.::TPL@bar:.<0x1>::frob@bar:.<0x2>'} module } } +// { dg-final { scan-lang-dump {Reading definition type_decl '::foo@foo:.::TPL@bar:.<0x1>'} module } } diff --git c/gcc/testsuite/g++.dg/modules/inext-1.H w/gcc/testsuite/g++.dg/modules/inext-1.H new file mode 100644 index 00000000000..7708c391618 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inext-1.H @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodule-header -isystem [srcdir] -isystem [srcdir]/sys -fdump-lang-module" } + +#ifndef _PROTECT +#define _PROTECT + +/* We were found on the system inc path, so have been turned into a + system header, so no warning on the following extension. */ +#include_next + +#endif + diff --git c/gcc/testsuite/g++.dg/modules/inh-tmpl-ctor-1.h w/gcc/testsuite/g++.dg/modules/inh-tmpl-ctor-1.h new file mode 100644 index 00000000000..13f769f12d9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inh-tmpl-ctor-1.h @@ -0,0 +1,35 @@ + +template +struct Base +{ + // template constructor + template Base(_Tp *__p, _Del __d); +}; + +template +struct Derived : Base<_Tp> +{ + // Inheriting the template constructor + using Base<_Tp>::Base; +}; + +template +class unique_ptr +{ + Derived<_Tp, int> _M_t; + +public: + // Instantiates Derived::Derived + template unique_ptr(unique_ptr<_Up>&& __u) noexcept + : _M_t ((_Tp *)0, 1) { } +}; + +struct ResultBase { }; +struct ResultDerived : ResultBase { }; + +void Frob (unique_ptr &&__res) ; + +inline void X (unique_ptr &parm) +{ + Frob (static_cast &&> (parm)); +} diff --git c/gcc/testsuite/g++.dg/modules/inh-tmpl-ctor-1_a.H w/gcc/testsuite/g++.dg/modules/inh-tmpl-ctor-1_a.H new file mode 100644 index 00000000000..822221229c1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inh-tmpl-ctor-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "inh-tmpl-ctor-1.h" diff --git c/gcc/testsuite/g++.dg/modules/inh-tmpl-ctor-1_b.C w/gcc/testsuite/g++.dg/modules/inh-tmpl-ctor-1_b.C new file mode 100644 index 00000000000..ae1612c1475 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inh-tmpl-ctor-1_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } + +#include "inh-tmpl-ctor-1.h" +import "inh-tmpl-ctor-1_a.H"; + diff --git c/gcc/testsuite/g++.dg/modules/init-1_a.C w/gcc/testsuite/g++.dg/modules/init-1_a.C new file mode 100644 index 00000000000..b5727d7e3b7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/init-1_a.C @@ -0,0 +1,11 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts -fno-inline" } +export module Foo; +// { dg-module-cmi Foo } + +int Frob (int i) +{ + return i; +} + +export int j = Frob (5); diff --git c/gcc/testsuite/g++.dg/modules/init-1_b.C w/gcc/testsuite/g++.dg/modules/init-1_b.C new file mode 100644 index 00000000000..3d2239f9982 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/init-1_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts -fno-inline" } +import Foo; + +int frob (int j) +{ + return j + 1; +} + +int q = frob (j); + +int main () +{ + return !(q == 6); +} diff --git c/gcc/testsuite/g++.dg/modules/init-2_a.C w/gcc/testsuite/g++.dg/modules/init-2_a.C new file mode 100644 index 00000000000..1e9093ef13d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/init-2_a.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts -fno-inline" } +export module Foo; +// { dg-module-cmi Foo } + +// { dg-final { scan-assembler {_ZGIW3FooEv:} } } diff --git c/gcc/testsuite/g++.dg/modules/init-2_b.C w/gcc/testsuite/g++.dg/modules/init-2_b.C new file mode 100644 index 00000000000..b9692ca862c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/init-2_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -fno-inline" } +export module Bar; +// { dg-module-cmi Bar } + +import Foo; + +// { dg-final { scan-assembler {_?_ZGIW3BarEv:} } } +// { dg-final { scan-assembler {call[ \t]+_?_ZGIW3FooEv} { target i?86-*-* x86_64-*-* } } } diff --git c/gcc/testsuite/g++.dg/modules/init-2_c.C w/gcc/testsuite/g++.dg/modules/init-2_c.C new file mode 100644 index 00000000000..c1fa5d80cd4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/init-2_c.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -fno-inline" } + +import Foo; +import Bar; + +// We know Bar imports Foo, so only call Bar's Global Init +// { dg-final { scan-assembler {call[ \t]+_?_ZGIW3BarEv} { target i?86-*-* x86_64-*-* } } } +// { dg-final { scan-assembler-not {call[ \t]+_?_ZGIW3FooEv} { target i?86-*-* x86_64-*-* } } } diff --git c/gcc/testsuite/g++.dg/modules/inst-1_a.C w/gcc/testsuite/g++.dg/modules/inst-1_a.C new file mode 100644 index 00000000000..e1d438b5c19 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inst-1_a.C @@ -0,0 +1,42 @@ +// { dg-module-do run } +// { dg-additional-options {-fmodules-ts -fdump-lang-module-graph-blocks} } + +export module foo; +// { dg-module-cmi foo } + +int i_baz (int i) +{ + return i; +} + +inline int baz (int i) +{ + return i_baz (i); +} + +int f_baz (float f) +{ + return int (f); +} + +inline int baz (float f) +{ + return f_baz (f); +} + +export template +int foo (T t) +{ + return baz (t); +} + +export inline void user () +{ + foo (1); + foo (1.0f); +} + +// { dg-final { scan-lang-dump {Depending definition function_decl:'::foo'} module } } +// { dg-final { scan-lang-dump {Depending definition function_decl:'::foo'} module } } +// { dg-final { scan-lang-dump {\[0\]=specialization definition '::foo'} module } } +// { dg-final { scan-lang-dump {\[0\]=specialization definition '::foo'} module } } diff --git c/gcc/testsuite/g++.dg/modules/inst-1_b.C w/gcc/testsuite/g++.dg/modules/inst-1_b.C new file mode 100644 index 00000000000..08a92aef63a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inst-1_b.C @@ -0,0 +1,16 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-uid-alias} } +import foo; + +int main () +{ + user (); + foo ('a'); // new inst + foo (1); // find foo's inst + return 0; +} + +// { dg-final { scan-lang-dump {Reading definition function_decl '::foo@foo:.'} module } } +// { dg-final { scan-lang-dump {Reading definition function_decl '::foo@foo:.'} module } } + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(unique\) function_decl:'::baz'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(unique\) function_decl:'::baz'} module } } diff --git c/gcc/testsuite/g++.dg/modules/inst-2_a.C w/gcc/testsuite/g++.dg/modules/inst-2_a.C new file mode 100644 index 00000000000..40d6229d4b3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inst-2_a.C @@ -0,0 +1,26 @@ +// { dg-module-do run } +// { dg-additional-options {-fmodules-ts -fdump-lang-module-blocks-uid-alias} } + +export module foo; +// { dg-module-cmi foo } + +inline int baz (int i) +{ + return i; +} + +export template +inline int foo (T t) +{ + return baz (t); +} + +export inline void user () +{ + foo (1); +} + +// { dg-final { scan-lang-dump {\[0\]=specialization definition '::foo'} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s named merge key \(decl\) function_decl:'::baz'} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s decl spec merge key \(specialization\) function_decl:'::foo'} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s decl spec merge key \(specialization\) function_decl:'::foo'} module } } diff --git c/gcc/testsuite/g++.dg/modules/inst-2_b.C w/gcc/testsuite/g++.dg/modules/inst-2_b.C new file mode 100644 index 00000000000..3e918bcfb31 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inst-2_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-uid-alias} } +import foo; + +int main () +{ + foo (1); // read pending inst + user (); // + foo (1); // reuse inst + return 0; +} + +// { dg-final { scan-lang-dump {Reading 1 pending specializations} module } } + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s decl spec merge key \(new\) function_decl:'::foo'} module } } diff --git c/gcc/testsuite/g++.dg/modules/inst-3_a.C w/gcc/testsuite/g++.dg/modules/inst-3_a.C new file mode 100644 index 00000000000..3305805b5b7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inst-3_a.C @@ -0,0 +1,21 @@ +// { dg-module-do run } +// { dg-additional-options {-fmodules-ts -fdump-lang-module-graph-blocks-alias} } + +export module foo; +// { dg-module-cmi foo } + +export template struct TPL +{ + T m; +}; + +export inline int user (int i) +{ + TPL x; + x.m = i; + return x.m; +} + +// { dg-final { scan-lang-dump {Cluster members:\n( \[.\]=[^\n]*'\n)* \[.\]=specialization definition '::TPL'\n \[.\]=specialization declaration '::TPL::TPL'\n} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s type spec merge key \(specialization\) type_decl:'::TPL'} module } } +// { dg-final { scan-lang-dump {Depset:. specialization entity:. type_decl:'::TPL'} module } } diff --git c/gcc/testsuite/g++.dg/modules/inst-3_b.C w/gcc/testsuite/g++.dg/modules/inst-3_b.C new file mode 100644 index 00000000000..80a9946587c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inst-3_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-alias-uid} } +import foo; + +int main () +{ + if (user (1) != 1) + return 1; + TPL x; + TPL y; + return 0; +} + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s type spec merge key \(new\) type_decl:'::TPL'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s decl spec merge key \(new\) type_decl:'::template TPL@foo:.::TPL'} module } } diff --git c/gcc/testsuite/g++.dg/modules/inst-4_a.C w/gcc/testsuite/g++.dg/modules/inst-4_a.C new file mode 100644 index 00000000000..e7435ec2ee1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inst-4_a.C @@ -0,0 +1,20 @@ +// { dg-module-do run } +// { dg-additional-options {-fmodules-ts -fdump-lang-module-graph-blocks-alias} } + +export module foo; +// { dg-module-cmi foo } + +export template struct TPL +{ + T m; +}; + +export inline int user (int i) +{ + TPL x; + x.m = i; + return x.m; +} + +// { dg-final { scan-lang-dump {Specialization '::TPL' entity:. keyed to foo\[.\] '::template TPL'} module } } +// { dg-final { scan-lang-dump {Specialization '::TPL::TPL' entity:. keyed to foo\[.\] '::template TPL::template TPL'} module } } diff --git c/gcc/testsuite/g++.dg/modules/inst-4_b.C w/gcc/testsuite/g++.dg/modules/inst-4_b.C new file mode 100644 index 00000000000..c83e1c1437c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inst-4_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-alias-uid} } +import foo; + +int main () +{ + TPL x; + if (user (1) != 1) + return 1; + return 0; +} + +// { dg-final { scan-lang-dump {Reading 1 pending specializations keyed to foo\[.\] '::template TPL@foo:.'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s type spec merge key \(new\) type_decl:'::TPL'} module } } diff --git c/gcc/testsuite/g++.dg/modules/inst-5_a.H w/gcc/testsuite/g++.dg/modules/inst-5_a.H new file mode 100644 index 00000000000..46d9432fe7c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inst-5_a.H @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template int fn () +{ + return I; +} + +inline void g () +{ + fn<1> (); // instantiation gets emitted +} diff --git c/gcc/testsuite/g++.dg/modules/inst-5_b.C w/gcc/testsuite/g++.dg/modules/inst-5_b.C new file mode 100644 index 00000000000..7cc94c83be3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/inst-5_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } + +template int fn () +{ + return I; +} + +void f () +{ + fn<1> (); +} + +import "inst-5_a.H"; +// no longer need to instantate diff --git c/gcc/testsuite/g++.dg/modules/internal-1.C w/gcc/testsuite/g++.dg/modules/internal-1.C new file mode 100644 index 00000000000..45d3bf06f28 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/internal-1.C @@ -0,0 +1,21 @@ +// { dg-additional-options "-fmodules-ts" } + +export module frob; // { dg-error "failed to write" } +// { dg-module-cmi !frob } + +namespace { +// We shouldn't be complaining about members of internal linkage +// entities +class X // { dg-bogus "internal linkage" "" { xfail *-*-* } } +{ // { dg-bogus "internal linkage" "" { xfail *-*-* } } +}; + +} + +static int frob () +{ + return 1; +} + +export int f (int = frob ()); // { dg-error "references internal linkage" } +int goof (X &); // { dg-error "references internal linkage" } diff --git c/gcc/testsuite/g++.dg/modules/internal-2_a.H w/gcc/testsuite/g++.dg/modules/internal-2_a.H new file mode 100644 index 00000000000..4b530bdc72c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/internal-2_a.H @@ -0,0 +1,10 @@ +// { dg-module-do run } +// { dg-additional-options {-fmodule-header -fdump-lang-module-blocks} } +// { dg-module-cmi {} } + +static int bob (int x) +{ + return x; +} + +// { dg-final { scan-lang-dump { Cluster members:\n \[0\]=decl definition '::bob'\n \[1\]=binding '::bob'} module } } diff --git c/gcc/testsuite/g++.dg/modules/internal-2_b.H w/gcc/testsuite/g++.dg/modules/internal-2_b.H new file mode 100644 index 00000000000..cdcbe77e0d1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/internal-2_b.H @@ -0,0 +1,7 @@ +// { dg-additional-options {-fmodule-header} } +// { dg-module-cmi {} } + +static int bob (int x) +{ + return x; +} diff --git c/gcc/testsuite/g++.dg/modules/internal-2_c.C w/gcc/testsuite/g++.dg/modules/internal-2_c.C new file mode 100644 index 00000000000..c0bc46dd8a0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/internal-2_c.C @@ -0,0 +1,12 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-alias} } + +import "internal-2_a.H"; +import "internal-2_b.H"; + +int main () +{ + bob (2); +} + +// { dg-final { scan-lang-dump { Read:-1's named merge key \(new\) function_decl:'::bob'} module } } +// { dg-final { scan-lang-dump { Read:-1's named merge key \(matched\) function_decl:'::bob'} module } } diff --git c/gcc/testsuite/g++.dg/modules/isalnum.H w/gcc/testsuite/g++.dg/modules/isalnum.H new file mode 100644 index 00000000000..2fac358d7fd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/isalnum.H @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +extern "C" +{ + extern int isalnum (int) __attribute__ ((__nothrow__, __leaf__)); +} + +namespace std +{ +using ::isalnum; +} diff --git c/gcc/testsuite/g++.dg/modules/keyword-1_a.C w/gcc/testsuite/g++.dg/modules/keyword-1_a.C new file mode 100644 index 00000000000..190f5739072 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/keyword-1_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } + +export module bob; +// { dg-module-cmi bob } + +export struct import {}; +export ::import *a; +export ::import (b); diff --git c/gcc/testsuite/g++.dg/modules/keyword-1_b.C w/gcc/testsuite/g++.dg/modules/keyword-1_b.C new file mode 100644 index 00000000000..24a5b5b448c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/keyword-1_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } + +import bob; + +::import (d); // not import +import (e); // not import + +void foo () +{ + void *c = a; + void *e = &b; +} + diff --git c/gcc/testsuite/g++.dg/modules/lambda-1_a.C w/gcc/testsuite/g++.dg/modules/lambda-1_a.C new file mode 100644 index 00000000000..1b97187da96 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-1_a.C @@ -0,0 +1,15 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } +export module tom.riddle; +// { dg-module-cmi tom.riddle } + +export inline auto One (int a) +{ + return [=] (int b) { return a + b; }; +} + +// Look Ma! this isn't inline! +export auto Two (int a) +{ + return [=] (int b) { return a * b; }; +} diff --git c/gcc/testsuite/g++.dg/modules/lambda-1_b.C w/gcc/testsuite/g++.dg/modules/lambda-1_b.C new file mode 100644 index 00000000000..af213492153 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-1_b.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts" } +import tom.riddle; + +int main () +{ + auto one = One (2); + + if (one (1) != 3) + return 1; + + auto two = Two (3); + if (two (2) != 6) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/lambda-2.h w/gcc/testsuite/g++.dg/modules/lambda-2.h new file mode 100644 index 00000000000..3433686b36d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-2.h @@ -0,0 +1,2 @@ +// The lambda is attached to 'all', and should be merged keyed by that. +inline constexpr auto all = [] () {}; diff --git c/gcc/testsuite/g++.dg/modules/lambda-2_a.H w/gcc/testsuite/g++.dg/modules/lambda-2_a.H new file mode 100644 index 00000000000..79401209049 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-2_a.H @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodule-header -fdump-lang-module-alias" } +// { dg-module-cmi {} } + +#include "lambda-2.h" + +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s attached merge key \(decl\) type_decl:'::._anon_0'} module } } +// { dg-final { scan-lang-dump {Written -[0-9]*\[0\] attached decl '::._anon_0'} module } } diff --git c/gcc/testsuite/g++.dg/modules/lambda-2_b.C w/gcc/testsuite/g++.dg/modules/lambda-2_b.C new file mode 100644 index 00000000000..56ec9e3aa30 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-2_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } +// Not an ODR violation! +#include "lambda-2.h" +import "lambda-2_a.H"; + +// { dg-bogus "conflicting" "not an odr violation" } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s attached merge key \(matched\) type_decl:'#null#'} module } } +// { dg-final { scan-lang-dump {Read -[0-9]*\[0\] matched attached decl '::._anon_0'} module } } diff --git c/gcc/testsuite/g++.dg/modules/lambda-2_c.C w/gcc/testsuite/g++.dg/modules/lambda-2_c.C new file mode 100644 index 00000000000..c626b9dd850 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-2_c.C @@ -0,0 +1,3 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +import "lambda-2_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/lambda-3.h w/gcc/testsuite/g++.dg/modules/lambda-3.h new file mode 100644 index 00000000000..8f60a824ab4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-3.h @@ -0,0 +1,5 @@ + +template inline constexpr auto tmpl = [] {return I;}; + +inline const auto tpl_1 = tmpl<1>; +inline const auto tpl_2 = tmpl<2>; diff --git c/gcc/testsuite/g++.dg/modules/lambda-3_a.H w/gcc/testsuite/g++.dg/modules/lambda-3_a.H new file mode 100644 index 00000000000..171a2637969 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-3_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header -fdump-lang-module-alias" } +// { dg-module-cmi {} } + +#include "lambda-3.h" diff --git c/gcc/testsuite/g++.dg/modules/lambda-3_b.C w/gcc/testsuite/g++.dg/modules/lambda-3_b.C new file mode 100644 index 00000000000..25a418bb44a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-3_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "lambda-3.h" +import "lambda-3_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump {Read -1\[0\] matched attached decl '::template ._anon_0<#unnamed#>'} module } } +// { dg-final { scan-lang-dump {Read -1\[0\] matched attached decl '::._anon_2'} module } } +// { dg-final { scan-lang-dump {Read -1\[0\] matched attached decl '::._anon_1'} module } } diff --git c/gcc/testsuite/g++.dg/modules/lambda-3_c.C w/gcc/testsuite/g++.dg/modules/lambda-3_c.C new file mode 100644 index 00000000000..69efa50be0a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-3_c.C @@ -0,0 +1,3 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +import "lambda-3_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/lambda-4.h w/gcc/testsuite/g++.dg/modules/lambda-4.h new file mode 100644 index 00000000000..fe9a06bbd0a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-4.h @@ -0,0 +1,2 @@ + +inline void (*all) (int) = [] (auto) {}; diff --git c/gcc/testsuite/g++.dg/modules/lambda-4_a.H w/gcc/testsuite/g++.dg/modules/lambda-4_a.H new file mode 100644 index 00000000000..738ea8b4e36 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-4_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header -fdump-lang-module-alias" } +// { dg-module-cmi {} } + +#include "lambda-4.h" diff --git c/gcc/testsuite/g++.dg/modules/lambda-4_b.C w/gcc/testsuite/g++.dg/modules/lambda-4_b.C new file mode 100644 index 00000000000..772045d9efb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lambda-4_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "lambda-4.h" +import "lambda-4_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump {named merge key \(matched\) template_decl:'::._anon_0::template _FUN'} module } } +// { dg-final { scan-lang-dump {named merge key \(matched\) template_decl:'::._anon_0::template __conv_op '} module } } diff --git c/gcc/testsuite/g++.dg/modules/lang-1_a.H w/gcc/testsuite/g++.dg/modules/lang-1_a.H new file mode 100644 index 00000000000..8131d3ffe79 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lang-1_a.H @@ -0,0 +1,15 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +extern "C" +{ + int cfunc (); +} + +extern "C++" +{ + int cxxfunc (); +} + + + diff --git c/gcc/testsuite/g++.dg/modules/lang-1_b.C w/gcc/testsuite/g++.dg/modules/lang-1_b.C new file mode 100644 index 00000000000..0db144c8ff3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lang-1_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +extern "C" +{ + import "lang-1_a.H"; +} + +extern "C" int cfunc (int); // { dg-error "conflicting declaration" } +extern "C" int cxxfunc (int); diff --git c/gcc/testsuite/g++.dg/modules/lang-1_c.C w/gcc/testsuite/g++.dg/modules/lang-1_c.C new file mode 100644 index 00000000000..e3b939df373 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lang-1_c.C @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodules-ts } + +extern "C++" +{ + import "lang-1_a.H"; +} + +extern "C" +import "lang-1_a.H"; // { dg-error "cannot appear directly" } + +extern "C" int cfunc (int); // { dg-error "conflicting declaration" } +extern "C" int cxxfunc (int); diff --git c/gcc/testsuite/g++.dg/modules/lang-2_a.C w/gcc/testsuite/g++.dg/modules/lang-2_a.C new file mode 100644 index 00000000000..a3bbe727168 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lang-2_a.C @@ -0,0 +1,3 @@ +// { dg-additional-options -fmodules-ts } +export module foo; +// { dg-module-cmi foo } diff --git c/gcc/testsuite/g++.dg/modules/lang-2_b.C w/gcc/testsuite/g++.dg/modules/lang-2_b.C new file mode 100644 index 00000000000..0a7a0d2f8e5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lang-2_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } + +extern "C" +{ + import foo; // { dg-warning "inside language-linkage" } +} +extern "C++" +{ + import foo; // { dg-warning "inside language-linkage" } +} diff --git c/gcc/testsuite/g++.dg/modules/late-ret-1.H w/gcc/testsuite/g++.dg/modules/late-ret-1.H new file mode 100644 index 00000000000..fb73e51c0ee --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/late-ret-1.H @@ -0,0 +1,16 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template +struct reverse_iterator +{ + _Iterator base() const; +}; + +template +reverse_iterator<_Iterator> __make_reverse_iterator (_Iterator __i); + +template +auto __niter_base(reverse_iterator<_Iterator> __it) + -> decltype (__make_reverse_iterator(__niter_base(__it.base()))) +{ return __make_reverse_iterator(__niter_base(__it.base())); } diff --git c/gcc/testsuite/g++.dg/modules/late-ret-2_a.H w/gcc/testsuite/g++.dg/modules/late-ret-2_a.H new file mode 100644 index 00000000000..0ff435ff0fa --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/late-ret-2_a.H @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodule-header -fdump-lang-module-blocks" } +// { dg-module-cmi {} } + +template struct TPL {operator T () const {return 0;}}; + +template +auto Foo (T *arg) + -> TPL {return TPL ();} + +template +auto Bar (T *arg) + -> TPL ; + +// { dg-final { scan-lang-dump { Cluster members:\n \[0\]=decl definition '::template Foo'\n \[1\]=specialization declaration '::TPL<#null#>'\n \[2\]=binding '::Foo'\n} module } } diff --git c/gcc/testsuite/g++.dg/modules/late-ret-2_b.H w/gcc/testsuite/g++.dg/modules/late-ret-2_b.H new file mode 100644 index 00000000000..80b83f40e3c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/late-ret-2_b.H @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template struct TPL {operator T () const {return 0;}}; + +template +auto Foo (T *arg) + -> TPL {return TPL ();} + +// Deliberately different to 2_a's Bar +template +auto Bar (T *arg) + -> TPL ; diff --git c/gcc/testsuite/g++.dg/modules/late-ret-2_c.C w/gcc/testsuite/g++.dg/modules/late-ret-2_c.C new file mode 100644 index 00000000000..c5898fb236e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/late-ret-2_c.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-alias" } + +import "late-ret-2_a.H"; +import "late-ret-2_b.H"; + +int main () +{ + int *p = 0; + int j = Foo (p); + + Bar (p); // { dg-error "ambiguous" } + + return 0; +} + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) template_decl:'::template Foo'\n Deduping '::template Foo@[^\n]*/late-ret-2_a.H:.'\n} module } } diff --git c/gcc/testsuite/g++.dg/modules/late-ret-3_a.H w/gcc/testsuite/g++.dg/modules/late-ret-3_a.H new file mode 100644 index 00000000000..54f95db0456 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/late-ret-3_a.H @@ -0,0 +1,20 @@ +// { dg-additional-options "-fmodule-header -fdump-lang-module-blocks" } +// { dg-module-cmi {} } + +template struct TPL_1 { using type = T;}; + +template struct TPL_2 { using type = int;}; + +template using TPL_3 = typename TPL_2::type; + +template +auto Foo (const A& arg) + -> TPL_3::type> + {return 3;} + +template +auto Bar (const A& arg) + -> TPL_3::type> + {return 3;} + +// { dg-final { scan-lang-dump { Cluster members:\n \[0\]=decl definition '::template Foo'\n \[1\]=specialization declaration '::TPL_1<#null#>'\n \[2\]=specialization declaration '::TPL_3<::TPL_1<#null#>::type>'\n \[3\]=specialization declaration '::TPL_2<::TPL_1<#null#>::type>'\n \[4\]=binding '::Foo'\n} module } } diff --git c/gcc/testsuite/g++.dg/modules/late-ret-3_b.H w/gcc/testsuite/g++.dg/modules/late-ret-3_b.H new file mode 100644 index 00000000000..2ec63ac65f0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/late-ret-3_b.H @@ -0,0 +1,20 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template struct TPL_1 { using type = T;}; + +template struct TPL_2 { using type = int;}; + +template using TPL_3 = typename TPL_2::type; + +template +auto Foo (const A& arg) + -> TPL_3::type> + {return 3;} + +// Deliberately different to 3_a's Bar +template +auto Bar (const A& arg) + -> TPL_3::type> + {return 3;} + diff --git c/gcc/testsuite/g++.dg/modules/late-ret-3_c.C w/gcc/testsuite/g++.dg/modules/late-ret-3_c.C new file mode 100644 index 00000000000..fae956542f9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/late-ret-3_c.C @@ -0,0 +1,22 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-alias" } + +import "late-ret-3_a.H"; +import "late-ret-3_b.H"; + +struct Arg +{ + int type; +}; + +int main () +{ + Arg arg; + + int j = Foo (arg); + + Bar (arg); // { dg-error "ambiguous" } + + return 0; +} + +// { dg-final { scan-lang-dump {Read:-1's named merge key \(matched\) template_decl:'::template Foo'\n Deduping '::template Foo@[^\n]*/late-ret-3_a.H:.'\n} module } } diff --git c/gcc/testsuite/g++.dg/modules/lazy-1_a.C w/gcc/testsuite/g++.dg/modules/lazy-1_a.C new file mode 100644 index 00000000000..0f7c7c9173c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lazy-1_a.C @@ -0,0 +1,19 @@ +// { dg-additional-options "-fmodules-ts" } +export module foo; +// { dg-module-cmi "foo" } + +export int bar () +{ + return 1; +} + +export int baz () +{ + return 2; +} + +export int quux () +{ + return 3; +} + diff --git c/gcc/testsuite/g++.dg/modules/lazy-1_b.C w/gcc/testsuite/g++.dg/modules/lazy-1_b.C new file mode 100644 index 00000000000..af213d59a3d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/lazy-1_b.C @@ -0,0 +1,21 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +// Check some lazy loading + +import foo; + +int main () +{ + bar (); + + baz (); + + return 0; +} + +// { dg-final { scan-lang-dump {Lazily binding '::bar'@'foo' section} "module" } } +// { dg-final { scan-lang-dump {Lazily binding '::baz'@'foo' section} "module" } } +// quux is not referenced, so never loaded +// { dg-final { scan-lang-dump {Bindings '::quux' section} "module" } } +// { dg-final { scan-lang-dump-not {Lazily binding '::quux'@'foo' section} "module" } } +// { dg-final { scan-lang-dump-not {Read -[0-9]* function_decl:'::quux'} "module" } } diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-1_a.H w/gcc/testsuite/g++.dg/modules/leg-merge-1_a.H new file mode 100644 index 00000000000..e7506b50874 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-1_a.H @@ -0,0 +1,5 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +int bob (int); diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-1_b.H w/gcc/testsuite/g++.dg/modules/leg-merge-1_b.H new file mode 100644 index 00000000000..07ae824d358 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-1_b.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +int bob (int); diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-1_c.C w/gcc/testsuite/g++.dg/modules/leg-merge-1_c.C new file mode 100644 index 00000000000..b204d54ccc5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-1_c.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +import "leg-merge-1_a.H"; +import "leg-merge-1_b.H"; + +int main () +{ + return bob (0); +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-1_d.C w/gcc/testsuite/g++.dg/modules/leg-merge-1_d.C new file mode 100644 index 00000000000..f7854524d45 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-1_d.C @@ -0,0 +1,4 @@ +int bob (int i) +{ + return i; +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-2_a.H w/gcc/testsuite/g++.dg/modules/leg-merge-2_a.H new file mode 100644 index 00000000000..d891c8966ce --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-2_a.H @@ -0,0 +1,5 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +class X; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-2_b.H w/gcc/testsuite/g++.dg/modules/leg-merge-2_b.H new file mode 100644 index 00000000000..b9be14d83d5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-2_b.H @@ -0,0 +1,5 @@ +// { dg-module-do link } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +class X; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-2_c.C w/gcc/testsuite/g++.dg/modules/leg-merge-2_c.C new file mode 100644 index 00000000000..d5a4da9bd63 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-2_c.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +import "leg-merge-2_a.H"; +import "leg-merge-2_b.H"; + +int main () +{ + X *ptr = 0; + + return ptr != 0; +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-3_a.H w/gcc/testsuite/g++.dg/modules/leg-merge-3_a.H new file mode 100644 index 00000000000..9142340bc84 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-3_a.H @@ -0,0 +1,5 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +extern int bob; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-3_b.H w/gcc/testsuite/g++.dg/modules/leg-merge-3_b.H new file mode 100644 index 00000000000..2ba847b6601 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-3_b.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +extern int bob; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-3_c.C w/gcc/testsuite/g++.dg/modules/leg-merge-3_c.C new file mode 100644 index 00000000000..c6b71b57c22 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-3_c.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +import "leg-merge-3_a.H"; +import "leg-merge-3_b.H"; + +int main () +{ + return !(bob == 17); +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-3_d.C w/gcc/testsuite/g++.dg/modules/leg-merge-3_d.C new file mode 100644 index 00000000000..36f028c4f04 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-3_d.C @@ -0,0 +1 @@ +int bob = 17; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-4_a.H w/gcc/testsuite/g++.dg/modules/leg-merge-4_a.H new file mode 100644 index 00000000000..9c61ea2356f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-4_a.H @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +extern int bob; +void frob (); +class X; + +extern int ok; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-4_b.H w/gcc/testsuite/g++.dg/modules/leg-merge-4_b.H new file mode 100644 index 00000000000..09c895fdcd4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-4_b.H @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +extern float bob; +int frob (); +union X; + +int ok (); diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-4_c.C w/gcc/testsuite/g++.dg/modules/leg-merge-4_c.C new file mode 100644 index 00000000000..f1b1aeb5b37 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-4_c.C @@ -0,0 +1,18 @@ +// { dg-additional-options -fmodules-ts } + +import "leg-merge-4_a.H"; +import "leg-merge-4_b.H"; + +void foo () +{ + 2[0]; // { dg-error "" } + bob = 5; + frob (); + X *p; +} + +// { dg-regexp "\nIn module \[^\n]*leg-merge-4_b.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_b.H:4:\[0-9]*: error: conflicting global module declaration 'float bob'\nIn module \[^\n]*leg-merge-4_a.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_a.H:4:\[0-9]*: note: existing declaration 'int bob'\n\[^\n]*leg-merge-4_c.C:9:\[0-9]*: note: during load of binding '::bob'$" } + +// { dg-regexp "\nIn module \[^\n]*leg-merge-4_b.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_b.H:5:\[0-9]*: error: conflicting global module declaration 'int frob\\(\\)'\nIn module \[^\n]*leg-merge-4_a.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_a.H:5:\[0-9]*: note: existing declaration 'void frob\\(\\)'\n\[^\n]*leg-merge-4_c.C:10:\[0-9]*: note: during load of binding '::frob'$" } + +// { dg-regexp "In module \[^\n]*leg-merge-4_b.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_b.H:6:\[0-9]*: error: conflicting global module declaration 'union X'\nIn module \[^\n]*leg-merge-4_a.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_a.H:6:\[0-9]*: note: existing declaration 'class X'\n\[^\n]*leg-merge-4_c.C:11:\[0-9]*: note: during load of binding '::X'$" } diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-5_a.H w/gcc/testsuite/g++.dg/modules/leg-merge-5_a.H new file mode 100644 index 00000000000..ba92696ed1f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-5_a.H @@ -0,0 +1,9 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +inline int bob (int x) +{ + return x; +} + diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-5_b.H w/gcc/testsuite/g++.dg/modules/leg-merge-5_b.H new file mode 100644 index 00000000000..b77efb3f85e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-5_b.H @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +inline int bob (int x) +{ + return x; +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-5_c.C w/gcc/testsuite/g++.dg/modules/leg-merge-5_c.C new file mode 100644 index 00000000000..cd1e757b340 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-5_c.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +import "leg-merge-5_a.H"; +import "leg-merge-5_b.H"; + +int main () +{ + return bob (0); +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-6_a.H w/gcc/testsuite/g++.dg/modules/leg-merge-6_a.H new file mode 100644 index 00000000000..64e8d2861be --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-6_a.H @@ -0,0 +1,10 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +struct X +{ + int m; + X (int m) :m(m) {} + operator int () const { return m; } +}; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-6_b.H w/gcc/testsuite/g++.dg/modules/leg-merge-6_b.H new file mode 100644 index 00000000000..2179d9002b1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-6_b.H @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +struct X +{ + int m; + X (int m) :m(m) {} + operator int () const { return m; } +}; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-6_c.C w/gcc/testsuite/g++.dg/modules/leg-merge-6_c.C new file mode 100644 index 00000000000..dddd88cb0ff --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-6_c.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +import "leg-merge-6_a.H"; +import "leg-merge-6_b.H"; + +int main () +{ + X x (75); + + return !(int (x) == 75); +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-7_a.H w/gcc/testsuite/g++.dg/modules/leg-merge-7_a.H new file mode 100644 index 00000000000..d8ea85943f0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-7_a.H @@ -0,0 +1,8 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +template int foo (int i) +{ + return I == i; +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-7_b.H w/gcc/testsuite/g++.dg/modules/leg-merge-7_b.H new file mode 100644 index 00000000000..9ec045be468 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-7_b.H @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +template int foo (int i) +{ + return I == i; +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-7_c.C w/gcc/testsuite/g++.dg/modules/leg-merge-7_c.C new file mode 100644 index 00000000000..0efdc0af1f4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-7_c.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +import "leg-merge-7_a.H"; +import "leg-merge-7_b.H"; + +int main () +{ + return !foo<2> (2); +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-8_a.H w/gcc/testsuite/g++.dg/modules/leg-merge-8_a.H new file mode 100644 index 00000000000..ad9a2f9e543 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-8_a.H @@ -0,0 +1,13 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +template struct Tpl +{ + int i; + Tpl () : i (I){} + operator int () const + { + return i; + } +}; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-8_b.H w/gcc/testsuite/g++.dg/modules/leg-merge-8_b.H new file mode 100644 index 00000000000..845984c480c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-8_b.H @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +template struct Tpl +{ + int i; + Tpl () : i (I){} + operator int () const + { + return i; + } +}; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-8_c.C w/gcc/testsuite/g++.dg/modules/leg-merge-8_c.C new file mode 100644 index 00000000000..fa67db99a80 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-8_c.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +import "leg-merge-8_a.H"; +import "leg-merge-8_b.H"; + +int main () +{ + Tpl<1> one; + + return !(one == 1); +} diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-9_a.H w/gcc/testsuite/g++.dg/modules/leg-merge-9_a.H new file mode 100644 index 00000000000..518ecbd11f7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-9_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +typedef int X; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-9_b.H w/gcc/testsuite/g++.dg/modules/leg-merge-9_b.H new file mode 100644 index 00000000000..518ecbd11f7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-9_b.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +typedef int X; diff --git c/gcc/testsuite/g++.dg/modules/leg-merge-9_c.C w/gcc/testsuite/g++.dg/modules/leg-merge-9_c.C new file mode 100644 index 00000000000..3c75dc8162c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/leg-merge-9_c.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } +import "leg-merge-9_a.H"; +import "leg-merge-9_b.H"; + +X an_int; + diff --git c/gcc/testsuite/g++.dg/modules/legacy-1_a.H w/gcc/testsuite/g++.dg/modules/legacy-1_a.H new file mode 100644 index 00000000000..3ab0856bcbc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-1_a.H @@ -0,0 +1,10 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +#ifndef HEADER_H +#define HEADER_H + +int frob (int); + +#endif diff --git c/gcc/testsuite/g++.dg/modules/legacy-1_b.C w/gcc/testsuite/g++.dg/modules/legacy-1_b.C new file mode 100644 index 00000000000..f758e3a3f8b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-1_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } + +int frob (int a) +{ + return a + 2; +} diff --git c/gcc/testsuite/g++.dg/modules/legacy-1_c.C w/gcc/testsuite/g++.dg/modules/legacy-1_c.C new file mode 100644 index 00000000000..277231c87ab --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-1_c.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +import "legacy-1_a.H"; + +int main () +{ + return !(frob (-2) == 0); +} diff --git c/gcc/testsuite/g++.dg/modules/legacy-2.h w/gcc/testsuite/g++.dg/modules/legacy-2.h new file mode 100644 index 00000000000..2bac5c74b84 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-2.h @@ -0,0 +1 @@ +#define FROB frob diff --git c/gcc/testsuite/g++.dg/modules/legacy-2.map w/gcc/testsuite/g++.dg/modules/legacy-2.map new file mode 100644 index 00000000000..9de5392f593 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-2.map @@ -0,0 +1 @@ +"legacy-2_a.H" diff --git c/gcc/testsuite/g++.dg/modules/legacy-2_a.H w/gcc/testsuite/g++.dg/modules/legacy-2_a.H new file mode 100644 index 00000000000..076bdbe4689 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-2_a.H @@ -0,0 +1,8 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +// this is a legacy header + +int frob (int); + diff --git c/gcc/testsuite/g++.dg/modules/legacy-2_b.H w/gcc/testsuite/g++.dg/modules/legacy-2_b.H new file mode 100644 index 00000000000..0d4ae071158 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-2_b.H @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodule-header -fmodule-mapper=|@g++-mapper-server\\ -mt\\ $srcdir/g++.dg/modules/legacy-2.map" } +// { dg-module-cmi {} } + +#define frob FROB + +// this should be diverted, if it isn't the above #define will break us +#include "legacy-2_a.H" +int move (int X = __LINE__); // Capture __LINE__ in a non-definition + +// this should not be diverted +#include "legacy-2.h" + + diff --git c/gcc/testsuite/g++.dg/modules/legacy-2_c.C w/gcc/testsuite/g++.dg/modules/legacy-2_c.C new file mode 100644 index 00000000000..ff31bd41297 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-2_c.C @@ -0,0 +1,8 @@ +int frob (int a) +{ + return a * 2; +} +int move (int a) +{ + return a; +} diff --git c/gcc/testsuite/g++.dg/modules/legacy-2_d.C w/gcc/testsuite/g++.dg/modules/legacy-2_d.C new file mode 100644 index 00000000000..5384d321128 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-2_d.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } + +import "legacy-2_b.H"; + +int main () +{ + if (frob (2) != 4) + return 1; + /* Check line number is not disturbed. */ + if (move () != 8) + return 2; + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/legacy-3.h w/gcc/testsuite/g++.dg/modules/legacy-3.h new file mode 100644 index 00000000000..2bac5c74b84 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-3.h @@ -0,0 +1 @@ +#define FROB frob diff --git c/gcc/testsuite/g++.dg/modules/legacy-3_a.H w/gcc/testsuite/g++.dg/modules/legacy-3_a.H new file mode 100644 index 00000000000..74d275536f9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-3_a.H @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +// this is a legacy header + +int frob (int); + diff --git c/gcc/testsuite/g++.dg/modules/legacy-3_b.H w/gcc/testsuite/g++.dg/modules/legacy-3_b.H new file mode 100644 index 00000000000..3bf819db661 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-3_b.H @@ -0,0 +1,16 @@ +// { dg-do preprocess } +// { dg-additional-options -fmodule-header } + +#define frob FROB + +// Enough blank lines to force a line sync before the legacy import + +// this should be diverted, if it isn't the above #define will break us +#include "legacy-3_a.H" +int move (int X = __LINE__); // Capture __LINE__ in a non-definition + +// this should not be diverted +#include "legacy-3.h" + +// { dg-final { scan-file legacy-3_b.i {\n# 9 "[^\n]*legacy-3_b.H"\nimport "[^\n]*legacy-3_a.H" \[\[__translated\]\];\nint move \(int X = 10\);\n} } } + diff --git c/gcc/testsuite/g++.dg/modules/legacy-3_c.H w/gcc/testsuite/g++.dg/modules/legacy-3_c.H new file mode 100644 index 00000000000..56b81722997 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-3_c.H @@ -0,0 +1,25 @@ +// { dg-do preprocess } +// { dg-additional-options -fmodule-header } + +#define frob FROB + +// this should be translated, if it isn't the above #define will break +// us +MARK1 __LINE__ +#include "legacy-3_a.H" +MARK2 __LINE__ +int move (int X = __LINE__); // Capture __LINE__ in a non-definition +// this should also be translated, but elided too +MARK2 __LINE__ +#include "legacy-3_a.H" +MARK3 __LINE__ + +// this should not be translated +#include "legacy-3.h" + +// { dg-final { scan-file legacy-3_c.i {MARK1 8\nimport "[^\n]*legacy-3_a.H" \[\[__translated\]\];\nMARK2 10\n} } } +// We should have stopped. +// { dg-final { scan-file legacy-3_c.i {move} } } +// { dg-final { scan-file legacy-3_c.i {MARK2 13\n\nMARK3 15\n} } } +// { dg-final { scan-file-not legacy-3_c.i {# [^\n]*legacy-3_a.H} } } +// { dg-final { scan-file legacy-3_c.i {# [^\n]*legacy-3.h} } } diff --git c/gcc/testsuite/g++.dg/modules/legacy-6.map w/gcc/testsuite/g++.dg/modules/legacy-6.map new file mode 100644 index 00000000000..8199bf9e190 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-6.map @@ -0,0 +1,2 @@ +./legacy-6_a.H +./legacy-6_b.H diff --git c/gcc/testsuite/g++.dg/modules/legacy-6_a.H w/gcc/testsuite/g++.dg/modules/legacy-6_a.H new file mode 100644 index 00000000000..7d7e970cdff --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-6_a.H @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +// this is a legacy user header + +int frob (int); diff --git c/gcc/testsuite/g++.dg/modules/legacy-6_b.H w/gcc/testsuite/g++.dg/modules/legacy-6_b.H new file mode 100644 index 00000000000..1a52d42f613 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-6_b.H @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +// this is a legacy user header + +int frob (float); diff --git c/gcc/testsuite/g++.dg/modules/legacy-6_c.C w/gcc/testsuite/g++.dg/modules/legacy-6_c.C new file mode 100644 index 00000000000..0b5bd7f2eb2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-6_c.C @@ -0,0 +1,8 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts -fmodule-mapper=|@g++-mapper-server\\ -mt\\ [srcdir]/legacy-6.map" } + +#include "legacy-6_a.H" +#include "legacy-6_b.H" +int i; + +// { dg-final { scan-file legacy-6_c.i {import "[^\n]*legacy-6_a.H" \[\[__translated\]\];\nimport "[^\n]*legacy-6_b.H" \[\[__translated\]\];\nint i;} } } diff --git c/gcc/testsuite/g++.dg/modules/legacy-6_d.C w/gcc/testsuite/g++.dg/modules/legacy-6_d.C new file mode 100644 index 00000000000..58ca21dbccf --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-6_d.C @@ -0,0 +1,9 @@ +// { dg-do preprocess } +// { dg-additional-options "-fmodules-ts -fmodule-mapper=|@g++-mapper-server\\ -mt\\ [srcdir]/legacy-6.map" } + +#include "legacy-6_a.H" +int i; +#include "legacy-6_b.H" + +// { dg-final { scan-file legacy-6_d.i {import "[^\n]*legacy-6_a.H" \[\[__translated\]\];\nint i;} } } +// { dg-final { scan-file legacy-6_d.i {int i;\nimport "[^\n]*legacy-6_b.H" \[\[__translated\]\];\n} } } diff --git c/gcc/testsuite/g++.dg/modules/legacy-6_e.C w/gcc/testsuite/g++.dg/modules/legacy-6_e.C new file mode 100644 index 00000000000..9d4dd9218dd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-6_e.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodule-mapper=|@mapper-server\\ -f\\ [srcdir]/legacy-6.map" } + +#include "legacy-6_a.H" +#include "legacy-6_b.H" +int i; diff --git c/gcc/testsuite/g++.dg/modules/legacy-6_f.C w/gcc/testsuite/g++.dg/modules/legacy-6_f.C new file mode 100644 index 00000000000..c15eadec6da --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-6_f.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodule-mapper=|@mapper-server\\ -f\\ [srcdir]/legacy-6.map" } + +#include "legacy-6_a.H" +int i; +#include "legacy-6_b.H" + diff --git c/gcc/testsuite/g++.dg/modules/legacy-7_a.H w/gcc/testsuite/g++.dg/modules/legacy-7_a.H new file mode 100644 index 00000000000..49578a929e8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-7_a.H @@ -0,0 +1,6 @@ +// { dg-additional-options "-std=c++2a -fmodule-header" } +// { dg-module-cmi {} } + +#define throw(...) /* { dg-warning "-:not exporting" } */ \ + noexcept(__VA_OPT__(false)) + diff --git c/gcc/testsuite/g++.dg/modules/legacy-7_b.C w/gcc/testsuite/g++.dg/modules/legacy-7_b.C new file mode 100644 index 00000000000..d78f45c2128 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-7_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -std=c++2a" } + +import "legacy-7_a.H"; + +#ifdef throw +#error barf +#endif + diff --git c/gcc/testsuite/g++.dg/modules/legacy-8_a.H w/gcc/testsuite/g++.dg/modules/legacy-8_a.H new file mode 100644 index 00000000000..a30cd880d9f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-8_a.H @@ -0,0 +1,5 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +int sqr (int); diff --git c/gcc/testsuite/g++.dg/modules/legacy-8_b.H w/gcc/testsuite/g++.dg/modules/legacy-8_b.H new file mode 100644 index 00000000000..62366e11a0f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-8_b.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +float sqr (float); diff --git c/gcc/testsuite/g++.dg/modules/legacy-8_c.C w/gcc/testsuite/g++.dg/modules/legacy-8_c.C new file mode 100644 index 00000000000..88300b28582 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-8_c.C @@ -0,0 +1,13 @@ +#include "legacy-8_a.H" +#include "legacy-8_a.H" + +int sqr (int a) +{ + return a * a; +} + + +float sqr (float a) +{ + return a * a; +} diff --git c/gcc/testsuite/g++.dg/modules/legacy-8_d.C w/gcc/testsuite/g++.dg/modules/legacy-8_d.C new file mode 100644 index 00000000000..85377d9f7d5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-8_d.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts" } +export module foo; +// { dg-module-cmi foo } + +import "legacy-8_a.H"; +import "legacy-8_b.H"; + +export inline int Sqr (int a) +{ + return sqr (a); +} + +export inline float Sqr (float a) +{ + return sqr (a); +} diff --git c/gcc/testsuite/g++.dg/modules/legacy-8_e.C w/gcc/testsuite/g++.dg/modules/legacy-8_e.C new file mode 100644 index 00000000000..afeb19a94c7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/legacy-8_e.C @@ -0,0 +1,18 @@ +// { dg-additional-options "-fmodules-ts" } + +import foo; + +int main () +{ + int (*ifp) (int) = Sqr; + float (*ffp) (float) = Sqr; + + if (ifp (2) != 4) + return 1; + + // Comparing these two floats is ok + if (ffp (2.0f) != 4.0f) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/libfn-1_a.C w/gcc/testsuite/g++.dg/modules/libfn-1_a.C new file mode 100644 index 00000000000..a8a8ee8ea71 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/libfn-1_a.C @@ -0,0 +1,16 @@ +// { dg-additional-options -fmodules-ts } +// Make sure we're not confused by an imported declaration of a +// library fn +export module foo; +// { dg-module-cmi foo } + +export inline void thrower () +{ + try + { + throw 1; + } + catch (...) + { + } +} diff --git c/gcc/testsuite/g++.dg/modules/libfn-1_b.C w/gcc/testsuite/g++.dg/modules/libfn-1_b.C new file mode 100644 index 00000000000..0e8346b5b71 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/libfn-1_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options -fmodules-ts } +import foo; + +void bar () +{ + thrower (); +} + +void baz () +{ + try + { + throw 1; + } + catch (...) + { + } +} diff --git c/gcc/testsuite/g++.dg/modules/literals-1_a.C w/gcc/testsuite/g++.dg/modules/literals-1_a.C new file mode 100644 index 00000000000..9fb2aea5c82 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/literals-1_a.C @@ -0,0 +1,51 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts -Wno-pedantic -Wno-psabi" } + +// Make sure e can serialize various literals. */ + +export module real2reel; +// { dg-module-cmi real2reel } + +export inline float assassing () +{ + return 2.0f; +} + +export inline double market (float square, double heroes) +{ + return 4.0 * square * heroes; +} + +using cplx_i = __complex__ int; +using cplx_f = __complex__ float; +using cplx_d = __complex__ double; + +export inline cplx_i cinderella_search () +{ + return (cplx_i) {1, 2}; +} +export inline cplx_f emerald_lies () +{ + return (cplx_f) {3, 4}; +} +export inline cplx_d forgotten_sons () +{ + return (cplx_d) {5, 6}; +} + +export inline int garden_party (unsigned ix) +{ + return "invites call the debs to play"[ix]; +} + +using vec = int __attribute__((vector_size (sizeof (int) * 4))); + +export inline vec incubus () +{ + return (vec){1,7,3,9}; // Not an arithmetic series +} + +export inline vec charting_the_single () +{ + return (vec){1,2,3,4}; // An arithmetic series +} diff --git c/gcc/testsuite/g++.dg/modules/literals-1_b.C w/gcc/testsuite/g++.dg/modules/literals-1_b.C new file mode 100644 index 00000000000..5468944fad3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/literals-1_b.C @@ -0,0 +1,39 @@ +// { dg-additional-options {-fmodules-ts -Wno-psabi} } + +import real2reel; + +int main () +{ + if (assassing () != 2.0f) + return 1; + + if (market (/*square=*/2.0f, /*heroes=*/7.0) != 56.0) + return 2; + + auto c_i = cinderella_search (); + if (__real__ (c_i) != 1 || __imag__ (c_i) != 2) + return 3; + + auto c_f = emerald_lies (); + if (__real__ (c_f) != 3.0f || __imag__ (c_f) != 4.0f) + return 4; + + auto c_d = forgotten_sons (); + if (__real__ (c_d) != 5.0 || __imag__ (c_d) != 6.0) + return 5; + + + if (garden_party (7) != ' ') + return 6; + + auto v = incubus (); + if (v[0] != 1 || v[1] != 7 || v[2] != 3 || v[3] != 9) + return 7; + + v = charting_the_single (); + if (v[0] != 1 || v[1] != 2 || v[2] != 3 || v[3] != 4) + return 8; + + return 0; +} + diff --git c/gcc/testsuite/g++.dg/modules/loc-1_a.C w/gcc/testsuite/g++.dg/modules/loc-1_a.C new file mode 100644 index 00000000000..8155181b009 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-1_a.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +export module bob; +// { dg-module-cmi bob } + +export int frob (int *); // line 5 diff --git c/gcc/testsuite/g++.dg/modules/loc-1_b.C w/gcc/testsuite/g++.dg/modules/loc-1_b.C new file mode 100644 index 00000000000..0a0b85ed78c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } + +export module stuart; +// { dg-module-cmi stuart } + + +export int frob (float *); // line 6 + diff --git c/gcc/testsuite/g++.dg/modules/loc-1_c.C w/gcc/testsuite/g++.dg/modules/loc-1_c.C new file mode 100644 index 00000000000..f9522597e9e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-1_c.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts" } + +import bob; +import stuart; + +void kevin () +{ + frob (nullptr); // { dg-error "call of overload" } +} + +// { dg-regexp "In module stuart, imported at \[^\n]*loc-1_c.C:4:\n\[^\n]*loc-1_b.C:7:12: note:.*" } +// { dg-regexp "In module bob, imported at \[^\n]*loc-1_c.C:3:\n\[^\n]*loc-1_a.C:6:12: note:.*" } + + diff --git c/gcc/testsuite/g++.dg/modules/loc-2_a.C w/gcc/testsuite/g++.dg/modules/loc-2_a.C new file mode 100644 index 00000000000..a4bbce36a2a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-2_a.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +export module bob; +// { dg-module-cmi bob } + +export int frob (int *); diff --git c/gcc/testsuite/g++.dg/modules/loc-2_b.C w/gcc/testsuite/g++.dg/modules/loc-2_b.C new file mode 100644 index 00000000000..42640098d8e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-2_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +export module stuart; +// { dg-module-cmi stuart } + +export import bob; diff --git c/gcc/testsuite/g++.dg/modules/loc-2_c.C w/gcc/testsuite/g++.dg/modules/loc-2_c.C new file mode 100644 index 00000000000..e731d50933b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-2_c.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } + +export module kevin; +// { dg-module-cmi kevin } + +export import stuart; +export import bob; // Bob should be reseated in the export map +export import stuart; diff --git c/gcc/testsuite/g++.dg/modules/loc-2_d.C w/gcc/testsuite/g++.dg/modules/loc-2_d.C new file mode 100644 index 00000000000..4ae8a690c9e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-2_d.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } + +import stuart; + +void foo () +{ + frob (2); /* { dg-error "invalid conversion" } */ +} + +// { dg-regexp "In module bob, imported at \[^\n]*loc-2_b.C:6,\nof module stuart, imported at \[^\n]*loc-2_d.C:3:\n\[^\n]*loc-2_a.C:6:18: note:.*" } diff --git c/gcc/testsuite/g++.dg/modules/loc-2_e.C w/gcc/testsuite/g++.dg/modules/loc-2_e.C new file mode 100644 index 00000000000..c4d0acb7db8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-2_e.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } + +import stuart; +import bob; +import stuart; + +void foo () +{ + frob (2); // { dg-error "invalid conversion" } +} + +// { dg-regexp "In module bob, imported at \[^\n]*loc-2_e.C:4:\n\[^\n]*loc-2_a.C:6:18: note:.*" } diff --git c/gcc/testsuite/g++.dg/modules/loc-2_f.C w/gcc/testsuite/g++.dg/modules/loc-2_f.C new file mode 100644 index 00000000000..2888d048861 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-2_f.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } + +import kevin; + +void foo () +{ + frob (2); // { dg-error "invalid conversion" } +} + +// { dg-regexp "In module bob, imported at \[^\n]*loc-2_c.C:7,\nof module kevin, imported at \[^\n]*loc-2_f.C:3:\n\[^\n]*loc-2_a.C:6:18: note:.*" } diff --git c/gcc/testsuite/g++.dg/modules/loc-wrapper-1.h w/gcc/testsuite/g++.dg/modules/loc-wrapper-1.h new file mode 100644 index 00000000000..04e62d46f8f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-wrapper-1.h @@ -0,0 +1,14 @@ +template +struct __is_integer +{ + enum { __value = 0 }; +}; + +template +struct __is_integer_nonstrict + +{ + using __is_integer<_Tp>::__value; + + enum { __width = __value ? sizeof(_Tp) * 8 : 0 }; +}; diff --git c/gcc/testsuite/g++.dg/modules/loc-wrapper-1_a.H w/gcc/testsuite/g++.dg/modules/loc-wrapper-1_a.H new file mode 100644 index 00000000000..cddb46f5fab --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-wrapper-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } + +// { dg-module-cmi {} } +#include "loc-wrapper-1.h" diff --git c/gcc/testsuite/g++.dg/modules/loc-wrapper-1_b.C w/gcc/testsuite/g++.dg/modules/loc-wrapper-1_b.C new file mode 100644 index 00000000000..6d0229a8193 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/loc-wrapper-1_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } + +// ICEd comparing VIEW_CONVERT_EXPR location wrappers with null types +#include "loc-wrapper-1.h" +import "loc-wrapper-1_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/local-1_a.C w/gcc/testsuite/g++.dg/modules/local-1_a.C new file mode 100644 index 00000000000..c1a3343478b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/local-1_a.C @@ -0,0 +1,13 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +export module the.shop; +// { dg-module-cmi the.shop } + +export int for_local_people () +{ + struct X {int a;}; + X m; + m.a = 5; + return m.a; +} diff --git c/gcc/testsuite/g++.dg/modules/local-1_b.C w/gcc/testsuite/g++.dg/modules/local-1_b.C new file mode 100644 index 00000000000..37a9461706d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/local-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } +import the.shop; + +int main () +{ + if (for_local_people () != 5) + return 1; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/local-extern-1.C w/gcc/testsuite/g++.dg/modules/local-extern-1.C new file mode 100644 index 00000000000..7b016053d36 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/local-extern-1.C @@ -0,0 +1,20 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } + +module; +# 4 __FILE__ 1 +inline void frob () +{ + extern int bob; // OK +} + +# 11 "" 2 +export module bob; +// { dg-module-cmi !bob } + +inline void dob () +{ + extern int bob; // { dg-error "block-scope extern" } +} + + +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/local-extern-2.H w/gcc/testsuite/g++.dg/modules/local-extern-2.H new file mode 100644 index 00000000000..dab5ee4fb84 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/local-extern-2.H @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodule-header } + +// { dg-module-cmi {} } + +inline int *wcstok(int *__wcstok_ws1) +{ + extern int *__iso_wcstok(int * bob); + + return __iso_wcstok(__wcstok_ws1); +} diff --git c/gcc/testsuite/g++.dg/modules/local-struct-1_a.C w/gcc/testsuite/g++.dg/modules/local-struct-1_a.C new file mode 100644 index 00000000000..b4323b63e67 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/local-struct-1_a.C @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodules-ts } +export module foo; +// { dg-module-cmi foo } + +export inline int __inline_signbitf (float __x) +{ + union x { float __f; unsigned int __u; } __u; + + __u.__f = __x; + + return int (__u.__u >> 31); +} diff --git c/gcc/testsuite/g++.dg/modules/local-struct-1_b.C w/gcc/testsuite/g++.dg/modules/local-struct-1_b.C new file mode 100644 index 00000000000..96968e254ac --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/local-struct-1_b.C @@ -0,0 +1,3 @@ +// { dg-additional-options {-fmodules-ts -fno-module-lazy} } + +import foo; diff --git c/gcc/testsuite/g++.dg/modules/macloc-1_a.C w/gcc/testsuite/g++.dg/modules/macloc-1_a.C new file mode 100644 index 00000000000..a152b5191d8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macloc-1_a.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } + +export module agnes; +// { dg-module-cmi agnes } + +int a; + +#define BOB(X) int X () +#define KEVIN(X) int X () + +export BOB(me); +export KEVIN(you); + diff --git c/gcc/testsuite/g++.dg/modules/macloc-1_b.C w/gcc/testsuite/g++.dg/modules/macloc-1_b.C new file mode 100644 index 00000000000..8f8f1f55464 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macloc-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } + +export module edith; +// { dg-module-cmi edith } + +#define STUART(X) X + +import STUART(agnes); + +export void STUART(gru) (); diff --git c/gcc/testsuite/g++.dg/modules/macloc-1_c.C w/gcc/testsuite/g++.dg/modules/macloc-1_c.C new file mode 100644 index 00000000000..9b8f7fb9d59 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macloc-1_c.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } + +module edith; + +void gru () +{ + me (1); + you (1); +} + +// { dg-regexp "\[^\n]*macloc-1_c.C:7:8: error: too many arguments to function 'int me@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:11:12: note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n" } + +// { dg-regexp "\[^\n]*macloc-1_c.C:8:9: error: too many arguments to function 'int you@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:12:14: note: declared here\n\[^\n]*macloc-1_a.C:9:22: note: in definition of macro 'KEVIN'\n" } diff --git c/gcc/testsuite/g++.dg/modules/macloc-1_d.C w/gcc/testsuite/g++.dg/modules/macloc-1_d.C new file mode 100644 index 00000000000..5b2b7ba3034 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macloc-1_d.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } + +import edith; +import agnes; + +void margo () +{ + me (1); + gru (2); +} + +// { dg-regexp "\[^\n]*macloc-1_d.C:8:8: error: too many arguments to function 'int me@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_d.C:4:\n\[^\n]*macloc-1_a.C:11:12: note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n" } +// { dg-regexp "\[^\n]*macloc-1_d.C:9:9: error: too many arguments to function 'void gru@edith\\(\\)'\nIn module edith, imported at \[^\n]*macloc-1_d.C:3:\n\[^\n]*macloc-1_b.C:10:20: note: declared here\n\[^\n]*macloc-1_b.C:6:19: note: in definition of macro 'STUART'\n" } diff --git c/gcc/testsuite/g++.dg/modules/macloc-2_a.H w/gcc/testsuite/g++.dg/modules/macloc-2_a.H new file mode 100644 index 00000000000..99f08840280 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macloc-2_a.H @@ -0,0 +1,9 @@ +// { dg-additional-options {-fmodule-header -nostdinc} } +// { dg-module-cmi {} } + +#define MACRO(X) X + +inline int frob (int x) +{ + return x + 2; +} diff --git c/gcc/testsuite/g++.dg/modules/macloc-2_b.C w/gcc/testsuite/g++.dg/modules/macloc-2_b.C new file mode 100644 index 00000000000..601a4779c28 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macloc-2_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options {-fmodules-ts -nostdinc} } +module; + +import "macloc-2_a.H"; + +export module Foo; +// { dg-module-cmi Foo } + +export inline int MACRO (fn) (int i) +{ + return frob (i); +} + +export int (MACRO) (int i); diff --git c/gcc/testsuite/g++.dg/modules/macro-1_a.H w/gcc/testsuite/g++.dg/modules/macro-1_a.H new file mode 100644 index 00000000000..5b212a6d487 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-1_a.H @@ -0,0 +1,12 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +#ifndef MACRO_1_H +#define MACRO_1_H +#define foo bar baz +#define kevin(X) stuart (X) +#define stuart(X) bob ("banana", X) // Yes we have X bananas +#define bob(...) {__VA_ARGS__} + +#endif diff --git c/gcc/testsuite/g++.dg/modules/macro-1_b.C w/gcc/testsuite/g++.dg/modules/macro-1_b.C new file mode 100644 index 00000000000..afbcab281d7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-1_b.C @@ -0,0 +1,25 @@ +// { dg-additional-options "-fmodules-ts" } +import "macro-1_a.H"; + +#define baz = + 1 +int foo; +struct X +{ + const char *s; + int v; +} +; +X x kevin (5); + +int main () +{ + if (foo != 1) + return 1; + if (x.v != 5) + return 2; + const char *banana = "banana"; + for (unsigned ix = 0; banana[ix]; ix++) + if (banana[ix] != x.s[ix]) + return 3; + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/macro-2_a.H w/gcc/testsuite/g++.dg/modules/macro-2_a.H new file mode 100644 index 00000000000..89d66a5f405 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-2_a.H @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +#ifndef MACRO_2a_H +#define MACRO_2a_H + +#define FOO_OK foo +#define BAR_OK(BAZ) BINKY(2) + +#define FOO_BAD foo +#define BAR_BAD(BAZ) BINKY(2) + + +#endif diff --git c/gcc/testsuite/g++.dg/modules/macro-2_b.H w/gcc/testsuite/g++.dg/modules/macro-2_b.H new file mode 100644 index 00000000000..5690712607b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-2_b.H @@ -0,0 +1,24 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + + + + +// Make line numbers distinct from macro-2_a.H + + + + + + +#ifndef MACRO_2b_H +#define MACRO_2b_H + +#define FOO_OK foo +#define BAR_OK(BAZ) BINKY(2) + +#define FOO_BAD foot +#define BAR_BAD(BAZ) BINKY(3) + + +#endif diff --git c/gcc/testsuite/g++.dg/modules/macro-2_c.H w/gcc/testsuite/g++.dg/modules/macro-2_c.H new file mode 100644 index 00000000000..ed053236a5b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-2_c.H @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodule-header -fdump-lang-module" } +// { dg-module-cmi {} } + +#ifndef MACRO_2c_H +#define MACRO_2c_H +import "macro-2_a.H"; + +#endif + +// { dg-final { scan-lang-dump-not {Read new macro #define MACRO_2a_H at} module } } diff --git c/gcc/testsuite/g++.dg/modules/macro-2_d.C w/gcc/testsuite/g++.dg/modules/macro-2_d.C new file mode 100644 index 00000000000..04b80fb3058 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-2_d.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts" } + +#define BINKY(X) X + +import "macro-2_a.H"; +import "macro-2_b.H"; + +int FOO_OK = BAR_OK(1); + +int BAR_BAD; +// { dg-regexp {[^\n]*macro-2_d.C:10:5: error: inconsistent imported macro definition 'BAR_BAD'\nIn module [^\n]*macro-2_a.H, imported at [^\n]*macro-2_d.C:5:\n[^\n]*macro-2_a.H:11: note: '#define BAR_BAD\(BAZ\) BINKY\(2\)'\nIn module [^\n]*macro-2_b.H, imported at [^\n]*macro-2_d.C:6:\n[^\n]*macro-2_b.H:21: note: '#define BAR_BAD\(BAZ\) BINKY\(3\)'\n} } + +int FOO_BAD; +// { dg-regexp {[^\n]*macro-2_d.C:13:5: error: inconsistent imported macro definition 'FOO_BAD'\nIn module [^\n]*macro-2_a.H, imported at [^\n]*macro-2_d.C:5:\n[^\n]*macro-2_a.H:10: note: '#define FOO_BAD foo'\nIn module [^\n]*macro-2_b.H, imported at [^\n]*macro-2_d.C:6:\n[^\n]*macro-2_b.H:20: note: '#define FOO_BAD foot'\n} } diff --git c/gcc/testsuite/g++.dg/modules/macro-3_a.H w/gcc/testsuite/g++.dg/modules/macro-3_a.H new file mode 100644 index 00000000000..6582e3cb26c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-3_a.H @@ -0,0 +1,19 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header -fdump-lang-module-vops" } +// { dg-module-cmi {} } + +#ifndef MACRO_3a_H +#define MACRO_3a_H + +#undef nothing +#define bob x +#undef bob +#define foo 1 +#define bar 2 + +#endif + +// { dg-final { scan-lang-dump {Writing macro #define foo at} module } } +// { dg-final { scan-lang-dump {Writing macro #define bar at} module } } +// { dg-final { scan-lang-dump-not {Writing macro #define bob at} module } } +// { dg-final { scan-lang-dump-not {Writing macro #undef nothing at} module } } diff --git c/gcc/testsuite/g++.dg/modules/macro-3_b.H w/gcc/testsuite/g++.dg/modules/macro-3_b.H new file mode 100644 index 00000000000..2af92ac51e9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-3_b.H @@ -0,0 +1,24 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodule-header -fdump-lang-module-vops" } +// { dg-module-cmi {} } + +import "macro-3_a.H"; + +// Not the controlling macro, because of above tokens +#ifndef MACRO_3b_H +#define MACRO_3b_H + +#define bob 1 +#undef foo +#undef bar +#define bar 3 + +#endif + +// { dg-final { scan-lang-dump {Read new macro #define foo at} module } } +// { dg-final { scan-lang-dump {Read new macro #define bar at} module } } +// { dg-final { scan-lang-dump-not {Read [^ ]* macro #define bob at} module } } + +// { dg-final { scan-lang-dump {Writing macro #define bob at} module } } +// { dg-final { scan-lang-dump {Writing macro #undef & #define bar at} module } } +// { dg-final { scan-lang-dump {Writing macro #undef foo at} module } } diff --git c/gcc/testsuite/g++.dg/modules/macro-3_c.C w/gcc/testsuite/g++.dg/modules/macro-3_c.C new file mode 100644 index 00000000000..f0795807878 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-3_c.C @@ -0,0 +1,24 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-vops" } + +import "macro-3_b.H"; +import "macro-3_a.H"; + +int main () +{ +#ifdef foo + return 1; +#endif + if (bar != 3) + return 2; +#define foo 2 + if (foo != 2) + return 3; + return 0; +} + +// { dg-final { scan-lang-dump {Read new macro #define foo at} module } } +// { dg-final { scan-lang-dump {Read new macro #define bar at} module } } + +// { dg-final { scan-lang-dump {Read add macro #undef foo} module } } +// { dg-final { scan-lang-dump {Read new macro #define bob} module } } +// { dg-final { scan-lang-dump {Read add macro #undef & #define bar} module } } diff --git c/gcc/testsuite/g++.dg/modules/macro-4_a.H w/gcc/testsuite/g++.dg/modules/macro-4_a.H new file mode 100644 index 00000000000..c04854ea594 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-4_a.H @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodule-header -Winvalid-imported-macros" } +// { dg-module-cmi {} } + +#ifndef MACRO_4_a +#define MACRO_4_a + +#define ONE 1 +#define TWO 2 +#define THREE 3 +#define FOUR 4 +#define FIVE 5 + +#endif diff --git c/gcc/testsuite/g++.dg/modules/macro-4_b.H w/gcc/testsuite/g++.dg/modules/macro-4_b.H new file mode 100644 index 00000000000..04039389045 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-4_b.H @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodule-header -Winvalid-imported-macros" } +// { dg-module-cmi {} } + +#ifndef MACRO_4_b +#define MACRO_4_b + +#define ONE 1 +#define TWO 2a +#undef THREE // no effect +#define THREE 3b + +#endif diff --git c/gcc/testsuite/g++.dg/modules/macro-4_c.H w/gcc/testsuite/g++.dg/modules/macro-4_c.H new file mode 100644 index 00000000000..ec2bed91ccd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-4_c.H @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodule-header -Winvalid-imported-macros" } +// { dg-module-cmi {} } + +#ifndef MACRO_4_c +#define MACRO_4_c + +#undef FIVE // no effect +import "macro-4_a.H"; +int a; +#undef THREE +#undef FOUR +#define FOUR 4c + +#endif diff --git c/gcc/testsuite/g++.dg/modules/macro-4_d.C w/gcc/testsuite/g++.dg/modules/macro-4_d.C new file mode 100644 index 00000000000..bff9494281b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-4_d.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -Winvalid-imported-macros" } + +import "macro-4_b.H"; +import "macro-4_a.H"; + +// { dg-regexp {[^\n]*macro-4_d.C: warning: inconsistent imported macro definition 'TWO' \[-Winvalid-imported-macros\]\nIn module [^\n]*macro-4_b.H, imported at [^\n]*macro-4_d.C:[0-9]*:\n[^\n]*macro-4_b.H:[0-9]*: note: .#define TWO 2a.\nIn module [^\n]*macro-4_a.H, imported at [^\n]*macro-4_d.C:[0-9]*:\n[^\n]*macro-4_a.H:[0-9]*: note: .#define TWO 2.\n} } + +// { dg-regexp {[^\n]*macro-4_d.C: warning: inconsistent imported macro definition 'THREE' \[-Winvalid-imported-macros\]\nIn module [^\n]*macro-4_b.H, imported at [^\n]*macro-4_d.C:[0-9]*:\n[^\n]*macro-4_b.H:[0-9]*: note: .#define THREE 3b.\nIn module [^\n]*macro-4_a.H, imported at [^\n]*macro-4_d.C:[0-9]*:\n[^\n]*macro-4_a.H:[0-9]*: note: .#define THREE 3.\n} } diff --git c/gcc/testsuite/g++.dg/modules/macro-4_e.C w/gcc/testsuite/g++.dg/modules/macro-4_e.C new file mode 100644 index 00000000000..38fa6c7feeb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-4_e.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts -Winvalid-imported-macros" } + +import "macro-4_b.H"; +import "macro-4_a.H"; +import "macro-4_c.H"; + +int stop; + +#ifndef FIVE +#error bah! +#endif + +// { dg-regexp {[^\n]*macro-4_e.C: warning: inconsistent imported macro definition 'TWO' \[-Winvalid-imported-macros\]\nIn module [^\n]*macro-4_b.H, imported at [^\n]*macro-4_e.C:[0-9]*:\n[^\n]*macro-4_b.H:[0-9]*: note: .#define TWO 2a.\nIn module [^\n]*macro-4_a.H, imported at [^\n]*macro-4_e.C:[0-9]*:\n[^\n]*macro-4_a.H:[0-9]*: note: .#define TWO 2.\n} } diff --git c/gcc/testsuite/g++.dg/modules/macro-4_f.C w/gcc/testsuite/g++.dg/modules/macro-4_f.C new file mode 100644 index 00000000000..1279de271c0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-4_f.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } + +export module bob; +// { dg-module-cmi bob } +export import "macro-4_b.H"; diff --git c/gcc/testsuite/g++.dg/modules/macro-4_g.C w/gcc/testsuite/g++.dg/modules/macro-4_g.C new file mode 100644 index 00000000000..f3ff0e49f06 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-4_g.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -Winvalid-imported-macros" } + +import bob; +import "macro-4_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/macro-5_a.H w/gcc/testsuite/g++.dg/modules/macro-5_a.H new file mode 100644 index 00000000000..d0913d1c53e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-5_a.H @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodule-header -Dfoo=bar -Dbaz=1 -fdump-lang-module-vops" } +// command line macros are not exported +// { dg-module-cmi {} } + +// { dg-final { scan-lang-dump-not {Writing macro #define [_a-zA-Z0-9]* at [0-9]*} module } } diff --git c/gcc/testsuite/g++.dg/modules/macro-5_b.H w/gcc/testsuite/g++.dg/modules/macro-5_b.H new file mode 100644 index 00000000000..656d51143a1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-5_b.H @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodule-header -Dfoo=bar -Dbaz=2 -fdump-lang-module-vops" } +// { dg-module-cmi {} } + +#undef baz // not exported +#define baz 3 // exported + + +// { dg-final { scan-lang-dump {Writing macro #define baz at [0-9]*} module } } diff --git c/gcc/testsuite/g++.dg/modules/macro-5_c.C w/gcc/testsuite/g++.dg/modules/macro-5_c.C new file mode 100644 index 00000000000..17f6fe29913 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-5_c.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -Winvalid-imported-macros" } + +import "macro-5_a.H"; +import "macro-5_b.H"; + +#if baz != 3 +#error +#endif diff --git c/gcc/testsuite/g++.dg/modules/macro-6_a.H w/gcc/testsuite/g++.dg/modules/macro-6_a.H new file mode 100644 index 00000000000..4947e2ee76f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-6_a.H @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +#ifndef MACRO_6_H +#define MACRO_6_H +#define foo bar baz + +#endif diff --git c/gcc/testsuite/g++.dg/modules/macro-6_b.C w/gcc/testsuite/g++.dg/modules/macro-6_b.C new file mode 100644 index 00000000000..cbc3b2a68e5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-6_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +export module macro; +// { dg-module-cmi {macro} } +import "macro-6_a.H"; + +#ifndef foo +#error bad +#endif + +// { dg-final { scan-lang-dump {Reading macro table [^\n]*macro-6_a.H} module } } diff --git c/gcc/testsuite/g++.dg/modules/macro-6_c.C w/gcc/testsuite/g++.dg/modules/macro-6_c.C new file mode 100644 index 00000000000..a9a6f4f5db7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-6_c.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } +// Macro tables are only loaded when transitively reachable from top +// level + +import macro; + +#ifdef foo +#error bad +#endif + +// { dg-final { scan-lang-dump-not {>Reading macro table "macro-6_a.H"} module } } diff --git c/gcc/testsuite/g++.dg/modules/macro-7_a.C w/gcc/testsuite/g++.dg/modules/macro-7_a.C new file mode 100644 index 00000000000..f336f006d5f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-7_a.C @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodules-ts } +export module foo; +// { dg-module-cmi foo } + +#define MACRO(X) X + +export template int Factory () +{ + // this macro expansion location ends up in the instantiation + // emitted by an importer + return MACRO(I); +} + diff --git c/gcc/testsuite/g++.dg/modules/macro-7_b.C w/gcc/testsuite/g++.dg/modules/macro-7_b.C new file mode 100644 index 00000000000..025f5ebd29a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-7_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } +export module bar; +// { dg-module-cmi bar } + +import foo; + +export inline int One () +{ + return Factory<1> (); +} diff --git c/gcc/testsuite/g++.dg/modules/macro-7_c.C w/gcc/testsuite/g++.dg/modules/macro-7_c.C new file mode 100644 index 00000000000..902f1a8a803 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/macro-7_c.C @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodules-ts } +import bar; + +int main () +{ + return !(One () == 1); +} diff --git c/gcc/testsuite/g++.dg/modules/map-1.map w/gcc/testsuite/g++.dg/modules/map-1.map new file mode 100644 index 00000000000..58963bdb32d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/map-1.map @@ -0,0 +1,2 @@ +$root . +frob map-1_a.nms diff --git c/gcc/testsuite/g++.dg/modules/map-1_a.C w/gcc/testsuite/g++.dg/modules/map-1_a.C new file mode 100644 index 00000000000..f714672d05e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/map-1_a.C @@ -0,0 +1,13 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts -fmodule-mapper=[srcdir]/map-1.map" } + +// Ick! no cross-host testing for you! +// { dg-additional-files map-1.map } + +export module frob; +// { dg-module-cmi "=map-1_a.nms" } + +export int frob (int i) +{ + return -i; +} diff --git c/gcc/testsuite/g++.dg/modules/map-1_b.C w/gcc/testsuite/g++.dg/modules/map-1_b.C new file mode 100644 index 00000000000..0e306d8ba1f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/map-1_b.C @@ -0,0 +1,13 @@ +// Ick! +// { dg-additional-options "-fmodules-ts -fmodule-mapper=[srcdir]/map-1_b.map?MAP" } +// { dg-additional-files map-1.map } + +import frob; + +int main () +{ + if (frob (-2) != 2) + return 1; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/map-1_b.map w/gcc/testsuite/g++.dg/modules/map-1_b.map new file mode 100644 index 00000000000..f125dc8bda1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/map-1_b.map @@ -0,0 +1,3 @@ +MAP $root . +MAP frob map-1_a.nms +I can't see you diff --git c/gcc/testsuite/g++.dg/modules/map-2.C w/gcc/testsuite/g++.dg/modules/map-2.C new file mode 100644 index 00000000000..dceb1834196 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/map-2.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts -fmodule-mapper=[srcdir]/map-2.map" } + + +// Ick! no cross-host testing for you! +// { dg-additional-files map-2.map } + +export module foo; +// { dg-error "Interface: no such module" "" { target *-*-* } .-1 } +// { dg-error "failed reading mapper" "" { target *-*-* } 0 } + +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/map-2.map w/gcc/testsuite/g++.dg/modules/map-2.map new file mode 100644 index 00000000000..43aecde4b7f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/map-2.map @@ -0,0 +1 @@ +$bad . diff --git c/gcc/testsuite/g++.dg/modules/member-def-1_a.C w/gcc/testsuite/g++.dg/modules/member-def-1_a.C new file mode 100644 index 00000000000..f7a508cbea9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/member-def-1_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +export module foo:part1; +// { dg-module-cmi {foo:part1} } +struct frob +{ + struct inner; +}; diff --git c/gcc/testsuite/g++.dg/modules/member-def-1_b.C w/gcc/testsuite/g++.dg/modules/member-def-1_b.C new file mode 100644 index 00000000000..fbe1ac44cf2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/member-def-1_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } + +export module foo:part2; +// { dg-module-cmi {foo:part2} } + +import :part1; + +struct frob::inner +{ + int i; +}; + +// { dg-final { scan-lang-dump { Cluster members:\n \[0\]=decl definition '::frob@foo:part1:1::inner'\n \[1\]=decl declaration '::frob@foo:part1:1::inner::inner'\n} module } } +// { dg-final { scan-lang-dump {Member '::frob@foo:part1:1::inner' entity:0 keyed to foo:part1\[0\] '::frob@foo:part1:1'} module } } diff --git c/gcc/testsuite/g++.dg/modules/member-def-1_c.C w/gcc/testsuite/g++.dg/modules/member-def-1_c.C new file mode 100644 index 00000000000..c7c3f6eb194 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/member-def-1_c.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks-alias" } + +export module foo; +// { dg-module-cmi foo } + +export import :part2; +export import :part1; + +export auto foo () +{ + return frob::inner (); +} + +// { dg-final { scan-lang-dump {Reading 1 pending members keyed to foo:part1\[0\] '::frob@foo:part1:1'} module } } +// { dg-final { scan-lang-dump { Cluster members:\n \[0\]=decl definition '::frob@foo:part1:1'\n \[1\]=decl definition '::frob@foo:part1:1::inner@foo:part1:1'\n \[2\]=decl declaration '::frob@foo:part1:1::inner@foo:part1:1::__dt '\n( \[.\]=decl declaration '::frob@foo:part1:1::inner@foo:part1:1::__ct '\n)* \[6\]=decl declaration '::frob@foo:part1:1::inner@foo:part1:1::inner@foo:part2:2'\n \[7\]=decl declaration '::frob@foo:part1:1::frob@foo:part1:1'\n \[8\]=decl declaration '::frob@foo:part1:1::__as_base @foo:part1:1'\n \[9\]=binding '::frob'\n} module } } +// { dg-final { scan-lang-dump {Pendings 0} module } } diff --git c/gcc/testsuite/g++.dg/modules/member-def-1_d.C w/gcc/testsuite/g++.dg/modules/member-def-1_d.C new file mode 100644 index 00000000000..5609d47b075 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/member-def-1_d.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +module foo; + +void f () +{ + frob::inner x; + x.i = 17; +} + +// { dg-final { scan-lang-dump {Loaded 1 clusters} module } } diff --git c/gcc/testsuite/g++.dg/modules/member-def-2_a.C w/gcc/testsuite/g++.dg/modules/member-def-2_a.C new file mode 100644 index 00000000000..b4904dabbec --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/member-def-2_a.C @@ -0,0 +1,10 @@ +// { dg-module-do link } +// { dg-additional-options -fmodules-ts } + +export module foo:part1; +// { dg-module-cmi {foo:part1} } + +export struct frob +{ + void member (); +}; diff --git c/gcc/testsuite/g++.dg/modules/member-def-2_b.C w/gcc/testsuite/g++.dg/modules/member-def-2_b.C new file mode 100644 index 00000000000..dedcbe70fcd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/member-def-2_b.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } + +export module foo:part2; +// { dg-module-cmi {foo:part2} } + +import :part1; + +inline void frob::member () +{ +} + +// { dg-final { scan-lang-dump { Cluster members:\n \[0\]=decl definition '::frob@foo:part1:1::member'\n} module } } +// { dg-final { scan-lang-dump {Pendings 1} module } } +// { dg-final { scan-lang-dump {Bindings 0} module } } + +// { dg-final { scan-assembler-not {_ZN4frob6memberEv:} } } diff --git c/gcc/testsuite/g++.dg/modules/member-def-2_c.C w/gcc/testsuite/g++.dg/modules/member-def-2_c.C new file mode 100644 index 00000000000..f0a193f34ce --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/member-def-2_c.C @@ -0,0 +1,15 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks-alias" } + +export module foo; +// { dg-module-cmi foo } + +export import :part2; +export import :part1; + + +// { dg-final { scan-lang-dump { Cluster members:\n \[0\]=decl definition '::frob@foo:part1:1'\n \[1\]=decl declaration '::frob@foo:part1:1::frob@foo:part1:1'\n \[2\]=decl definition '::frob@foo:part1:1::member@foo:part1:1'\n \[3\]=decl declaration '::frob@foo:part1:1::__as_base @foo:part1:1'\n \[4\]=binding '::frob'\n} module } } +// { dg-final { scan-lang-dump {Bindings 1} module } } +// { dg-final { scan-lang-dump {Pendings 0} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key .matched. function_decl:'::frob@foo:part1:1::member'} module } } + +// { dg-final { scan-assembler-not {_ZN4frob6memberEv:} } } diff --git c/gcc/testsuite/g++.dg/modules/member-def-2_d.C w/gcc/testsuite/g++.dg/modules/member-def-2_d.C new file mode 100644 index 00000000000..c2b9c3e655b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/member-def-2_d.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +import foo; + +int main () +{ + frob x; + x.member (); +} + +// { dg-final { scan-lang-dump {Reading function definition '::frob@foo:1::member@foo:1'} module } } + +// { dg-final { scan-assembler {_ZN4frob6memberEv:} } } diff --git c/gcc/testsuite/g++.dg/modules/memref-1_a.C w/gcc/testsuite/g++.dg/modules/memref-1_a.C new file mode 100644 index 00000000000..e780999778d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/memref-1_a.C @@ -0,0 +1,24 @@ +// { dg-additional-options -fmodules-ts } + +export module Foo; +// { dg-module-cmi Foo } + +export class Bit +{ +private: + unsigned _M_msb:1; +}; + +Bit Make () noexcept; + +export class Container +{ +public: + void Frob () + { + _M_rep = Make (); + } + +private: + Bit _M_rep; +}; diff --git c/gcc/testsuite/g++.dg/modules/memref-1_b.C w/gcc/testsuite/g++.dg/modules/memref-1_b.C new file mode 100644 index 00000000000..82c52faed7a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/memref-1_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +import Foo; + +void X () +{ + Container c; + c.Frob (); +} diff --git c/gcc/testsuite/g++.dg/modules/merge-10.h w/gcc/testsuite/g++.dg/modules/merge-10.h new file mode 100644 index 00000000000..9df9d2cb75b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-10.h @@ -0,0 +1,8 @@ + +struct timex +{ + unsigned modes; + int :32; + int :32; +}; + diff --git c/gcc/testsuite/g++.dg/modules/merge-10_a.H w/gcc/testsuite/g++.dg/modules/merge-10_a.H new file mode 100644 index 00000000000..dc4be18f076 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-10_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "merge-10.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-10_b.C w/gcc/testsuite/g++.dg/modules/merge-10_b.C new file mode 100644 index 00000000000..9df07ee962a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-10_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-10.h" +import "merge-10_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-11.h w/gcc/testsuite/g++.dg/modules/merge-11.h new file mode 100644 index 00000000000..87342e18880 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-11.h @@ -0,0 +1,15 @@ + + + +template +struct __is_nt_convertible_helper; + +template +class __is_nt_convertible_helper<_From, false> +{ + template static int __test (int); + template static void __test(...); + +public: + using type = decltype(__test<_From>(0)); +}; diff --git c/gcc/testsuite/g++.dg/modules/merge-11_a.H w/gcc/testsuite/g++.dg/modules/merge-11_a.H new file mode 100644 index 00000000000..6de063d1a7f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-11_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "merge-11.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-11_b.C w/gcc/testsuite/g++.dg/modules/merge-11_b.C new file mode 100644 index 00000000000..2c30e341f53 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-11_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-11.h" +import "merge-11_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-12.h w/gcc/testsuite/g++.dg/modules/merge-12.h new file mode 100644 index 00000000000..96b2ba30265 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-12.h @@ -0,0 +1,23 @@ + +template +struct invoke_result; + +template +struct is_invocable; + +template +concept invocable = is_invocable<_Fn, _Args...>::value; + +template +requires invocable<_Fn, _Is> + using indirect_result_t = typename invoke_result<_Fn, _Is>::type; + +template +struct remove_cv; + +template +struct projected +{ + using value_type = remove_cv>; +}; + diff --git c/gcc/testsuite/g++.dg/modules/merge-12_a.H w/gcc/testsuite/g++.dg/modules/merge-12_a.H new file mode 100644 index 00000000000..4ee061f590e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-12_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header -fconcepts" } +// { dg-module-cmi {} } + +#include "merge-12.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-12_b.C w/gcc/testsuite/g++.dg/modules/merge-12_b.C new file mode 100644 index 00000000000..4bafbddb816 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-12_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fconcepts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-12.h" +import "merge-12_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-13.h w/gcc/testsuite/g++.dg/modules/merge-13.h new file mode 100644 index 00000000000..ad282a0ed62 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-13.h @@ -0,0 +1,10 @@ +template class Base; + +template class Derived : Base +{ + using Base_ = Base; + using typename Base_::base_member; + +public: + base_member Func (); +}; diff --git c/gcc/testsuite/g++.dg/modules/merge-13_a.H w/gcc/testsuite/g++.dg/modules/merge-13_a.H new file mode 100644 index 00000000000..ecf0c319e49 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-13_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header -fconcepts" } +// { dg-module-cmi {} } + +#include "merge-13.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-13_b.C w/gcc/testsuite/g++.dg/modules/merge-13_b.C new file mode 100644 index 00000000000..b62101fefb1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-13_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fconcepts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-13.h" +import "merge-13_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-14.h w/gcc/testsuite/g++.dg/modules/merge-14.h new file mode 100644 index 00000000000..0b867b68826 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-14.h @@ -0,0 +1,7 @@ +template +struct TPL +{ + T val = 0; +}; + +inline TPL x; diff --git c/gcc/testsuite/g++.dg/modules/merge-14_a.H w/gcc/testsuite/g++.dg/modules/merge-14_a.H new file mode 100644 index 00000000000..c197ec85e2d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-14_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "merge-14.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-14_b.C w/gcc/testsuite/g++.dg/modules/merge-14_b.C new file mode 100644 index 00000000000..4d92b084b95 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-14_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-14.h" +import "merge-14_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-15.h w/gcc/testsuite/g++.dg/modules/merge-15.h new file mode 100644 index 00000000000..ccf3b844d69 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-15.h @@ -0,0 +1,5 @@ +struct optional +{ + int &get () &; + int &&get () &&; +}; diff --git c/gcc/testsuite/g++.dg/modules/merge-15_a.H w/gcc/testsuite/g++.dg/modules/merge-15_a.H new file mode 100644 index 00000000000..afef95dbcbf --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-15_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "merge-15.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-15_b.C w/gcc/testsuite/g++.dg/modules/merge-15_b.C new file mode 100644 index 00000000000..07378d65368 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-15_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-15.h" +import "merge-15_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-1_a.C w/gcc/testsuite/g++.dg/modules/merge-1_a.C new file mode 100644 index 00000000000..966fd4bc4df --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-1_a.C @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +template +struct integral_constant +{ +}; + +typedef integral_constant true_type; + +void __throw_with_nested_impl (true_type); diff --git c/gcc/testsuite/g++.dg/modules/merge-1_b.C w/gcc/testsuite/g++.dg/modules/merge-1_b.C new file mode 100644 index 00000000000..c7f533ff1ba --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +void frob () +{ + __throw_with_nested_impl (integral_constant ()); +} diff --git c/gcc/testsuite/g++.dg/modules/merge-2_a.H w/gcc/testsuite/g++.dg/modules/merge-2_a.H new file mode 100644 index 00000000000..ac6d06a1d8f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-2_a.H @@ -0,0 +1,29 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template class istreambuf_iterator; + +void move(char __t); +void move(istreambuf_iterator &__u); + +template struct allocator {}; + +template struct __alloc_traits +{ + static void _S_on_swap(_Alloc& __b) + { + move (__b); + } + + typedef allocator other; +}; + +template class basic_string +{ + typedef __alloc_traits::other _Char_alloc_type; +}; + +template class istreambuf_iterator +{ + void frob (const basic_string& __s); +}; diff --git c/gcc/testsuite/g++.dg/modules/merge-2_b.C w/gcc/testsuite/g++.dg/modules/merge-2_b.C new file mode 100644 index 00000000000..21bbd048f2d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-2_b.C @@ -0,0 +1,2 @@ +// { dg-additional-options {-fmodules-ts -fno-module-lazy} } +import "merge-2_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/merge-3_a.H w/gcc/testsuite/g++.dg/modules/merge-3_a.H new file mode 100644 index 00000000000..80dfd9cc9a1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-3_a.H @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodule-header } +// { dg-module_cmi {} } + +struct bob +{ + int i; +}; diff --git c/gcc/testsuite/g++.dg/modules/merge-3_b.C w/gcc/testsuite/g++.dg/modules/merge-3_b.C new file mode 100644 index 00000000000..1e863f8c1e5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-3_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +struct bob; +import "merge-3_a.H"; + +bob b = {1}; + +void frob () +{ + b.i = 7; +} diff --git c/gcc/testsuite/g++.dg/modules/merge-4.h w/gcc/testsuite/g++.dg/modules/merge-4.h new file mode 100644 index 00000000000..842fedc5718 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-4.h @@ -0,0 +1,7 @@ +template struct Bob +{ + struct M + { + int m; + }; +}; diff --git c/gcc/testsuite/g++.dg/modules/merge-4_a.H w/gcc/testsuite/g++.dg/modules/merge-4_a.H new file mode 100644 index 00000000000..78b0ec74edd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-4_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "merge-4.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-4_b.C w/gcc/testsuite/g++.dg/modules/merge-4_b.C new file mode 100644 index 00000000000..89b69619ee2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-4_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-4.h" +import "merge-4_a.H"; + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) template_decl:'::template Bob'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) template_decl:'::template Bob::template M'} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-5.h w/gcc/testsuite/g++.dg/modules/merge-5.h new file mode 100644 index 00000000000..5db1b0a8115 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-5.h @@ -0,0 +1,8 @@ + +template struct __truth_type; + +template struct __traitor +{ + enum X { __value = true }; + typedef typename __truth_type<__value>::__type __type; +}; diff --git c/gcc/testsuite/g++.dg/modules/merge-5_a.H w/gcc/testsuite/g++.dg/modules/merge-5_a.H new file mode 100644 index 00000000000..e3d8c690921 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-5_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "merge-5.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-5_b.C w/gcc/testsuite/g++.dg/modules/merge-5_b.C new file mode 100644 index 00000000000..58c2a348c0a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-5_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-5.h" +import "merge-5_a.H"; + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) const_decl:'::template __traitor::template X::__value'} module } } +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-6.h w/gcc/testsuite/g++.dg/modules/merge-6.h new file mode 100644 index 00000000000..6a1d6542c51 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-6.h @@ -0,0 +1,10 @@ + +template +struct __truth_type; + +template +struct __traitor +{ + enum { __value = true }; // Oh, an anonymous templatey thing! + typedef typename __truth_type<__value>::__type __type; +}; diff --git c/gcc/testsuite/g++.dg/modules/merge-6_a.H w/gcc/testsuite/g++.dg/modules/merge-6_a.H new file mode 100644 index 00000000000..4e0b81c5a4a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-6_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "merge-6.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-6_b.C w/gcc/testsuite/g++.dg/modules/merge-6_b.C new file mode 100644 index 00000000000..11fe63153d5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-6_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-6.h" +import "merge-6_a.H"; + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s field merge key \(matched\) template_decl:'::template __traitor::template #null#'} module } } +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-7.h w/gcc/testsuite/g++.dg/modules/merge-7.h new file mode 100644 index 00000000000..6350e743f72 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-7.h @@ -0,0 +1,5 @@ +template +struct __promote_2 +{ + typedef __typeof__(_Tp2() + _Up2()) __type; +}; diff --git c/gcc/testsuite/g++.dg/modules/merge-7_a.H w/gcc/testsuite/g++.dg/modules/merge-7_a.H new file mode 100644 index 00000000000..3c32b33ada8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-7_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "merge-7.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-7_b.C w/gcc/testsuite/g++.dg/modules/merge-7_b.C new file mode 100644 index 00000000000..da9632d71bf --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-7_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-7.h" +import "merge-7_a.H"; + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) template_decl:'::template __promote_2<_Tp2,_Up2>::template __type'} module } } +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-8.h w/gcc/testsuite/g++.dg/modules/merge-8.h new file mode 100644 index 00000000000..d2539021ce3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-8.h @@ -0,0 +1,17 @@ + +struct __do_is_destructible_impl +{ + template + static bool __test(int); + + template + static float __test(...); +}; + +template +struct __is_destructible_impl + : public __do_is_destructible_impl +{ + // Requires BINFO merging + typedef decltype(__test<_Tp>(0)) type; +}; diff --git c/gcc/testsuite/g++.dg/modules/merge-8_a.H w/gcc/testsuite/g++.dg/modules/merge-8_a.H new file mode 100644 index 00000000000..d2add6bfdd8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-8_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "merge-8.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-8_b.C w/gcc/testsuite/g++.dg/modules/merge-8_b.C new file mode 100644 index 00000000000..c489e30a8ec --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-8_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-8.h" +import "merge-8_a.H"; + +// { dg-final { scan-lang-dump {Deduping binfo '::__do_is_destructible_impl'\[0\]} module } } +// { dg-final { scan-lang-dump {Deduping binfo '::template __is_destructible_impl<_Tp>'\[0\]} module } } +// { dg-final { scan-lang-dump {Deduping binfo '::template __is_destructible_impl<_Tp>'\[1\]} module } } diff --git c/gcc/testsuite/g++.dg/modules/merge-9.h w/gcc/testsuite/g++.dg/modules/merge-9.h new file mode 100644 index 00000000000..19447799fea --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-9.h @@ -0,0 +1,9 @@ +using size_t = __SIZE_TYPE__; + +namespace std +{ +// This is a builtin, but should not be a global tree + enum class align_val_t: size_t {}; + // as is this + class type_info; +} diff --git c/gcc/testsuite/g++.dg/modules/merge-9_a.H w/gcc/testsuite/g++.dg/modules/merge-9_a.H new file mode 100644 index 00000000000..69f32cb3671 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-9_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "merge-9.h" diff --git c/gcc/testsuite/g++.dg/modules/merge-9_b.C w/gcc/testsuite/g++.dg/modules/merge-9_b.C new file mode 100644 index 00000000000..0a92cf344df --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/merge-9_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "merge-9.h" +import "merge-9_a.H"; + +// { dg-final { scan-lang-dump {Read:-[10-9]*'s named merge key \(matched\) type_decl:'::std::align_val_t'} module } } +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/mod-exp-1_a.C w/gcc/testsuite/g++.dg/modules/mod-exp-1_a.C new file mode 100644 index 00000000000..800752dc871 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-exp-1_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts" } +export module Baz; +// { dg-module-cmi "Baz" } + +void Quux (void); + +export void Bar (void); + +void Foo (void); diff --git c/gcc/testsuite/g++.dg/modules/mod-exp-1_b.C w/gcc/testsuite/g++.dg/modules/mod-exp-1_b.C new file mode 100644 index 00000000000..efea205a50d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-exp-1_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +module; +# 4 "gmf" 1 +void Frob (void); +# 6 "" 2 + +module Baz; diff --git c/gcc/testsuite/g++.dg/modules/mod-imp-1_a.C w/gcc/testsuite/g++.dg/modules/mod-imp-1_a.C new file mode 100644 index 00000000000..cf9e1d7a2cc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-imp-1_a.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +export module Foo; +// { dg-module-cmi "Foo" } + +// { dg-final { scan-lang-dump "Starting module Foo" "module" } } diff --git c/gcc/testsuite/g++.dg/modules/mod-imp-1_b.C w/gcc/testsuite/g++.dg/modules/mod-imp-1_b.C new file mode 100644 index 00000000000..0dc4bdb58a3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-imp-1_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +module Foo; +// { dg-final { scan-lang-dump "Starting module Foo" "module" } } diff --git c/gcc/testsuite/g++.dg/modules/mod-imp-1_c.C w/gcc/testsuite/g++.dg/modules/mod-imp-1_c.C new file mode 100644 index 00000000000..e32aaaf7461 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-imp-1_c.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +export module Baz; +// { dg-module-cmi "Baz" } + +import Foo; + +// { dg-final { scan-lang-dump "Starting module Foo" "module" } } +// { dg-final { scan-lang-dump "Starting module Baz" "module" } } +// { dg-final { scan-lang-dump "Writing import:1->1 Foo" "module" } } diff --git c/gcc/testsuite/g++.dg/modules/mod-imp-1_d.C w/gcc/testsuite/g++.dg/modules/mod-imp-1_d.C new file mode 100644 index 00000000000..ca6f64914c2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-imp-1_d.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +module Baz; + +// { dg-final { scan-lang-dump "Starting module Baz" "module" } } +// { dg-final { scan-lang-dump "Found import:1 Foo->1" "module" } } +// { dg-final { scan-lang-dump "Starting module Foo" "module" } } diff --git c/gcc/testsuite/g++.dg/modules/mod-impl-1_a.C w/gcc/testsuite/g++.dg/modules/mod-impl-1_a.C new file mode 100644 index 00000000000..9f9dfd42806 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-impl-1_a.C @@ -0,0 +1,12 @@ +// { dg-module-do "run" } +// { dg-additional-options "-fmodules-ts" } + +export module baz; +// { dg-module-cmi "baz" } + +export int Square (int); + +float Square (int, int); +export int Square (int, int, int); + +int Prod (int, int); diff --git c/gcc/testsuite/g++.dg/modules/mod-impl-1_b.C w/gcc/testsuite/g++.dg/modules/mod-impl-1_b.C new file mode 100644 index 00000000000..c1f9a5c9233 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-impl-1_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } +module baz; + +int Square (int a) +{ + return Prod (a, a); +} + +float Square (int a, int b) +{ + return a * b * 1.5f; +} diff --git c/gcc/testsuite/g++.dg/modules/mod-impl-1_c.C w/gcc/testsuite/g++.dg/modules/mod-impl-1_c.C new file mode 100644 index 00000000000..c50aade4212 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-impl-1_c.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } +module baz; + +int Prod (int a, int b) +{ + return a * b; +} + +int Square (int a, int b, int c) +{ + return Prod (Square (a, b), c); +} diff --git c/gcc/testsuite/g++.dg/modules/mod-impl-1_d.C w/gcc/testsuite/g++.dg/modules/mod-impl-1_d.C new file mode 100644 index 00000000000..4f05a76159b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-impl-1_d.C @@ -0,0 +1,27 @@ +// { dg-additional-options "-fmodules-ts" } + +import baz; + +int Prod (int a, int b) +{ + return -a * b; // What kind of crazy math is this? +} + +int Square (float a) +{ + return Prod (int (a), int (a)); +} + +int main () +{ + if (Square (2) != 4) + return 1; + + if (Square (2.0f) != -4) + return 1; + + if (Square (2, 3, 4) != 9 * 4) + return 1; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/mod-indirect-1_a.C w/gcc/testsuite/g++.dg/modules/mod-indirect-1_a.C new file mode 100644 index 00000000000..a27153cb9ab --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-indirect-1_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } +// { dg-module-do run } + +export module Foo; +// { dg-module-cmi "Foo" } + +export int bob (int); +export float bob (float); diff --git c/gcc/testsuite/g++.dg/modules/mod-indirect-1_b.C w/gcc/testsuite/g++.dg/modules/mod-indirect-1_b.C new file mode 100644 index 00000000000..7e466f1d897 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-indirect-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } + +export module Bar; +// { dg-module-cmi "Bar" } + +import Foo; + +export int frob (int, float); diff --git c/gcc/testsuite/g++.dg/modules/mod-indirect-1_c.C w/gcc/testsuite/g++.dg/modules/mod-indirect-1_c.C new file mode 100644 index 00000000000..e19f41d4601 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-indirect-1_c.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } +module Foo; + +int bob (int a) +{ + return a * 2; +} + +float bob (float b) +{ + return b * 1.5f; +} diff --git c/gcc/testsuite/g++.dg/modules/mod-indirect-1_d.C w/gcc/testsuite/g++.dg/modules/mod-indirect-1_d.C new file mode 100644 index 00000000000..304be95561e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-indirect-1_d.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +module Bar; + +int frob (int a, float b) +{ + return bob (a) * bob (b); +} diff --git c/gcc/testsuite/g++.dg/modules/mod-indirect-1_e.C w/gcc/testsuite/g++.dg/modules/mod-indirect-1_e.C new file mode 100644 index 00000000000..23241b1601f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-indirect-1_e.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +import Bar; + +int main () +{ + return frob (2, 4) != 4 * 6; +} diff --git c/gcc/testsuite/g++.dg/modules/mod-stamp-1_a.C w/gcc/testsuite/g++.dg/modules/mod-stamp-1_a.C new file mode 100644 index 00000000000..cf8e73f85d7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-stamp-1_a.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } + +export module Foo; +// { dg-module-cmi "Foo" } + +export int bob (); + diff --git c/gcc/testsuite/g++.dg/modules/mod-stamp-1_b.C w/gcc/testsuite/g++.dg/modules/mod-stamp-1_b.C new file mode 100644 index 00000000000..3a5e8e20ba5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-stamp-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } + +export module Bar; +// { dg-module-cmi "Bar" } + +import Foo; + +export int bill (); diff --git c/gcc/testsuite/g++.dg/modules/mod-stamp-1_c.C w/gcc/testsuite/g++.dg/modules/mod-stamp-1_c.C new file mode 100644 index 00000000000..554ba3f26eb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-stamp-1_c.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } + +export module Foo; + +export int bob (int); diff --git c/gcc/testsuite/g++.dg/modules/mod-stamp-1_d.C w/gcc/testsuite/g++.dg/modules/mod-stamp-1_d.C new file mode 100644 index 00000000000..f16833ed5c9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-stamp-1_d.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } + +import Bar; +// { dg-error "CRC mismatch" "" { target *-*-* } 0 } +// { dg-regexp "Foo: error: failed to read compiled module: Bad file data\n" } +// { dg-regexp "Bar: error: failed to read compiled module: Bad import dependency\n" } +// { dg-prune-output "fatal error:" } +// { dg-prune-output "compilation terminated" } + +int bill (); diff --git c/gcc/testsuite/g++.dg/modules/mod-sym-1.C w/gcc/testsuite/g++.dg/modules/mod-sym-1.C new file mode 100644 index 00000000000..b20710189d1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-sym-1.C @@ -0,0 +1,34 @@ +// { dg-additional-options "-fmodules-ts" } +export module linkage; +// { dg-module-cmi "linkage" } + +inline void Foo () {} + +export inline void Baz () __attribute__((used)); + +inline void Bink () {} + +export inline void Baz () { Foo (); Bink (); } + +extern "C" inline void cfunc (void) __attribute__((used)); +extern "C" inline void cfunc (void) {} + +namespace Inner +{ + inline void Foo2 () {} + + export inline void Baz2 () __attribute__((used)); + + inline void Bink2 () {} + + export inline void Baz2 () { Foo2 (); Bink2 (); } +} + +// These fail until namespace hack is removed +// { dg-final { scan-assembler "_ZW7linkageE3Foov:" } } +// { dg-final { scan-assembler "_ZW7linkageE4Binkv:" } } +// { dg-final { scan-assembler "_ZW7linkageEN5Inner4Foo2Ev:" } } +// { dg-final { scan-assembler "_ZW7linkageEN5Inner5Bink2Ev:" } } +// { dg-final { scan-assembler "_Z3Bazv:" } } +// { dg-final { scan-assembler "_ZN5Inner4Baz2Ev:" } } +// { dg-final { scan-assembler "cfunc:" } } diff --git c/gcc/testsuite/g++.dg/modules/mod-sym-2.C w/gcc/testsuite/g++.dg/modules/mod-sym-2.C new file mode 100644 index 00000000000..ef0c3f03317 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-sym-2.C @@ -0,0 +1,23 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +module; +# 4 "header" 1 +inline void Foo () {} +# 6 "" 2 +export module okely.dokely; +// { dg-module-cmi "okely.dokely" } + +namespace One { + namespace Two { + inline namespace Three + { + inline void Foo2 () {} + + export inline void Baz2 () __attribute__((used)); + export inline void Baz2 () { Foo (); Foo2 (); } + } + } +} + +// { dg-final { scan-assembler "_Z3Foov:" } } +// { dg-final { scan-assembler "_ZW5okely6dokelyEN3One3Two5Three4Foo2Ev:" } } +// { dg-final { scan-assembler "_ZN3One3Two5Three4Baz2Ev:" } } diff --git c/gcc/testsuite/g++.dg/modules/mod-sym-3.C w/gcc/testsuite/g++.dg/modules/mod-sym-3.C new file mode 100644 index 00000000000..9481ad1e719 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-sym-3.C @@ -0,0 +1,26 @@ +// { dg-additional-options "-fmodules-ts" } +export module bob; +// { dg-module-cmi "bob" } + +namespace X +{ + inline void Foo () __attribute__((used)); + export inline void Baz () __attribute__((used)); + + namespace Y + { + inline void Quux () __attribute__((used)); + export inline void Bar () __attribute__((used)); + } + + inline void Y::Quux () {} + inline void Y::Bar () {} +} + +inline void X::Foo () {} +inline void X::Baz () {} + +// { dg-final { scan-assembler "_ZW3bobEN1X3FooEv:" } } +// { dg-final { scan-assembler "_ZN1X3BazEv:" } } +// { dg-final { scan-assembler "_ZW3bobEN1X1Y4QuuxEv:" } } +// { dg-final { scan-assembler "_ZN1X1Y3BarEv:" } } diff --git c/gcc/testsuite/g++.dg/modules/mod-tpl-1_a.C w/gcc/testsuite/g++.dg/modules/mod-tpl-1_a.C new file mode 100644 index 00000000000..f48e1237d01 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-tpl-1_a.C @@ -0,0 +1,12 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +export module Frob; +// { dg-module-cmi "Frob" } + +export template +T twice (T x) +{ + return x * 2; +} + diff --git c/gcc/testsuite/g++.dg/modules/mod-tpl-1_b.C w/gcc/testsuite/g++.dg/modules/mod-tpl-1_b.C new file mode 100644 index 00000000000..669f2c68881 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-tpl-1_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts" } +import Frob; + +int main () +{ + return twice (2) != 4; +} diff --git c/gcc/testsuite/g++.dg/modules/mod-tpl-2_a.C w/gcc/testsuite/g++.dg/modules/mod-tpl-2_a.C new file mode 100644 index 00000000000..86281bb97a6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-tpl-2_a.C @@ -0,0 +1,16 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +export module frob; +// { dg-module-cmi "frob" } + +export template +class X +{ + T m; + +public: + void frob (T v) { m = v; } + + T frobber (T v) { return v + m; } +}; diff --git c/gcc/testsuite/g++.dg/modules/mod-tpl-2_b.C w/gcc/testsuite/g++.dg/modules/mod-tpl-2_b.C new file mode 100644 index 00000000000..8452c7d7875 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mod-tpl-2_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } + +import frob; + +int main () +{ + X x; + + x.frob (3); + + return ! (x.frobber (-3) == 0); +} diff --git c/gcc/testsuite/g++.dg/modules/mutual-friend.ii w/gcc/testsuite/g++.dg/modules/mutual-friend.ii new file mode 100644 index 00000000000..b42b9798998 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/mutual-friend.ii @@ -0,0 +1,11 @@ +class exception_ptr; + + +void rethrow_exception(exception_ptr); + + +class exception_ptr +{ + friend void rethrow_exception(exception_ptr); +}; + diff --git c/gcc/testsuite/g++.dg/modules/namespace-1_a.C w/gcc/testsuite/g++.dg/modules/namespace-1_a.C new file mode 100644 index 00000000000..1929acc167a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/namespace-1_a.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } +export module Frob; +// { dg-module-cmi Frob } + +namespace impl +{ + export int doit (int); +} + +namespace ompl +{ + export int doneit (int); +} diff --git c/gcc/testsuite/g++.dg/modules/namespace-1_b.C w/gcc/testsuite/g++.dg/modules/namespace-1_b.C new file mode 100644 index 00000000000..096e6ce41ae --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/namespace-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } +export module Frink; +// { dg-module-cmi Frink } + +import Frob; + +export int frab (int x) +{ + return impl::doit (x) + ompl::doneit (x); +} diff --git c/gcc/testsuite/g++.dg/modules/namespace-1_c.C w/gcc/testsuite/g++.dg/modules/namespace-1_c.C new file mode 100644 index 00000000000..748ef5d79a4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/namespace-1_c.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } +// The indirect import of frob, with namespaces impl and ompl doesn't +// affect us. +static int impl; +import Frink; + +static int ompl; + +void corge (int x) +{ + impl = x; + ompl = frab (x); +} diff --git c/gcc/testsuite/g++.dg/modules/namespace-2_a.C w/gcc/testsuite/g++.dg/modules/namespace-2_a.C new file mode 100644 index 00000000000..18327e205ee --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/namespace-2_a.C @@ -0,0 +1,40 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module -Wno-pedantic" } + +module; +# 5 "gmf" 1 +namespace not_exported +{ + // not in purview +} +# 10 "" 2 +export module foo; +// { dg-module-cmi foo } + +namespace explicit_export +{ +} + +namespace implicit_export +{ + export int bob (); +} + +namespace also_not_exported +{ + int bob (); +} + +export namespace explicit_export +{ + namespace also_exported + { + } +} + +// { dg-final { scan-lang-dump-not {Writable bindings at '::not_exported'} "module" } } +// { dg-final { scan-lang-dump {Writing namespace:[0-9] '::implicit_export', export, public} "module" } } +// { dg-final { scan-lang-dump {Writing namespace:[0-9] '::explicit_export', export, public} "module" } } +// { dg-final { scan-lang-dump {Writing namespace:[0-9] '::also_not_exported', public} "module" } } +// { dg-final { scan-lang-dump {Writing namespace:[0-9] '::explicit_export::also_exported', export, public} "module" } } +// { dg-final { scan-lang-dump-not {Writing namespace:[0-9] '::not_exported'} "module" } } +// { dg-final { scan-lang-dump-not {Writing namespace:[0-9] '::std'} "module" } } diff --git c/gcc/testsuite/g++.dg/modules/namespace-2_b.C w/gcc/testsuite/g++.dg/modules/namespace-2_b.C new file mode 100644 index 00000000000..6ab5113c23a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/namespace-2_b.C @@ -0,0 +1,17 @@ +// { dg-additional-options "-fmodules-ts" } + +import foo; + +static int also_not_exported; // ok + +void X () +{ + implicit_export::bob (); +} + +static int implicit_export; // { dg-error "different kind" } + +void Y () +{ + also_not_exported = 1; +} diff --git c/gcc/testsuite/g++.dg/modules/namespace-3_a.C w/gcc/testsuite/g++.dg/modules/namespace-3_a.C new file mode 100644 index 00000000000..8e9508d7ff8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/namespace-3_a.C @@ -0,0 +1,21 @@ +// Check namespace needed only by internal reference is not made visible +// { dg-additional-options "-fmodules-ts" } + +export module frob; +// { dg-module-cmi frob } + +namespace silent +{ + namespace inner + { + static int X () + { + return 1; + } + } +} + +export int f (int y) +{ + return y + silent::inner::X (); +} diff --git c/gcc/testsuite/g++.dg/modules/namespace-3_b.C w/gcc/testsuite/g++.dg/modules/namespace-3_b.C new file mode 100644 index 00000000000..f779ffe8c8f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/namespace-3_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } + +import frob; + +int x = silent; // { dg-error "not declared" } + +static int silent; + +int user () +{ + return f (silent); +} diff --git c/gcc/testsuite/g++.dg/modules/namespace-4_a.C w/gcc/testsuite/g++.dg/modules/namespace-4_a.C new file mode 100644 index 00000000000..b49e0ea7ce6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/namespace-4_a.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts" } + +export module frob; +// { dg-module-cmi frob } + +namespace +{ + int nope; +} + +export int f (int) +{ + return nope; +} + +int g (int *a); diff --git c/gcc/testsuite/g++.dg/modules/namespace-4_b.C w/gcc/testsuite/g++.dg/modules/namespace-4_b.C new file mode 100644 index 00000000000..3530bcd9def --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/namespace-4_b.C @@ -0,0 +1,15 @@ +// { dg-additional-options "-fmodules-ts" } + +module frob; + +namespace +{ +void *nope; // ok, different nope +} + +void *q (int) +{ + f (bool (nope)); + g (static_cast (nope)); + return nope; // Ok sees above nope +} diff --git c/gcc/testsuite/g++.dg/modules/namespace-4_c.C w/gcc/testsuite/g++.dg/modules/namespace-4_c.C new file mode 100644 index 00000000000..2526289ec3e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/namespace-4_c.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts" } + +import frob; + +namespace +{ + float *nope; +} + +float *q () +{ + f (int (*nope)); + return nope; +} diff --git c/gcc/testsuite/g++.dg/modules/nest-1_a.C w/gcc/testsuite/g++.dg/modules/nest-1_a.C new file mode 100644 index 00000000000..4788d5da601 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nest-1_a.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } +export module foo; +// { dg-module-cmi foo } + +namespace foo { + + export int frob (int i) + { + return i; + } + +} diff --git c/gcc/testsuite/g++.dg/modules/nest-1_b.C w/gcc/testsuite/g++.dg/modules/nest-1_b.C new file mode 100644 index 00000000000..cc302781248 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nest-1_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } +export module bar; +// { dg-module-cmi bar } + +import foo; + +namespace bar +{ + export int frob (int i) + { + return i; + } +} diff --git c/gcc/testsuite/g++.dg/modules/nest-1_c.C w/gcc/testsuite/g++.dg/modules/nest-1_c.C new file mode 100644 index 00000000000..05ca02ffc61 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nest-1_c.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts --param lazy-modules=1" } +import bar; + +int main () +{ + return bar::frob (0); +} diff --git c/gcc/testsuite/g++.dg/modules/nested-1_a.C w/gcc/testsuite/g++.dg/modules/nested-1_a.C new file mode 100644 index 00000000000..31726571ae8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-1_a.C @@ -0,0 +1,19 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +export module blinky; +// { dg-module-cmi blinky } + +export struct X +{ + struct Inner + { + int m; + Inner (int); + int getter () const + { + return m; + } + }; +}; + diff --git c/gcc/testsuite/g++.dg/modules/nested-1_b.C w/gcc/testsuite/g++.dg/modules/nested-1_b.C new file mode 100644 index 00000000000..9f775b16c17 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } + +module blinky; + +X::Inner::Inner (int m_) + :m (m_) +{ +} diff --git c/gcc/testsuite/g++.dg/modules/nested-1_c.C w/gcc/testsuite/g++.dg/modules/nested-1_c.C new file mode 100644 index 00000000000..f46e6dfde3d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-1_c.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } + +import blinky; + +int main () +{ + X::Inner i (7); + + if (i.getter () != 7) + return 1; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/nested-2_a.C w/gcc/testsuite/g++.dg/modules/nested-2_a.C new file mode 100644 index 00000000000..e21973593d1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-2_a.C @@ -0,0 +1,24 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +export module bob; +// { dg-module-cmi bob } + +export struct X +{ + typedef X *iter; + + int m; + X() :m(-1) + { + } + + void set (int m_) + { + m = m_; + } + operator int () const + { + return m; + } +}; diff --git c/gcc/testsuite/g++.dg/modules/nested-2_b.C w/gcc/testsuite/g++.dg/modules/nested-2_b.C new file mode 100644 index 00000000000..1ca02bdc2fe --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-2_b.C @@ -0,0 +1,20 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +import bob; + +int main () +{ + X ary[10]; + X::iter iter; + unsigned ix; + + for (ix = 10, iter = ary; ix--; iter++) + iter->set (ix); + + for (ix = 10; ix--;) + if (ary[ix] + ix != 9) + return 1; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/nested-constr-1.h w/gcc/testsuite/g++.dg/modules/nested-constr-1.h new file mode 100644 index 00000000000..6962ccad850 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-constr-1.h @@ -0,0 +1,15 @@ + +template +struct traits +{ + template + struct nested + { using type = void; }; + + template requires requires { typename U::type; } + struct nested + { using type = typename U::type; }; +}; + +using V = traits::nested::type; + diff --git c/gcc/testsuite/g++.dg/modules/nested-constr-1_a.H w/gcc/testsuite/g++.dg/modules/nested-constr-1_a.H new file mode 100644 index 00000000000..9398986dd42 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-constr-1_a.H @@ -0,0 +1,3 @@ +// { dg-additional-options "-std=c++2a -fmodule-header" } +// { dg-module-cmi {} } +#include "nested-constr-1.h" diff --git c/gcc/testsuite/g++.dg/modules/nested-constr-1_b.C w/gcc/testsuite/g++.dg/modules/nested-constr-1_b.C new file mode 100644 index 00000000000..7043ffa8554 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-constr-1_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-std=c++2a -fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "nested-constr-1.h" +import "nested-constr-1_a.H"; + +struct X +{ + using type = int; +}; + +traits::nested::type b; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/nested-constr-2_a.C w/gcc/testsuite/g++.dg/modules/nested-constr-2_a.C new file mode 100644 index 00000000000..b29d670a570 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-constr-2_a.C @@ -0,0 +1,18 @@ +// { dg-additional-options "-std=c++2a -fmodules-ts" } +export module foo; +// { dg-module-cmi foo } + +export template +struct traits +{ + template + struct nested + { using type = void; }; + + template requires requires { typename U::type; } + struct nested + { using type = typename U::type; }; +}; + +export using V = traits::nested::type; + diff --git c/gcc/testsuite/g++.dg/modules/nested-constr-2_b.C w/gcc/testsuite/g++.dg/modules/nested-constr-2_b.C new file mode 100644 index 00000000000..a34ef523f90 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-constr-2_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-std=c++2a -fmodules-ts" } +export module bar; +// { dg-module-cmi bar } +import foo; + +struct X +{ + using type = int; +}; + +export traits::nested::type b; diff --git c/gcc/testsuite/g++.dg/modules/nested-constr-2_c.C w/gcc/testsuite/g++.dg/modules/nested-constr-2_c.C new file mode 100644 index 00000000000..5c81b3b6c09 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nested-constr-2_c.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-std=c++2a -fmodules-ts" } + +import bar; + +decltype(b) c; diff --git c/gcc/testsuite/g++.dg/modules/nodes-1_a.C w/gcc/testsuite/g++.dg/modules/nodes-1_a.C new file mode 100644 index 00000000000..446461c8a6b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nodes-1_a.C @@ -0,0 +1,46 @@ +// { dg-additional-options -fmodules-ts } +// { dg-module-do run } + +export module node; +// { dg-module-cmi node } + +export template void assert (T t) +{ + static_assert (sizeof (T) == sizeof (int), "whoops"); +} + +export class other +{ +public: + other () :f (5) {} + void o () { } + int f; +}; + +export template class baselink : T, other +{ +public: + int Frob () + { + o (); + return this->T::frob (); + } +}; + +export template bool trait () +{ + return __has_nothrow_assign(T); +} + +export inline bool ptrmemdata (other const &obj) +{ + int other::*ptr = &other::f; + + return (obj.*ptr) == 5; +} + +export template int ptrmemfn (T const &obj) +{ + int (T::*ptr) () const = &T::frob; + return (obj.*ptr) (); +} diff --git c/gcc/testsuite/g++.dg/modules/nodes-1_b.C w/gcc/testsuite/g++.dg/modules/nodes-1_b.C new file mode 100644 index 00000000000..1567e90c1a5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nodes-1_b.C @@ -0,0 +1,27 @@ +// { dg-additional-options -fmodules-ts } +import node; + +struct b +{ + int frob () const + { + return 0; + } +}; + +int main () +{ + assert (0); + baselink thing; + thing.Frob (); + if (!trait ()) + return 1; + + if (!ptrmemdata (other ())) + return 2; + + if (ptrmemfn (b ())) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/noexcept-1.h w/gcc/testsuite/g++.dg/modules/noexcept-1.h new file mode 100644 index 00000000000..a4a0de5dd7f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/noexcept-1.h @@ -0,0 +1,78 @@ +template +struct integral_constant +{ + static constexpr _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant<_Tp, __v> type; +}; + +template +constexpr _Tp integral_constant<_Tp, __v>::value; + +typedef integral_constant false_type; + + +template +struct Alien +{ +}; + +template +bool operator==(const Alien<_T1>& __x, const Alien<_T1>& __y); + +template +struct duration; + +template +struct __duration_cast_impl +{ +}; + +template +long Frob (const duration<_Rep>& __d) +{ + typedef __duration_cast_impl __dc; + + return 0; +} + +template +struct duration +{ +public: + constexpr duration() = default; + + duration (const duration& __d) + { + Frob (__d); + } +}; + +template +struct __atomic_semaphore +{ + template + bool _M_try_acquire_for (const duration<_Rep>& __rtime) noexcept; + + void _M_release() noexcept; +}; + +template +class counting_semaphore +{ + __atomic_semaphore _M_sem; + +public: + explicit counting_semaphore() noexcept; + + void release() noexcept (noexcept (_M_sem._M_release ())); +}; + +class stop_token +{ +public: + counting_semaphore<1> _M_done; +}; + +bool operator==(const stop_token& __a, const stop_token& __b); diff --git c/gcc/testsuite/g++.dg/modules/noexcept-1_a.H w/gcc/testsuite/g++.dg/modules/noexcept-1_a.H new file mode 100644 index 00000000000..00949cf5a3c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/noexcept-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options {-std=c++20 -fmodule-header} } +// { dg-module-cmi {} } + +#include "noexcept-1.h" diff --git c/gcc/testsuite/g++.dg/modules/noexcept-1_b.C w/gcc/testsuite/g++.dg/modules/noexcept-1_b.C new file mode 100644 index 00000000000..62a13fcf6a7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/noexcept-1_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options {-std=c++20 -fmodules-ts -fno-module-lazy} } + +#include "noexcept-1.h" +import "noexcept-1_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/ns-alias-1_a.C w/gcc/testsuite/g++.dg/modules/ns-alias-1_a.C new file mode 100644 index 00000000000..9f501eee166 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-alias-1_a.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts" } + +export module foo; +// { dg-module-cmi foo } + +export namespace detail { + using bob = int; +} + +namespace elsewhere { +export namespace det = ::detail; +namespace ail = ::detail; + +void frob (det::bob); + +} diff --git c/gcc/testsuite/g++.dg/modules/ns-alias-1_b.C w/gcc/testsuite/g++.dg/modules/ns-alias-1_b.C new file mode 100644 index 00000000000..55fd9268b44 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-alias-1_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +module foo; + +elsewhere::det::bob j; +elsewhere::ail::bob k; diff --git c/gcc/testsuite/g++.dg/modules/ns-alias-1_c.C w/gcc/testsuite/g++.dg/modules/ns-alias-1_c.C new file mode 100644 index 00000000000..9e4a81dce82 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-alias-1_c.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +import foo; + +elsewhere::det::bob j; +elsewhere::ail::bob k; // { dg-error "does not name a type" } diff --git c/gcc/testsuite/g++.dg/modules/ns-dir-1_a.C w/gcc/testsuite/g++.dg/modules/ns-dir-1_a.C new file mode 100644 index 00000000000..d63f9fd8aaa --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-dir-1_a.C @@ -0,0 +1,18 @@ +// { dg-additional-options -fmodules-ts } + +export module bob; +// { dg-module-cmi bob } + +namespace detail { +int i; +} + +namespace elsewhere { + +export inline void frob () +{ + using namespace detail; + i = 5; +} + +} diff --git c/gcc/testsuite/g++.dg/modules/ns-dir-1_b.C w/gcc/testsuite/g++.dg/modules/ns-dir-1_b.C new file mode 100644 index 00000000000..b26e7875a6e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-dir-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +import bob; + +void foo () +{ + elsewhere::frob (); +} diff --git c/gcc/testsuite/g++.dg/modules/ns-dup-1_a.C w/gcc/testsuite/g++.dg/modules/ns-dup-1_a.C new file mode 100644 index 00000000000..600f518207a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-dup-1_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +export namespace std +{ +} diff --git c/gcc/testsuite/g++.dg/modules/ns-dup-1_b.C w/gcc/testsuite/g++.dg/modules/ns-dup-1_b.C new file mode 100644 index 00000000000..23190db013e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-dup-1_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options {-fmodules-ts -Wno-pedantic} } + +module; +# 5 __FILE__ 1 +namespace std {} +# 7 "" 2 +export module bob; +// { dg-module-cmi bob } + +import foo; +namespace std {} diff --git c/gcc/testsuite/g++.dg/modules/ns-imp-1_a.C w/gcc/testsuite/g++.dg/modules/ns-imp-1_a.C new file mode 100644 index 00000000000..9a91a1e1970 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-imp-1_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +export module Foo; +// { dg-module-cmi {Foo} } + +namespace Bob +{ +export int Random (); +} diff --git c/gcc/testsuite/g++.dg/modules/ns-imp-1_b.C w/gcc/testsuite/g++.dg/modules/ns-imp-1_b.C new file mode 100644 index 00000000000..449c70513c5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-imp-1_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +export module Bar; +// { dg-module-cmi {Bar} } + +export import Foo; + +namespace Bob +{ +export int Quux (); +} diff --git c/gcc/testsuite/g++.dg/modules/ns-imp-1_c.C w/gcc/testsuite/g++.dg/modules/ns-imp-1_c.C new file mode 100644 index 00000000000..2a58a919661 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-imp-1_c.C @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodules-ts } + +export import Foo; +export import Bar; + +namespace Bob +{ +void Widget () +{ + Random (); + Quux (); +} +} diff --git c/gcc/testsuite/g++.dg/modules/ns-part-1_a.C w/gcc/testsuite/g++.dg/modules/ns-part-1_a.C new file mode 100644 index 00000000000..5b761dfb11e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-part-1_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +export module Foo:A; +// { dg-module-cmi {Foo:A} } + +namespace Bob +{ +export int Random (); +} diff --git c/gcc/testsuite/g++.dg/modules/ns-part-1_b.C w/gcc/testsuite/g++.dg/modules/ns-part-1_b.C new file mode 100644 index 00000000000..d5b49b88ea9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-part-1_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +export module Foo:B; +// { dg-module-cmi {Foo:B} } + +export import :A; + +namespace Bob +{ +export int Quux (); +} diff --git c/gcc/testsuite/g++.dg/modules/ns-part-1_c.C w/gcc/testsuite/g++.dg/modules/ns-part-1_c.C new file mode 100644 index 00000000000..ee0ec4018d7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ns-part-1_c.C @@ -0,0 +1,16 @@ +// { dg-additional-options -fmodules-ts } + +export module Foo; +// { dg-module-cmi {Foo} } + +export import :A; +export import :B; + +namespace Bob +{ +export void Widget () +{ + Random (); + Quux (); +} +} diff --git c/gcc/testsuite/g++.dg/modules/nsdmi-1_a.C w/gcc/testsuite/g++.dg/modules/nsdmi-1_a.C new file mode 100644 index 00000000000..8e26d3cf832 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nsdmi-1_a.C @@ -0,0 +1,9 @@ +// { dg-module-do run } +// { dg-additional-options -fmodules-ts } +export module nsdmi; +// { dg-module-cmi nsdmi } + +export struct Bob +{ + int m = 42; +}; diff --git c/gcc/testsuite/g++.dg/modules/nsdmi-1_b.C w/gcc/testsuite/g++.dg/modules/nsdmi-1_b.C new file mode 100644 index 00000000000..032cf5be986 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nsdmi-1_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +import nsdmi; + +int main () +{ + Bob b; + + return b.m != 42; +} diff --git c/gcc/testsuite/g++.dg/modules/nsdmi-2.C w/gcc/testsuite/g++.dg/modules/nsdmi-2.C new file mode 100644 index 00000000000..081c1a154fe --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/nsdmi-2.C @@ -0,0 +1,19 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } +export module foo; +// { dg-module-cmi foo } + + +export enum class file_type : signed char { none = 0 }; + +export class directory_entry +{ +public: + directory_entry(int); + + int _M_path; + + // ICE from deferred_parse NSDMI in as_base class + file_type _M_type = file_type::none; +}; + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::directory_entry'\n \[1\]=decl definition '::directory_entry::__as_base '\n \[2\]=decl declaration '::directory_entry::__ct '\n} module } } diff --git c/gcc/testsuite/g++.dg/modules/omp-1_a.C w/gcc/testsuite/g++.dg/modules/omp-1_a.C new file mode 100644 index 00000000000..722720a0e93 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/omp-1_a.C @@ -0,0 +1,17 @@ +// { dg-additional-options "-fmodules-ts -fopenmp" } + +export module foo; +// { dg-module-cmi foo } + +export inline void frob (unsigned (&ary)[64]) +{ + int sum = 0; + +#pragma omp for + for (unsigned ix = 0; ix < 64; ix++) + sum += ary[ix]; + +#pragma omp simd safelen(16) aligned (ary : 16) + for (unsigned ix = 0; ix < 64; ix++) + ary[ix] *= 2; +} diff --git c/gcc/testsuite/g++.dg/modules/omp-1_b.C w/gcc/testsuite/g++.dg/modules/omp-1_b.C new file mode 100644 index 00000000000..f3f5d92e517 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/omp-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -fopenmp" } + +import foo; + +unsigned ary[64]; + +int main () +{ + frob (ary); +} diff --git c/gcc/testsuite/g++.dg/modules/omp-1_c.C w/gcc/testsuite/g++.dg/modules/omp-1_c.C new file mode 100644 index 00000000000..f30f6115277 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/omp-1_c.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } + +import foo; + +// { dg-regexp "In module imported at \[^\n]*omp-1_c.C:3:1:\nfoo: error: module contains OpenMP, use '-fopenmp' to enable\n" } +// { dg-prune-output "failed to read" } +// { dg-prune-output "fatal error:" } +// { dg-prune-output "compilation terminated" } diff --git c/gcc/testsuite/g++.dg/modules/omp-2_a.C w/gcc/testsuite/g++.dg/modules/omp-2_a.C new file mode 100644 index 00000000000..d2291b6bbe0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/omp-2_a.C @@ -0,0 +1,18 @@ +// { dg-additional-options "-fmodules-ts -fopenmp" } + +export module foo; +// { dg-module-cmi foo } + +// The OpenMPness doesn't escape to the interface. +export void frob (unsigned (&ary)[64]) +{ + int sum = 0; + +#pragma omp for + for (unsigned ix = 0; ix < 64; ix++) + sum += ary[ix]; + +#pragma omp simd safelen(16) aligned (ary : 16) + for (unsigned ix = 0; ix < 64; ix++) + ary[ix] *= 2; +} diff --git c/gcc/testsuite/g++.dg/modules/omp-2_b.C w/gcc/testsuite/g++.dg/modules/omp-2_b.C new file mode 100644 index 00000000000..39f34c70275 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/omp-2_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } + +import foo; + +unsigned ary[64]; + +int main () +{ + frob (ary); +} diff --git c/gcc/testsuite/g++.dg/modules/only-1.C w/gcc/testsuite/g++.dg/modules/only-1.C new file mode 100644 index 00000000000..97dcb1d0cf1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/only-1.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -fmodule-only" } + +export module bob; +// { dg-module-cmi bob } diff --git c/gcc/testsuite/g++.dg/modules/only-2.C w/gcc/testsuite/g++.dg/modules/only-2.C new file mode 100644 index 00000000000..6be8c767d3e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/only-2.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodule-only" } + + +int i; +// { dg-warning "for non-interface" "" { target *-*-* } 0 } diff --git c/gcc/testsuite/g++.dg/modules/only-3.C w/gcc/testsuite/g++.dg/modules/only-3.C new file mode 100644 index 00000000000..a3c61c4bf64 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/only-3.C @@ -0,0 +1,5 @@ +// { dg-options "-fmodule-only" } + + +int i; +// { dg-warning "for non-interface" "" { target *-*-* } 0 } diff --git c/gcc/testsuite/g++.dg/modules/operator-1_a.C w/gcc/testsuite/g++.dg/modules/operator-1_a.C new file mode 100644 index 00000000000..d7a7176eb99 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/operator-1_a.C @@ -0,0 +1,18 @@ +// { dg-additional-options {-fmodules-ts -Wno-pedantic} } + +module; +# 5 __FILE__ 1 + +struct Type {}; +bool operator==(Type const &, Type const &); + +# 10 "" 2 +export module Foo; +// { dg-module-cmi Foo } + +export template +bool equal (T const &x, T const &y) +{ + return x == y; +} + diff --git c/gcc/testsuite/g++.dg/modules/operator-1_b.C w/gcc/testsuite/g++.dg/modules/operator-1_b.C new file mode 100644 index 00000000000..dab8d1093b9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/operator-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options {-fmodules-ts -Wno-pedantic} } + +struct Type {}; + +import Foo; + +bool foo (Type const &t) +{ + return equal (t, t); +} diff --git c/gcc/testsuite/g++.dg/modules/p0713-1.C w/gcc/testsuite/g++.dg/modules/p0713-1.C new file mode 100644 index 00000000000..f7d8006cd58 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/p0713-1.C @@ -0,0 +1,3 @@ +// { dg-additional-options "-fmodules-ts" } +module; +module; // { dg-error "expected" } diff --git c/gcc/testsuite/g++.dg/modules/p0713-2.C w/gcc/testsuite/g++.dg/modules/p0713-2.C new file mode 100644 index 00000000000..c7846e450a9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/p0713-2.C @@ -0,0 +1,3 @@ +// { dg-additional-options "-fmodules-ts" } +int j; +module; // { dg-error "not permitted" } diff --git c/gcc/testsuite/g++.dg/modules/p0713-3.C w/gcc/testsuite/g++.dg/modules/p0713-3.C new file mode 100644 index 00000000000..3c539ebab3e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/p0713-3.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } +int k; +module frob; // { dg-error "not permitted" } +// { dg-prune-output "failed to read" } +// { dg-prune-output "fatal error:" } +// { dg-prune-output "compilation terminated" } diff --git c/gcc/testsuite/g++.dg/modules/part-1_a.C w/gcc/testsuite/g++.dg/modules/part-1_a.C new file mode 100644 index 00000000000..de58a20fab4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-1_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +// { dg-module-cmi foo:baz } + +export module foo:baz; + +export int baz () +{ + return -1; +} diff --git c/gcc/testsuite/g++.dg/modules/part-1_b.C w/gcc/testsuite/g++.dg/modules/part-1_b.C new file mode 100644 index 00000000000..c908c22e395 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-1_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +export import :baz; + +export int foo (int a) +{ + return a; +} diff --git c/gcc/testsuite/g++.dg/modules/part-1_c.C w/gcc/testsuite/g++.dg/modules/part-1_c.C new file mode 100644 index 00000000000..88b033036dc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-1_c.C @@ -0,0 +1,14 @@ +// { dg-additional-options -fmodules-ts } + +import foo; + +int main () +{ + if (baz () != -1) + return 1; + + if (foo (42) != 42) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/part-2_a.C w/gcc/testsuite/g++.dg/modules/part-2_a.C new file mode 100644 index 00000000000..60fbe9942e5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-2_a.C @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodules-ts } + +export module foo:inter; +// { dg-module-cmi foo:inter } diff --git c/gcc/testsuite/g++.dg/modules/part-2_b.C w/gcc/testsuite/g++.dg/modules/part-2_b.C new file mode 100644 index 00000000000..c9bbac8e5e1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-2_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } + +module foo:imp; +// { dg-module-cmi foo:imp } + +import :inter; // ok diff --git c/gcc/testsuite/g++.dg/modules/part-2_c.C w/gcc/testsuite/g++.dg/modules/part-2_c.C new file mode 100644 index 00000000000..759f1c9260c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-2_c.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +export module foo:inter2; +// { dg-module-cmi foo:inter2 } + +import :imp; // ok + +import :inter; // ok at this point diff --git c/gcc/testsuite/g++.dg/modules/part-2_d.C w/gcc/testsuite/g++.dg/modules/part-2_d.C new file mode 100644 index 00000000000..b2e72891bc4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-2_d.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi !foo } + +import :imp; // ok + +export import :inter2; // ok + +// { dg-regexp "In module imported at \[^\n]*part-2_b.C:6:.,\nof module foo:imp, imported at \[^\n]*part-2_d.C:6:\nfoo:inter: error: interface partition is not exported\n" } diff --git c/gcc/testsuite/g++.dg/modules/part-2_e.C w/gcc/testsuite/g++.dg/modules/part-2_e.C new file mode 100644 index 00000000000..677c066ad6b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-2_e.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +import :imp; // ok + +export import :inter2; // ok + +export import :inter; // ok now + diff --git c/gcc/testsuite/g++.dg/modules/part-3_a.C w/gcc/testsuite/g++.dg/modules/part-3_a.C new file mode 100644 index 00000000000..85100d27123 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-3_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } +export module foo:bar; +// { dg-module-cmi foo:bar } + +int foo (int x) +{ + return -x; +} diff --git c/gcc/testsuite/g++.dg/modules/part-3_b.C w/gcc/testsuite/g++.dg/modules/part-3_b.C new file mode 100644 index 00000000000..a60ad3ee997 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-3_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } + +export module foo:baz; +// { dg-module-cmi foo:baz } + +int foo (int); diff --git c/gcc/testsuite/g++.dg/modules/part-3_c.C w/gcc/testsuite/g++.dg/modules/part-3_c.C new file mode 100644 index 00000000000..aff74766436 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-3_c.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-alias" } + +export module foo; +// { dg-module-cmi foo } + +export import :bar; +export import :baz; + +export inline int frob (int x) +{ + return foo (x); +} + +// { dg-final { scan-lang-dump {Read:-[0-9]'s named merge key \(new\) function_decl:'::foo'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]'s named merge key \(matched\) function_decl:'::foo'} module } } +// { dg-final { scan-lang-dump {Cluster sections are \[1,3\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/part-3_d.C w/gcc/testsuite/g++.dg/modules/part-3_d.C new file mode 100644 index 00000000000..d07274a3fa7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-3_d.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-alias" } +import foo; + +int main () +{ + int r = frob (75); + return !(r == -75); +} + +// { dg-final { scan-lang-dump { Read:-[0-9]'s named merge key \(unique\) function_decl:'::frob'} module } } +// { dg-final { scan-lang-dump {> Read:-[0-9]'s named merge key \(unique\) function_decl:'::foo'} module } } diff --git c/gcc/testsuite/g++.dg/modules/part-4_a.C w/gcc/testsuite/g++.dg/modules/part-4_a.C new file mode 100644 index 00000000000..edd606bbcdc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-4_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +export module foo:part1; +// { dg-module-cmi {foo:part1} } + +struct frob { + struct inner {}; +}; diff --git c/gcc/testsuite/g++.dg/modules/part-4_b.C w/gcc/testsuite/g++.dg/modules/part-4_b.C new file mode 100644 index 00000000000..a200ecac3d6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-4_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } +// detecting an ICE in dumping machinery + +export module foo; +// { dg-module-cmi foo } + +export import :part1; + +export frob foo () +{ + return frob (); +} diff --git c/gcc/testsuite/g++.dg/modules/part-4_c.C w/gcc/testsuite/g++.dg/modules/part-4_c.C new file mode 100644 index 00000000000..1f319cccf20 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-4_c.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +import foo; + +void f () +{ + auto f = foo (); + + decltype (f)::inner x; +} diff --git c/gcc/testsuite/g++.dg/modules/part-6_a.C w/gcc/testsuite/g++.dg/modules/part-6_a.C new file mode 100644 index 00000000000..8fece83349e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-6_a.C @@ -0,0 +1,15 @@ +// { dg-module-do link } +// { dg-additional-options -fmodules-ts } + +export module foo:exp; +// { dg-module-cmi foo:exp } + +export class Foo +{ + Foo (); + +public: + void Func (); + + static Foo *Factory (); +}; diff --git c/gcc/testsuite/g++.dg/modules/part-6_b.C w/gcc/testsuite/g++.dg/modules/part-6_b.C new file mode 100644 index 00000000000..0bad008db9e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-6_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +export import :exp; diff --git c/gcc/testsuite/g++.dg/modules/part-6_c.C w/gcc/testsuite/g++.dg/modules/part-6_c.C new file mode 100644 index 00000000000..395e7096683 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-6_c.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } +module foo:bits; +import :exp; + +void Foo::Func () +{ +} + +inline Foo::Foo () +{ +} diff --git c/gcc/testsuite/g++.dg/modules/part-6_d.C w/gcc/testsuite/g++.dg/modules/part-6_d.C new file mode 100644 index 00000000000..71783a6a360 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-6_d.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } +module foo; +import :bits; + +Foo *Foo::Factory () +{ + return new Foo (); +} diff --git c/gcc/testsuite/g++.dg/modules/part-6_e.C w/gcc/testsuite/g++.dg/modules/part-6_e.C new file mode 100644 index 00000000000..6c1ba4c0995 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-6_e.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +import foo; + +int main () +{ + Foo::Factory ()->Func (); +} diff --git c/gcc/testsuite/g++.dg/modules/part-7_a.C w/gcc/testsuite/g++.dg/modules/part-7_a.C new file mode 100644 index 00000000000..32b10f4b6be --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-7_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +export module foo:bill; +// { dg-module-cmi foo:bill } + +export class frob; + +export template class FROB; diff --git c/gcc/testsuite/g++.dg/modules/part-7_b.C w/gcc/testsuite/g++.dg/modules/part-7_b.C new file mode 100644 index 00000000000..9a7eb134b1a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-7_b.C @@ -0,0 +1,20 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-blocks} } + +module foo:bob; +// { dg-module-cmi foo:bob } + +class frob +{ +public: + int field; +}; + +template +class FROB +{ +public: + static constexpr int val = J; +}; + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::frob'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::template FROB'} module } } diff --git c/gcc/testsuite/g++.dg/modules/part-7_c.C w/gcc/testsuite/g++.dg/modules/part-7_c.C new file mode 100644 index 00000000000..4e1df2af020 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-7_c.C @@ -0,0 +1,19 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-blocks} } + +export module foo; +// { dg-module-cmi foo } +import :bob; +export import :bill; + +int foo (frob *p) +{ + return p->field; +} + +int foo (FROB<2> *p) +{ + return p->val; +} + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::frob@foo:bob:1'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::template FROB@foo:bob:1'} module } } diff --git c/gcc/testsuite/g++.dg/modules/part-hdr-1_a.H w/gcc/testsuite/g++.dg/modules/part-hdr-1_a.H new file mode 100644 index 00000000000..62f3b7d4e69 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-hdr-1_a.H @@ -0,0 +1,3 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + diff --git c/gcc/testsuite/g++.dg/modules/part-hdr-1_b.C w/gcc/testsuite/g++.dg/modules/part-hdr-1_b.C new file mode 100644 index 00000000000..93759097f24 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-hdr-1_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +// { dg-module-cmi {mod:impl} } + +module; +# 6 "inner" 1 +import "part-hdr-1_a.H"; +# 8 "" 2 +module mod:impl; + diff --git c/gcc/testsuite/g++.dg/modules/part-hdr-1_c.C w/gcc/testsuite/g++.dg/modules/part-hdr-1_c.C new file mode 100644 index 00000000000..78a53d2fda3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-hdr-1_c.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +// { dg-module-cmi {mod} } + +export module mod; +import mod:impl; diff --git c/gcc/testsuite/g++.dg/modules/part-mac-1_a.H w/gcc/testsuite/g++.dg/modules/part-mac-1_a.H new file mode 100644 index 00000000000..191525dc44d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-mac-1_a.H @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +#define FOO(X) int X + diff --git c/gcc/testsuite/g++.dg/modules/part-mac-1_b.C w/gcc/testsuite/g++.dg/modules/part-mac-1_b.C new file mode 100644 index 00000000000..2adc3b08c0c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-mac-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +// { dg-module-cmi {mod:impl} } + +module; +# 6 "inner" 1 +import "part-mac-1_a.H"; +# 8 "" 2 +module mod:impl; + +FOO(k); diff --git c/gcc/testsuite/g++.dg/modules/part-mac-1_c.C w/gcc/testsuite/g++.dg/modules/part-mac-1_c.C new file mode 100644 index 00000000000..78a53d2fda3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/part-mac-1_c.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts" } +// { dg-module-cmi {mod} } + +export module mod; +import mod:impl; diff --git c/gcc/testsuite/g++.dg/modules/partial-1.h w/gcc/testsuite/g++.dg/modules/partial-1.h new file mode 100644 index 00000000000..0f911076762 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/partial-1.h @@ -0,0 +1,30 @@ + +template +class allocator {}; + +template struct allocator_traits; + +template +struct allocator_traits > +{ + using pointer = _Tp*; +}; + +struct mutex {}; + +template +class Inplace +{ +public: + virtual void _M_dispose() noexcept + { + // bogus error ambiguous partial specializations + typename allocator_traits<_Alloc>::pointer v; + } +}; + +inline void * +allocate_shared() +{ + return new Inplace> (); +} diff --git c/gcc/testsuite/g++.dg/modules/partial-1_a.H w/gcc/testsuite/g++.dg/modules/partial-1_a.H new file mode 100644 index 00000000000..164a54c8c9e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/partial-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "partial-1.h" diff --git c/gcc/testsuite/g++.dg/modules/partial-1_b.C w/gcc/testsuite/g++.dg/modules/partial-1_b.C new file mode 100644 index 00000000000..7e981eb0be4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/partial-1_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } + +#include "partial-1.h" +import "partial-1_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/pmf-1.h w/gcc/testsuite/g++.dg/modules/pmf-1.h new file mode 100644 index 00000000000..e4c99f5e6f1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pmf-1.h @@ -0,0 +1,10 @@ + +struct X +{ + int mfn (); +}; + +inline void bob (X &) +{ + int (X::*pmf) () = &X::mfn; +} diff --git c/gcc/testsuite/g++.dg/modules/pmf-1_a.H w/gcc/testsuite/g++.dg/modules/pmf-1_a.H new file mode 100644 index 00000000000..c597db1fe8a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pmf-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "pmf-1.h" diff --git c/gcc/testsuite/g++.dg/modules/pmf-1_b.C w/gcc/testsuite/g++.dg/modules/pmf-1_b.C new file mode 100644 index 00000000000..0b086107045 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pmf-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "pmf-1.h" +import "pmf-1_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// The function-scope var is unique +// { dg-final { scan-lang-dump-times {merge key \(unique\)} 1 module } } diff --git c/gcc/testsuite/g++.dg/modules/pmf-2.h w/gcc/testsuite/g++.dg/modules/pmf-2.h new file mode 100644 index 00000000000..890b9856c43 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pmf-2.h @@ -0,0 +1,26 @@ +template +struct remove_reference +{ typedef _Tp FOO; }; + +template +void forward (typename remove_reference<_Tp>::FOO const& __t) +{ +} + +template +void __invoke(_Callable const & __fn) +{ + forward<_Callable const>(__fn); +} + +class _State_baseV2 +{ +public: + void _M_set_result() + { + __invoke (&_State_baseV2::_M_do_set); + } + + void _M_do_set(); +}; + diff --git c/gcc/testsuite/g++.dg/modules/pmf-2_a.H w/gcc/testsuite/g++.dg/modules/pmf-2_a.H new file mode 100644 index 00000000000..b6bd763b745 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pmf-2_a.H @@ -0,0 +1,6 @@ +// { dg-additional-options {-fmodule-header -fdump-lang-module-uid} } +// { dg-module-cmi {} } + +#include "pmf-2.h" + +// { dg-final { scan-lang-dump-times {Written:-[0-9]* ptrmem type} 1 module } } diff --git c/gcc/testsuite/g++.dg/modules/pmf-2_b.C w/gcc/testsuite/g++.dg/modules/pmf-2_b.C new file mode 100644 index 00000000000..b76f090ff7b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pmf-2_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-uid" } + +#include "pmf-2.h" +import "pmf-2_a.H"; + +// { dg-final { scan-lang-dump {Cloned:-[0-9]* typedef template_type_parm:'::template remove_reference<_Tp>::template FOO<_Tp>'} module } } +// { dg-final { scan-lang-dump {Created:-[0-9]* ptrmem type} module } } diff --git c/gcc/testsuite/g++.dg/modules/pmp-1_a.C w/gcc/testsuite/g++.dg/modules/pmp-1_a.C new file mode 100644 index 00000000000..2832692faa6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pmp-1_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +export module bob; +// { dg-module-cmi bob } +int k; + +module :private; // { dg-message "sorry, unimplemented: private module fragment" } +int i; diff --git c/gcc/testsuite/g++.dg/modules/pmp-1_b.C w/gcc/testsuite/g++.dg/modules/pmp-1_b.C new file mode 100644 index 00000000000..40cb0fa5278 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pmp-1_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodules-ts } + +module bob; +int k; + +module :private; // { dg-error "private module fragment" } +int i; diff --git c/gcc/testsuite/g++.dg/modules/pmp-2.C w/gcc/testsuite/g++.dg/modules/pmp-2.C new file mode 100644 index 00000000000..56ce48f9a7f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pmp-2.C @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodules-ts } + +export module bob; +// { dg-module-cmi bob } + +module :private; // { dg-message "sorry, unimplemented: private module fragment" } +int i; diff --git c/gcc/testsuite/g++.dg/modules/pmp-3.C w/gcc/testsuite/g++.dg/modules/pmp-3.C new file mode 100644 index 00000000000..8c68bbe89a3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pmp-3.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } + +int k; + +module :private; // { dg-error "private module fragment" } +int i; diff --git c/gcc/testsuite/g++.dg/modules/pragma-1_a.H w/gcc/testsuite/g++.dg/modules/pragma-1_a.H new file mode 100644 index 00000000000..6eb0a5900a7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pragma-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } + +// { dg-module-cmi {} } +int i; diff --git c/gcc/testsuite/g++.dg/modules/pragma-1_b.C w/gcc/testsuite/g++.dg/modules/pragma-1_b.C new file mode 100644 index 00000000000..55d5de3d537 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pragma-1_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } + +#pragma GCC visibility push (default) +#pragma GCC visibility pop + +import "pragma-1_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/predef-1.C w/gcc/testsuite/g++.dg/modules/predef-1.C new file mode 100644 index 00000000000..07a85b0e6b1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/predef-1.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts -nostdinc -include [srcdir]/predef-1.h" } +// { dg-additional-files predef-1.C } + +// test macro expansion inside forced header + +export module bob; diff --git c/gcc/testsuite/g++.dg/modules/predef-1.h w/gcc/testsuite/g++.dg/modules/predef-1.h new file mode 100644 index 00000000000..ab366d59a5a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/predef-1.h @@ -0,0 +1,10 @@ + +// expands a macro (inside #if conditional) inside forced header. +// modelled on glibc's stdc_predef.h + +#define GCC_IEC_559 1 + +# if GCC_IEC_559 > 0 +# define STDC_IEC_559__ 1 +# endif + diff --git c/gcc/testsuite/g++.dg/modules/predef-2.h w/gcc/testsuite/g++.dg/modules/predef-2.h new file mode 100644 index 00000000000..79486f1a253 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/predef-2.h @@ -0,0 +1,7 @@ + +// expands a macro (inside #if conditional) inside forced header. +// modelled on glibc's stdc_predef.h + +// some builtin macro +# if __GNUC__ > 0 +# endif diff --git c/gcc/testsuite/g++.dg/modules/predef-2_a.C w/gcc/testsuite/g++.dg/modules/predef-2_a.C new file mode 100644 index 00000000000..bbf83440cce --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/predef-2_a.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -nostdinc -include [srcdir]/predef-2.h" } +// { dg-additional-files predef-2.h } + +// test macro expansion inside forced header + +export module bob:part; +// { dg-module-cmi bob:part } diff --git c/gcc/testsuite/g++.dg/modules/predef-2_b.C w/gcc/testsuite/g++.dg/modules/predef-2_b.C new file mode 100644 index 00000000000..d0dfb885933 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/predef-2_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -nostdinc -include [srcdir]/predef-2.h" } +// { dg-additional-files predef-2.h } + +// test macro expansion inside forced header + +export module bob; +// { dg-module-cmi bob } + +export import :part; diff --git c/gcc/testsuite/g++.dg/modules/preproc-1.C w/gcc/testsuite/g++.dg/modules/preproc-1.C new file mode 100644 index 00000000000..e7ba6d6f02b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/preproc-1.C @@ -0,0 +1,3 @@ +# 0 "preproc-1.C" +// { dg-additional-options "-fmodule-header -fpreprocessed" } +// { dg-module-cmi {=gcm.cache/,/preproc-1.C.gcm} } diff --git c/gcc/testsuite/g++.dg/modules/preproc-2_a.H w/gcc/testsuite/g++.dg/modules/preproc-2_a.H new file mode 100644 index 00000000000..8e81fb51a83 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/preproc-2_a.H @@ -0,0 +1,11 @@ +# 0 "preproc-2_a.H" +# 0 "" +#define __STDC__ 1 +# 0 "" +#define NAME bob +# 1 "preproc-2_a.H" +# 8 "preproc-2_a.H" +void NAME (); + +// { dg-additional-options "-fmodules-ts -fpreprocessed -fdirectives-only" } +// { dg-module-cmi {,/preproc-2_a.H} } diff --git c/gcc/testsuite/g++.dg/modules/preproc-2_b.C w/gcc/testsuite/g++.dg/modules/preproc-2_b.C new file mode 100644 index 00000000000..8ce21fdcdba --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/preproc-2_b.C @@ -0,0 +1,21 @@ +# 0 "preproc-2_b.C" +# 0 "" +#define __STDC__ 1 +# 0 "" +# 1 "preproc-2_b.C" +# 7 "preproc-2_b.C" +import "./preproc-2_a.H"; + +#define NAME bill + +int NAME = 4; + +int bob; // error with header + +float NAME; // error with self + +// { dg-additional-options "-fmodules-ts -fpreprocessed -fdirectives-only" } + +// { dg-regexp {preproc-2_b.C:13:5: error: 'int bob' redeclared as different kind of entity\nIn module ./preproc-2_a.H, imported at preproc-2_b.C:7:\n: note: previous declaration 'void bob\(\)'\npreproc-2_a.H:8:6: note: in expansion of macro 'NAME'} } + +// { dg-regexp {preproc-2_b.C:9:14: error: conflicting declaration 'float bill'\npreproc-2_b.C:15:7: note: in expansion of macro 'NAME'\npreproc-2_b.C:9:14: note: previous declaration as 'int bill'\npreproc-2_b.C:11:5: note: in expansion of macro 'NAME'} } diff --git c/gcc/testsuite/g++.dg/modules/printf-1_a.H w/gcc/testsuite/g++.dg/modules/printf-1_a.H new file mode 100644 index 00000000000..900c0631515 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/printf-1_a.H @@ -0,0 +1,9 @@ +// { dg-module-do run } +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +extern "C" +{ + // this matches an anticipated fn + extern int printf (const char *__restrict, ...); +} diff --git c/gcc/testsuite/g++.dg/modules/printf-1_b.C w/gcc/testsuite/g++.dg/modules/printf-1_b.C new file mode 100644 index 00000000000..a434e762833 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/printf-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } +import "printf-1_a.H"; + +int main () +{ + printf ("hello world!\n"); + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/reparent-1_a.C w/gcc/testsuite/g++.dg/modules/reparent-1_a.C new file mode 100644 index 00000000000..c5450985ecc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/reparent-1_a.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } +// { dg-module-cmi foo } + + +export module foo; +export void v (); diff --git c/gcc/testsuite/g++.dg/modules/reparent-1_b.C w/gcc/testsuite/g++.dg/modules/reparent-1_b.C new file mode 100644 index 00000000000..b44ae1cafb3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/reparent-1_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options {-fmodules-ts -Wno-pedantic} } +// { dg-module-cmi bar } + + +module; +# 7 "gmf1" 1 +# 8 "gmf2" 1 +# 9 "gmf3" 1 +import foo; +# 11 "" 2 +# 12 "" 2 +# 13 "" 2 +export module bar; +export import foo; diff --git c/gcc/testsuite/g++.dg/modules/reparent-1_c.C w/gcc/testsuite/g++.dg/modules/reparent-1_c.C new file mode 100644 index 00000000000..e4e984c87a9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/reparent-1_c.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +import bar; + +int main () +{ + v (0); // { dg-error "too many arguments" } +} + +// { dg -regexp {In module foo, imported at [^\n]*/reparent-1_b.C:14,\nof module bar, imported at [^\n]*/reparent-1_c.C:2:\n[^\n]*/reparent-1_a.C:6:13: note: declared here\n} } diff --git c/gcc/testsuite/g++.dg/modules/scc-1.C w/gcc/testsuite/g++.dg/modules/scc-1.C new file mode 100644 index 00000000000..a5d71f358c3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/scc-1.C @@ -0,0 +1,16 @@ +// Check SCC regions are atomic +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } + +export module foo; +// { dg-module-cmi foo } + +export int bar (int); +export int baz (int = bar (1)); +export int bar (int = baz (1)); + +// The ordering depends on hash table iteration, which is address-dependent + +// { dg-final { scan-lang-dump { Writing named:-[0-9]* function_decl:'::bar'} "module" } } +// { dg-final { scan-lang-dump { Writing named:-[0-9]* function_decl:'::baz'} "module" } } +// { dg-final { scan-lang-dump { \.[0-9]*\. Wrote backref:-[0-9]* function_decl:'::ba[rz]'} "module" } } +// { dg-final { scan-lang-dump { Wrote backref:-[0-9]* function_decl:'::ba[rz]'} "module" } } diff --git c/gcc/testsuite/g++.dg/modules/scc-2.C w/gcc/testsuite/g++.dg/modules/scc-2.C new file mode 100644 index 00000000000..385f27c45dd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/scc-2.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } +export module frob; +// { dg-module-cmi frob } + +export enum X +{ + One, Two, Three +}; diff --git c/gcc/testsuite/g++.dg/modules/shadow-1_a.C w/gcc/testsuite/g++.dg/modules/shadow-1_a.C new file mode 100644 index 00000000000..e4641aa529d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/shadow-1_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +export module shadow; +// { dg-module-cmi shadow } + +export struct stat +{ +}; + +export void stat (); diff --git c/gcc/testsuite/g++.dg/modules/shadow-1_b.C w/gcc/testsuite/g++.dg/modules/shadow-1_b.C new file mode 100644 index 00000000000..646381237ac --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/shadow-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } +import shadow; + +// unfortunately not the exact same diagnostic in both cases :( + +void stat (); // { dg-error "conflicts with import" } + +struct stat {}; // { dg-error "in a different module" } diff --git c/gcc/testsuite/g++.dg/modules/stat-tpl-1_a.H w/gcc/testsuite/g++.dg/modules/stat-tpl-1_a.H new file mode 100644 index 00000000000..fa4991f264d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/stat-tpl-1_a.H @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template +static inline __attribute__((__always_inline__)) constexpr void +__constant_char_array_p () +{ +} + +inline void foo () +{ + __constant_char_array_p (); +} diff --git c/gcc/testsuite/g++.dg/modules/static-1_a.C w/gcc/testsuite/g++.dg/modules/static-1_a.C new file mode 100644 index 00000000000..6bfced5ec04 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/static-1_a.C @@ -0,0 +1,11 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } + +module; +# 5 "gmf" 1 +static void Bar () {} +# 7 "" 2 +export module Foo; +// { dg-module-cmi Foo } + +static void Baz () {} + diff --git c/gcc/testsuite/g++.dg/modules/static-1_b.C w/gcc/testsuite/g++.dg/modules/static-1_b.C new file mode 100644 index 00000000000..f2f170d49f0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/static-1_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options "-fmodules-ts" } + +module Foo; + +void Frob () +{ + Bar (); // { dg-error "not declared" } + Baz (); // { dg-error "not declared" } +} + +static void Baz () {} +static void Bar () {} + +void Quux () +{ + Bar (); + Baz (); +} diff --git c/gcc/testsuite/g++.dg/modules/static-1_c.C w/gcc/testsuite/g++.dg/modules/static-1_c.C new file mode 100644 index 00000000000..a7ab89aaea7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/static-1_c.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } + +import Foo; + +void Frob () +{ + Bar (); // { dg-error "not declared" } + Baz (); // { dg-error "not declared" } +} + diff --git c/gcc/testsuite/g++.dg/modules/std-1_a.C w/gcc/testsuite/g++.dg/modules/std-1_a.C new file mode 100644 index 00000000000..53bdc7a1cd2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/std-1_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; + +namespace std +{ +int bob; +} diff --git c/gcc/testsuite/g++.dg/modules/std-1_b.C w/gcc/testsuite/g++.dg/modules/std-1_b.C new file mode 100644 index 00000000000..3fa4f40d576 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/std-1_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +int *i = &std::bob; diff --git c/gcc/testsuite/g++.dg/modules/stdns_a.C w/gcc/testsuite/g++.dg/modules/stdns_a.C new file mode 100644 index 00000000000..2d2cdbbc139 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/stdns_a.C @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodules-ts } + +export module std; +// { dg-module-cmi std } + +namespace std +{ +export int frob () +{ + return 1; +} + +} diff --git c/gcc/testsuite/g++.dg/modules/stdns_b.C w/gcc/testsuite/g++.dg/modules/stdns_b.C new file mode 100644 index 00000000000..c00e120b837 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/stdns_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +import std; + +int main () +{ + return !std::frob (); +} diff --git c/gcc/testsuite/g++.dg/modules/sv-1.h w/gcc/testsuite/g++.dg/modules/sv-1.h new file mode 100644 index 00000000000..113ae1bb15a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sv-1.h @@ -0,0 +1,75 @@ +template +struct integral_constant {}; + +typedef integral_constant true_type; +typedef integral_constant false_type; + +template +struct __is_not_void_helper + : public true_type { }; + +template<> struct __is_not_void_helper + : public false_type { }; + +template +struct is_same + : public integral_constant<__is_same_as(_Tp, _Up)> {}; + +template +struct iterator_traits; + +template requires __is_not_void_helper<_Tp>::value +struct iterator_traits<_Tp*>; + +template +struct iterator {}; + +template +class reverse_iterator + : public iterator::value_type> +{ +}; + +template struct _Deque_iterator; + +template void __copy_move_a1(_Deque_iterator<_Tp>); + +template +decltype (NOPE (_Iterator{})) __niter_base (reverse_iterator<_Iterator> __it); + + +template +inline void __copy_move_a (_II __first) +{ + __copy_move_a1 (__niter_base (__first)); +} + +template +struct __gnu_char_traits +{ + static void move (const char* __s2) + { + __copy_move_a (__s2); + } +}; + +class string_view +{ + using t = __gnu_char_traits; + +public: + string_view (const char* __str) noexcept; +}; + +template +void __stoa () +{ + struct _Range_chk { + static bool _S_chk (false_type) { return false; } + static bool _S_chk (true_type) { return true; } + }; + + _Range_chk::_S_chk (is_same<_Ret, long>{}); +} + +inline void stoi () { __stoa (); } diff --git c/gcc/testsuite/g++.dg/modules/sv-1_a.C w/gcc/testsuite/g++.dg/modules/sv-1_a.C new file mode 100644 index 00000000000..8d866fde0b0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sv-1_a.C @@ -0,0 +1,7 @@ +// { dg-additional-options {-fmodules-ts -std=c++2a} } +module; +#include "sv-1.h" +export module Hello; +// { dg-module-cmi Hello } + +export void SayHello (string_view const &name); diff --git c/gcc/testsuite/g++.dg/modules/sv-1_b.C w/gcc/testsuite/g++.dg/modules/sv-1_b.C new file mode 100644 index 00000000000..72dbe593825 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sv-1_b.C @@ -0,0 +1,15 @@ +// { dg-additional-options {-std=c++2a -fmodules-ts -fno-module-lazy} } +#include "sv-1.h" +import Hello; + +#if 0 +int main () +{ + SayHello ("World"); +} +#endif + +void foo () +{ + is_same q; +} diff --git c/gcc/testsuite/g++.dg/modules/sym-subst-1.C w/gcc/testsuite/g++.dg/modules/sym-subst-1.C new file mode 100644 index 00000000000..96ee25c65b5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sym-subst-1.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } +export module bob.stuart.kevin; +// { dg-module-cmi bob.stuart.kevin } + +class mytype +{ +}; + +void frob (mytype &) +{ +} + +// { dg-final { scan-assembler {_ZW3bob6stuart5kevinE4frobRW_2E6mytype:} } } diff --git c/gcc/testsuite/g++.dg/modules/sym-subst-2_a.C w/gcc/testsuite/g++.dg/modules/sym-subst-2_a.C new file mode 100644 index 00000000000..cd0a79dc729 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sym-subst-2_a.C @@ -0,0 +1,15 @@ +// { dg-additional-options "-fmodules-ts" } + +export module bob.stuart; +// { dg-module-cmi bob.stuart } + +template void inner (T &) +{ +} + +export template void foo (T &x) +{ + inner (x); +} + +// { dg-final { scan-assembler-not {all must have scan-assembler} } } diff --git c/gcc/testsuite/g++.dg/modules/sym-subst-2_b.C w/gcc/testsuite/g++.dg/modules/sym-subst-2_b.C new file mode 100644 index 00000000000..fc3db0ac5f8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sym-subst-2_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options "-fmodules-ts" } + +export module bob.kevin; +// { dg-module-cmi bob.kevin } + +import bob.stuart; + +class mytype +{ +}; + +void bar (mytype &m) +{ + foo (m); +} + +// { dg-final { scan-assembler {_ZW3bob5kevinE3barRW_1E6mytype:} } } +// { dg-final { scan-assembler {_ZW3bob6stuartE5innerIW_05kevinE6mytypeEvRT_:} } } diff --git c/gcc/testsuite/g++.dg/modules/sym-subst-3_a.C w/gcc/testsuite/g++.dg/modules/sym-subst-3_a.C new file mode 100644 index 00000000000..bd958dc0dc3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sym-subst-3_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -std=c++17" } +export module t.s; +// { dg-module-cmi t.s } + +struct s; + +export s *S; + +// { dg-final { scan-assembler {.globa?l[ \t]*_?S\n} } } diff --git c/gcc/testsuite/g++.dg/modules/sym-subst-3_b.C w/gcc/testsuite/g++.dg/modules/sym-subst-3_b.C new file mode 100644 index 00000000000..9ae3f8f7816 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sym-subst-3_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -std=c++17" } +export module t; +// { dg-module-cmi t } +import t.s; +struct t; +export void f (t*, decltype (S)){} +// { dg-final { scan-assembler {_Z1fPW1tE1tPW_01sE1s:} } } diff --git c/gcc/testsuite/g++.dg/modules/sym-subst-4.C w/gcc/testsuite/g++.dg/modules/sym-subst-4.C new file mode 100644 index 00000000000..d2266c407f4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sym-subst-4.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts" } +export module zero.eins.zwei.drei.vier.funf.sechs.sieben.acht.neun; +// We're in cologne! +// { dg-module-cmi zero.eins.zwei.drei.vier.funf.sechs.sieben.acht.neun } + +class mytype +{ +}; + +void frob (mytype &) +{ +} + +// { dg-final { scan-assembler {_ZW4zero4eins4zwei4drei4vier4funf5sechs6sieben4acht4neunE4frobRW_9E6mytype:} } } diff --git c/gcc/testsuite/g++.dg/modules/sym-subst-5.C w/gcc/testsuite/g++.dg/modules/sym-subst-5.C new file mode 100644 index 00000000000..1e26e7594ef --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sym-subst-5.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts" } +export module zero.eins.zwei.drei.vier.funf.sechs.sieben.acht.neun.zehn; +// We're in cologne! +// { dg-module-cmi zero.eins.zwei.drei.vier.funf.sechs.sieben.acht.neun.zehn } + +class mytype +{ +}; + +void frob (mytype &) +{ +} + +// { dg-final { scan-assembler {_ZW4zero4eins4zwei4drei4vier4funf5sechs6sieben4acht4neun4zehnE4frobRWW0_E6mytype:} } } diff --git c/gcc/testsuite/g++.dg/modules/sym-subst-6.C w/gcc/testsuite/g++.dg/modules/sym-subst-6.C new file mode 100644 index 00000000000..0a9ac6d8f38 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sym-subst-6.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts" } +export module zero.eins.zwei.drei.vier.funf.sechs.sieben.acht.neun.zehn.elf; +// We're in cologne! +// { dg-module-cmi zero.eins.zwei.drei.vier.funf.sechs.sieben.acht.neun.zehn.elf } + +class mytype +{ +}; + +void frob (mytype &) +{ +} + +// { dg-final { scan-assembler {_ZW4zero4eins4zwei4drei4vier4funf5sechs6sieben4acht4neun4zehn3elfE4frobRWW1_E6mytype:} } } diff --git c/gcc/testsuite/g++.dg/modules/sys/alias-2_a.H w/gcc/testsuite/g++.dg/modules/sys/alias-2_a.H new file mode 100644 index 00000000000..5a058089725 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sys/alias-2_a.H @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodule-header -isystem [srcdir]/sys" } +// { dg-module-cmi {} } + +#ifndef ALIAS_2_A_SYS +#define ALIAS_2_A_SYS + +int frob (int); + +#endif diff --git c/gcc/testsuite/g++.dg/modules/sys/inext-1.H w/gcc/testsuite/g++.dg/modules/sys/inext-1.H new file mode 100644 index 00000000000..1ecfe80a39b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/sys/inext-1.H @@ -0,0 +1,2 @@ +#define NEXT bob +int foo (); diff --git c/gcc/testsuite/g++.dg/modules/tdef-1_a.C w/gcc/testsuite/g++.dg/modules/tdef-1_a.C new file mode 100644 index 00000000000..6bec2023f4e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-1_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts" } + +export module tdef; +// { dg-module-cmi tdef } + +export struct A +{ + typedef int I; +}; diff --git c/gcc/testsuite/g++.dg/modules/tdef-1_b.C w/gcc/testsuite/g++.dg/modules/tdef-1_b.C new file mode 100644 index 00000000000..627d67215ec --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } + +import tdef; + +A::I main () +{ + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/tdef-2_a.C w/gcc/testsuite/g++.dg/modules/tdef-2_a.C new file mode 100644 index 00000000000..f7abf3064e3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-2_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules-ts" } + +export module tdef; +// { dg-module-cmi tdef } + +export typedef int I; +typedef int J; + diff --git c/gcc/testsuite/g++.dg/modules/tdef-2_b.C w/gcc/testsuite/g++.dg/modules/tdef-2_b.C new file mode 100644 index 00000000000..128e95ec8b5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-2_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +module tdef; + +I yup; +J yupper; diff --git c/gcc/testsuite/g++.dg/modules/tdef-2_c.C w/gcc/testsuite/g++.dg/modules/tdef-2_c.C new file mode 100644 index 00000000000..387a41d8075 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-2_c.C @@ -0,0 +1,14 @@ +// { dg-additional-options "-fmodules-ts" } + +import tdef; + +I main () +{ + return 0; +} + +J nope; // { dg-error "does not name a type" } + +typedef char J; + +static J ok; diff --git c/gcc/testsuite/g++.dg/modules/tdef-3_a.C w/gcc/testsuite/g++.dg/modules/tdef-3_a.C new file mode 100644 index 00000000000..8cc2276ce8f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-3_a.C @@ -0,0 +1,7 @@ +// { dg-module-do run } + +// { dg-additional-options -fmodules-ts } +export module frob; +// { dg-module-cmi frob } + +export typedef struct { int m; } frob; diff --git c/gcc/testsuite/g++.dg/modules/tdef-3_b.C w/gcc/testsuite/g++.dg/modules/tdef-3_b.C new file mode 100644 index 00000000000..9980acf06e7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-3_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +export module quux; +// { dg-module-cmi quux } +import frob; + +export int foo (frob *p) +{ + return p->m; +} diff --git c/gcc/testsuite/g++.dg/modules/tdef-3_c.C w/gcc/testsuite/g++.dg/modules/tdef-3_c.C new file mode 100644 index 00000000000..378415d5daf --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-3_c.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } + +import frob; +import quux; + +int main () +{ + frob f {2}; + + return !(foo (&f) == 2); +} diff --git c/gcc/testsuite/g++.dg/modules/tdef-4_a.C w/gcc/testsuite/g++.dg/modules/tdef-4_a.C new file mode 100644 index 00000000000..6136b383f77 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-4_a.C @@ -0,0 +1,16 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +export struct pthread_attr_t +// guess where this came from? +{ + int m; +}; +typedef struct pthread_attr_t pthread_attr_t; + +struct bob +{ +}; +export typedef struct bob bob; diff --git c/gcc/testsuite/g++.dg/modules/tdef-4_b.C w/gcc/testsuite/g++.dg/modules/tdef-4_b.C new file mode 100644 index 00000000000..af488e90feb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-4_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } +module foo; + +pthread_attr_t obj1; +struct pthread_attr_t obj2; + +bob obj3; +struct bob obj4; // OK -- we see the implicit typedef diff --git c/gcc/testsuite/g++.dg/modules/tdef-4_c.C w/gcc/testsuite/g++.dg/modules/tdef-4_c.C new file mode 100644 index 00000000000..a85a4d04823 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-4_c.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } + +import foo; +struct pthread_attr_t obj2; +pthread_attr_t obj1; // OK -- we see the implicit typedef + +bob obj4; +// the structure tag is not exported. We find the typedef-name, which +// is ill-formed +struct bob obj5; // { dg-error "using typedef-name" } diff --git c/gcc/testsuite/g++.dg/modules/tdef-5_a.C w/gcc/testsuite/g++.dg/modules/tdef-5_a.C new file mode 100644 index 00000000000..4d23ae14baa --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-5_a.C @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodules-ts } +export module foo; +// { dg-module-cmi foo } + +typedef float _IO_lock_t; + +_IO_lock_t _lock; diff --git c/gcc/testsuite/g++.dg/modules/tdef-5_b.C w/gcc/testsuite/g++.dg/modules/tdef-5_b.C new file mode 100644 index 00000000000..d37b7e28420 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-5_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodules-ts } +module foo; + +_IO_lock_t bob () +{ + return _lock; +} diff --git c/gcc/testsuite/g++.dg/modules/tdef-6_a.H w/gcc/testsuite/g++.dg/modules/tdef-6_a.H new file mode 100644 index 00000000000..aff599476b1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-6_a.H @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +typedef struct x +{ + int __count; +} X; + +typedef struct +{ + int __count; +} __mbstate_t; diff --git c/gcc/testsuite/g++.dg/modules/tdef-6_b.C w/gcc/testsuite/g++.dg/modules/tdef-6_b.C new file mode 100644 index 00000000000..2d12a2c9a2e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-6_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-alias" } + +typedef struct +{ + int __count; +} __mbstate_t; + +typedef struct x +{ + int __count; +} X; + +import "tdef-6_a.H"; + +X y; +__mbstate_t x; + +// { dg-final { scan-lang-dump {Read:-[0-9]'s named merge key \(matched\) type_decl:'::__mbstate_t'} module } } diff --git c/gcc/testsuite/g++.dg/modules/tdef-7.h w/gcc/testsuite/g++.dg/modules/tdef-7.h new file mode 100644 index 00000000000..5bc21e176cb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-7.h @@ -0,0 +1,7 @@ + +constexpr void duration_cast () +{ + // the constexpr's body's clone merely duplicates the TYPE_DECL, it + // doesn't create a kosher typedef + typedef int __to_rep; +} diff --git c/gcc/testsuite/g++.dg/modules/tdef-7_a.H w/gcc/testsuite/g++.dg/modules/tdef-7_a.H new file mode 100644 index 00000000000..9c6db65ba55 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-7_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "tdef-7.h" diff --git c/gcc/testsuite/g++.dg/modules/tdef-7_b.C w/gcc/testsuite/g++.dg/modules/tdef-7_b.C new file mode 100644 index 00000000000..c526ca8dd4f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-7_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias-uid" } + +#include "tdef-7.h" +import "tdef-7_a.H"; + +// { dg-final { scan-lang-dump-times {merge key \(matched\) function_decl:'::duration_cast} 1 module } } +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-times {merge key \(unique\) type_decl:'#null#'} 2 module } } +// { dg-final { scan-lang-dump-times {Cloned:-[0-9]* typedef integer_type:'::duration_cast::__to_rep'} 1 module } } diff --git c/gcc/testsuite/g++.dg/modules/tdef-8_a.C w/gcc/testsuite/g++.dg/modules/tdef-8_a.C new file mode 100644 index 00000000000..3ad20948ad1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-8_a.C @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodules-ts } + +export module bob; +// { dg-module-cmi bob } + +// from tr1/type_traits +export struct __sfinae_types +{ + // anon struct with tdef name + typedef struct { int i; } __two; +}; + diff --git c/gcc/testsuite/g++.dg/modules/tdef-8_b.C w/gcc/testsuite/g++.dg/modules/tdef-8_b.C new file mode 100644 index 00000000000..2cf59d78fde --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-8_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +import bob; + +int frob (__sfinae_types::__two *p) +{ + return p->i; +} diff --git c/gcc/testsuite/g++.dg/modules/tdef-inst-1.h w/gcc/testsuite/g++.dg/modules/tdef-inst-1.h new file mode 100644 index 00000000000..757113c0283 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-inst-1.h @@ -0,0 +1,14 @@ + +template +class basic_string; + +typedef basic_string string; + +template +class basic_string +{ + public: + string Frob (); + + basic_string (int); +}; diff --git c/gcc/testsuite/g++.dg/modules/tdef-inst-1_a.C w/gcc/testsuite/g++.dg/modules/tdef-inst-1_a.C new file mode 100644 index 00000000000..ab302bc1b6b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-inst-1_a.C @@ -0,0 +1,17 @@ +// { dg-additional-options -fmodules-ts } + +// The instantiation of the *definition* of basic_string is used in +// importers, *after* they have instantiated a declaration of it *and* +// created type variants. + +module; + +#include "tdef-inst-1.h" + +export module foo; +// { dg-module-cmi foo } + +export inline int greeter (string const &bob) +{ + return sizeof (bob); // instantiates string +} diff --git c/gcc/testsuite/g++.dg/modules/tdef-inst-1_b.C w/gcc/testsuite/g++.dg/modules/tdef-inst-1_b.C new file mode 100644 index 00000000000..ccf70520464 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tdef-inst-1_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +#include "tdef-inst-1.h" +import foo; + +string Quux () +{ + return 1; // failed to find converting ctor of string +} diff --git c/gcc/testsuite/g++.dg/modules/thunk-1_a.C w/gcc/testsuite/g++.dg/modules/thunk-1_a.C new file mode 100644 index 00000000000..7652400fd13 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/thunk-1_a.C @@ -0,0 +1,23 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +export struct Base +{ + virtual ~Base () {} + int m; +}; + +// Force the creation of implicit members, because we get that wrong +// in the importer and think its imported (as of 2018-11-27 this +// causes an ICE, previously it happened to work in this particular +// testcase. +Base x; + +export struct Derived : virtual Base +{ + ~Derived () {} +}; + +Derived y; diff --git c/gcc/testsuite/g++.dg/modules/thunk-1_b.C w/gcc/testsuite/g++.dg/modules/thunk-1_b.C new file mode 100644 index 00000000000..99eb029d513 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/thunk-1_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options -fmodules-ts } +export module baz; +// { dg-module-cmi baz } + +import foo; + +export struct Container : virtual Derived +{ + Container () {} + ~Container () {} +}; + + + diff --git c/gcc/testsuite/g++.dg/modules/tmpl-part-req-1.h w/gcc/testsuite/g++.dg/modules/tmpl-part-req-1.h new file mode 100644 index 00000000000..09de42923da --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tmpl-part-req-1.h @@ -0,0 +1,15 @@ + +template +struct Trait; + +template +struct Trait<_Iterator, void> {}; + +template +requires true +struct Trait<_Iterator, void> +{ + template struct __diff {}; + + template requires true struct __diff<_Iter> {}; +}; diff --git c/gcc/testsuite/g++.dg/modules/tmpl-part-req-1_a.H w/gcc/testsuite/g++.dg/modules/tmpl-part-req-1_a.H new file mode 100644 index 00000000000..20804d73620 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tmpl-part-req-1_a.H @@ -0,0 +1,3 @@ +// { dg-additional-options "-fmodule-header -std=c++2a" } +// { dg-module-cmi {} } +#include "tmpl-part-req-1.h" diff --git c/gcc/testsuite/g++.dg/modules/tmpl-part-req-1_b.C w/gcc/testsuite/g++.dg/modules/tmpl-part-req-1_b.C new file mode 100644 index 00000000000..4c00d54aee9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tmpl-part-req-1_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-std=c++2a -fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "tmpl-part-req-1.h" +import "tmpl-part-req-1_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/tmpl-part-req-2.h w/gcc/testsuite/g++.dg/modules/tmpl-part-req-2.h new file mode 100644 index 00000000000..0ca05933b11 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tmpl-part-req-2.h @@ -0,0 +1,24 @@ + +template +struct Trait; + +template +struct Trait<_Iterator, void> {}; + +template +requires true && true +struct Trait<_Iterator, void> +{ + template struct __cat {}; + + template requires true struct __cat<_Iter> {}; +}; + +template +requires true +struct Trait<_Iterator, void> +{ + template struct __diff {}; + + template requires true struct __diff<_Iter> {}; +}; diff --git c/gcc/testsuite/g++.dg/modules/tmpl-part-req-2_a.H w/gcc/testsuite/g++.dg/modules/tmpl-part-req-2_a.H new file mode 100644 index 00000000000..66b97ea372b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tmpl-part-req-2_a.H @@ -0,0 +1,3 @@ +// { dg-additional-options "-fmodule-header -std=c++2a" } +// { dg-module-cmi {} } +#include "tmpl-part-req-2.h" diff --git c/gcc/testsuite/g++.dg/modules/tmpl-part-req-2_b.C w/gcc/testsuite/g++.dg/modules/tmpl-part-req-2_b.C new file mode 100644 index 00000000000..1176f6012c7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tmpl-part-req-2_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-std=c++2a -fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "tmpl-part-req-2.h" +import "tmpl-part-req-2_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/token-1.C w/gcc/testsuite/g++.dg/modules/token-1.C new file mode 100644 index 00000000000..50eee4c7ea1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/token-1.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +# 3 __FILE__ 1 +module ; // { dg-error "cannot be in included file" } +export module bob; // { dg-error "cannot be in included file" } +# 6 "" 2 +// { dg-module-cmi !bob } +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/token-2_a.C w/gcc/testsuite/g++.dg/modules/token-2_a.C new file mode 100644 index 00000000000..a1dfbf77367 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/token-2_a.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +# 1 "other_name" +module ; +export module bob; +// { dg-module-cmi bob } diff --git c/gcc/testsuite/g++.dg/modules/token-2_b.C w/gcc/testsuite/g++.dg/modules/token-2_b.C new file mode 100644 index 00000000000..52b7498a26b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/token-2_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options -fmodules-ts } +#define SEMI ; // this is ok since p1857 +import bob SEMI +#define IMPORT import // { dg-error "does not name a type" } +IMPORT bob ; diff --git c/gcc/testsuite/g++.dg/modules/token-3.C w/gcc/testsuite/g++.dg/modules/token-3.C new file mode 100644 index 00000000000..5bab426e2a6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/token-3.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +# 3 __FILE__ 1 +export module bob; // { dg-error "in included file" } +# 6 "" 2 +// { dg-module-cmi !bob } +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/token-4.C w/gcc/testsuite/g++.dg/modules/token-4.C new file mode 100644 index 00000000000..5a852370d66 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/token-4.C @@ -0,0 +1,5 @@ +// { dg-additional-options -fmodules-ts } +#define MODULE module // { dg-error "does not name a type" } +export MODULE bob; // { dg-error "may only occur after" } +// { dg-module-cmi !bob } +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/token-5.C w/gcc/testsuite/g++.dg/modules/token-5.C new file mode 100644 index 00000000000..29d3ec8fd70 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/token-5.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } +module; + +class X; // { dg-error "global module fragment contents" } + +class Y; + +export module frob; +// { dg-module-cmi !frob } +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/tpl-alias-1.h w/gcc/testsuite/g++.dg/modules/tpl-alias-1.h new file mode 100644 index 00000000000..00f2d9b5b2b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-alias-1.h @@ -0,0 +1,70 @@ +template struct pointer_traits; + +template +struct pointer_traits<_Tp*> +{ + template using rebind = _Up*; +}; + +template +using __ptr_rebind = typename pointer_traits<_Ptr>::template rebind<_Tp>; + +template +struct allocator +{ + typedef _Tp value_type; + typedef _Tp* pointer; +}; + +template struct allocator_traits; + +template +struct allocator_traits> +{ + using pointer = _Tp*; + template + using rebind_alloc = allocator<_Up>; +}; + +template +struct __alloc_traits + : allocator_traits<_Alloc> +{ + typedef _Alloc allocator_type; + typedef allocator_traits<_Alloc> _Base_type; + template + struct rebind + { + typedef typename _Base_type::template rebind_alloc<_Tp> other; + }; +}; + +template +struct _Deque_iterator +{ + template + using __iter = _Deque_iterator<_CvTp&, __ptr_rebind<_Ptr, _CvTp>>; + + typedef __ptr_rebind<_Ptr, long> _Elt_pointer; + typedef __ptr_rebind<_Ptr, _Elt_pointer> _Map_pointer; +}; + +template +struct _Deque_base +{ + typedef typename __alloc_traits<_Alloc>::template rebind::other _Tp_alloc_type; + + typedef __alloc_traits<_Tp_alloc_type> _Alloc_traits; + + typedef typename _Alloc_traits::pointer _Ptr; + + typedef _Deque_iterator iterator; + + typedef typename iterator::_Map_pointer _Map_pointer; +}; + + +inline void stack () +{ + _Deque_base> c; +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-alias-1_a.H w/gcc/testsuite/g++.dg/modules/tpl-alias-1_a.H new file mode 100644 index 00000000000..502a649c74d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-alias-1_a.H @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodule-header -fdump-lang-module-alias-uid" } +// { dg-module-cmi {} } + +#include "tpl-alias-1.h" + +// { dg-final { scan-lang-dump {Writing named:-[0-9]* template_decl:'::allocator_traits<::allocator>::template rebind_alloc<_Up>'} module } } +// { dg-final { scan-lang-dump {Writing decl spec:-[0-9]* type_decl:'::allocator_traits<::allocator>::rebind_alloc<_Up>'} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s decl spec merge key \(specialization\) type_decl:'::allocator_traits<::allocator>::rebind_alloc<_Up>'} module } } +// { dg-final { scan-lang-dump {Wrote\(-[0-9]*\) alias template type_decl:'::allocator_traits<::allocator>::rebind_alloc<_Up>'} module } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-alias-1_b.C w/gcc/testsuite/g++.dg/modules/tpl-alias-1_b.C new file mode 100644 index 00000000000..59fd09c0454 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-alias-1_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-uid-alias" } + +#include "tpl-alias-1.h" +import "tpl-alias-1_a.H"; + +// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) template_decl:'::allocator_traits<::allocator>::template rebind_alloc'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s decl spec merge key \(matched\) type_decl:'::allocator_traits<::allocator<_Tp>>::rebind_alloc'} module } } +// { dg-final { scan-lang-dump {Read alias template type_decl:'::allocator_traits<::allocator>::rebind_alloc<_Up>'} module } } +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-ary-1.h w/gcc/testsuite/g++.dg/modules/tpl-ary-1.h new file mode 100644 index 00000000000..2f745afba36 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-ary-1.h @@ -0,0 +1,15 @@ + +int ary[4]; +extern int unb[]; +typedef int z[0]; + + +template +struct __aligned_membuf +{ + unsigned char _M_storage[sizeof(_Tp)]; + _Tp bob[5]; + + typedef _Tp ary[5]; + typedef const ary c_ary; +}; diff --git c/gcc/testsuite/g++.dg/modules/tpl-ary-1_a.H w/gcc/testsuite/g++.dg/modules/tpl-ary-1_a.H new file mode 100644 index 00000000000..0534e9349d1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-ary-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodule-header -Wno-pedantic" } +// { dg-module-cmi {} } + +#include "tpl-ary-1.h" diff --git c/gcc/testsuite/g++.dg/modules/tpl-ary-1_b.C w/gcc/testsuite/g++.dg/modules/tpl-ary-1_b.C new file mode 100644 index 00000000000..c64758085d1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-ary-1_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic -fno-module-lazy -fdump-lang-module-alias" } + +#include "tpl-ary-1.h" +import "tpl-ary-1_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-not {merge key \(unique\)} module } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_a.H w/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_a.H new file mode 100644 index 00000000000..f0aba549dfd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_a.H @@ -0,0 +1,16 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template +inline void Foo () +{ + { + void Frob (); + } + { + void Frob (); + } + { + void Frob (); + } +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_b.C w/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_b.C new file mode 100644 index 00000000000..8b093d4e15a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +import "tpl-extern-fn-1_a.H"; + +int main () +{ + Foo (); +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_a.H w/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_a.H new file mode 100644 index 00000000000..4a6437a85e3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_a.H @@ -0,0 +1,19 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template +inline void Foo () +{ + { + extern int EXTERN_; + EXTERN_++; + } + { + extern int EXTERN_; + EXTERN_++; + } + { + extern int EXTERN_; + EXTERN_++; + } +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_b.C w/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_b.C new file mode 100644 index 00000000000..222418128be --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } + +import "tpl-extern-var-1_a.H"; + +int main () +{ + Foo (); +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-1_a.C w/gcc/testsuite/g++.dg/modules/tpl-friend-1_a.C new file mode 100644 index 00000000000..88bb6e61f0c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-1_a.C @@ -0,0 +1,40 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-graph-blocks" } +// declarations followed by friend injection + +export module foo; +// { dg-module-cmi foo } + +void foo (int, void *); +void foo (float, void *); + +template class TPL +{ + friend void foo (T, void *); // { dg-warning "non-template function" } + + T member; +}; + +template class TPL; // instantiate + +// binding->465500 +// FUNCTION_DECL->465500 +// DECL_TEMPLATE_INFO->NULL +// DECL_USE_TEMPLATE->0 + +// specialization 465500 +// tmpl->333580 template_decl +// the friend decl implicit template + +// args->46b640 tree_vec +// length:1 +// elt:0 real_type + +// do not add this (non-)specialization to the depset table +// the ::foo fns and TPL should be in different depsets +// the friend decl should be streamed as part of TPL's definition + +// { dg-final { scan-lang-dump-not {Connecting declaration decl template_decl:'::foo'} module } } + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl declaration '::foo'\n \[1\]=decl declaration '::foo'\n \[2\]=binding '::foo'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::template TPL'\n( \[.\]=[^\n]*'\n)* \[.\]=binding '::TPL'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::TPL'} module } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-1_b.C w/gcc/testsuite/g++.dg/modules/tpl-friend-1_b.C new file mode 100644 index 00000000000..e4c42d18663 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-1_b.C @@ -0,0 +1,17 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +void foo (int x, void *p) +{ + auto *obj = reinterpret_cast *> (p); + + obj->member = x; +} + +void foo (float x, void *p) +{ + auto *obj = reinterpret_cast *> (p); + + obj->member = x; +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-2_a.C w/gcc/testsuite/g++.dg/modules/tpl-friend-2_a.C new file mode 100644 index 00000000000..3acacf8ee34 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-2_a.C @@ -0,0 +1,20 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-graph-blocks" } +// injection followed by declaration + +export module foo; +// { dg-module-cmi foo } + +template class TPL +{ + friend void foo (T, void *); // { dg-warning "non-template function" } + + T member; +}; + +template class TPL; // instantiate + +void foo (int, void *); + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl definition '::template TPL'\n( \[.\]=[^\n]*'\n)* \[.\]=decl declaration '::template foo'\n( \[.\]=[^\n]*'\n)* \[.\]=binding '::TPL'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl declaration '::foo'\n \[.\]=binding '::foo'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization definition '::TPL'} module } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-2_b.C w/gcc/testsuite/g++.dg/modules/tpl-friend-2_b.C new file mode 100644 index 00000000000..38d89f06b1a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-2_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +module foo; + +void foo (int x, void *p) +{ + auto *obj = reinterpret_cast *> (p); + + obj->member = x; +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-3_a.C w/gcc/testsuite/g++.dg/modules/tpl-friend-3_a.C new file mode 100644 index 00000000000..e71a2588e75 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-3_a.C @@ -0,0 +1,22 @@ +// { dg-additional-options "-fmodules-ts" } +// declarations followed by friend definition injection + +export module foo; +// { dg-module-cmi foo } + +void foo (int, void *); +void foo (float, void *); + +template class TPL +{ + friend void foo (T x, void *p) + { + auto *obj = reinterpret_cast *> (p); + + obj->member = x; + } + + T member; +}; + +template class TPL; // instantiate diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-3_b.C w/gcc/testsuite/g++.dg/modules/tpl-friend-3_b.C new file mode 100644 index 00000000000..accf5d5353c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-3_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +template class TPL; +// (instantiated in interface) template class TPL; + +void m () +{ + // friend definitions instantiated on-demand here + foo (1, 0); + foo (1.0f, 0); +} + diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-4_a.C w/gcc/testsuite/g++.dg/modules/tpl-friend-4_a.C new file mode 100644 index 00000000000..8acf5b91bf8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-4_a.C @@ -0,0 +1,25 @@ +// { dg-additional-options "-fmodules-ts" } +// friend injection then definition injection + +export module foo; +// { dg-module-cmi foo } + +template class TPL +{ + friend void foo (T, void *); // { dg-warning "non-template function" } + + T member; +}; + +template class DEF +{ + friend void foo (U x, void *p) + { + auto *obj = reinterpret_cast *> (p); + + obj->member = x; + } +}; + +template class TPL; // instantiate +template class DEF; // instantiate diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-4_b.C w/gcc/testsuite/g++.dg/modules/tpl-friend-4_b.C new file mode 100644 index 00000000000..3dd8741e42e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-4_b.C @@ -0,0 +1,21 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +template class TPL; +template class DEF; + +void m () +{ + // ADL to find hidden functions + foo (1, (TPL *)0); + foo (1.0f, (TPL *)0); + + // no ADL, no find + { + foo (1, 0); // { dg-error "not declared" } + } + { + foo (1.0f, 0); // { dg-error "not declared" } + } +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-5_a.C w/gcc/testsuite/g++.dg/modules/tpl-friend-5_a.C new file mode 100644 index 00000000000..e894c734efa --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-5_a.C @@ -0,0 +1,14 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +template class basic_ios; + +template +class basic_streambuf +{ + friend class basic_ios<_CharT>; + + _CharT member; +}; diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-5_b.C w/gcc/testsuite/g++.dg/modules/tpl-friend-5_b.C new file mode 100644 index 00000000000..adbe85d47fd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-5_b.C @@ -0,0 +1,23 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +module foo; + +template class basic_streambuf; + +template class basic_ios +{ +public: + static void frob (basic_streambuf<_CharT> *p, _CharT val) + { + p->member = val; + } +}; + +void bill (basic_streambuf *p) +{ + basic_ios::frob (p, 5); +} + +// { dg-final { scan-lang-dump {Lazily binding '::basic_streambuf'@'foo' section:} module } } +// { dg-final { scan-lang-dump {Loading entity foo\[0\] section:1} module } } +// { dg-final { scan-lang-dump {Loading entity foo\[1\] section:2} module } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-6_a.C w/gcc/testsuite/g++.dg/modules/tpl-friend-6_a.C new file mode 100644 index 00000000000..cc07c60a512 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-6_a.C @@ -0,0 +1,26 @@ +// { dg-additional-options -fmodules-ts } +// befriending a specialization + +export module foo; +// { dg-module-cmi foo } + +namespace not_std { + +template +class basic_streambuf; + +template +void __copy_streambufs_eof(basic_streambuf*); + +template +class basic_streambuf +{ + friend void __copy_streambufs_eof<>(basic_streambuf*); + + T member; +}; + +template<> +void +__copy_streambufs_eof(basic_streambuf* __sbin); +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-6_b.C w/gcc/testsuite/g++.dg/modules/tpl-friend-6_b.C new file mode 100644 index 00000000000..942fe7045bb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-6_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodules-ts } +module foo; + +namespace not_std { + +template<> +void +__copy_streambufs_eof(basic_streambuf* __sbin) +{ + __sbin->member = 0; +} + +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-7_a.C w/gcc/testsuite/g++.dg/modules/tpl-friend-7_a.C new file mode 100644 index 00000000000..bf13cf79ff9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-7_a.C @@ -0,0 +1,16 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +template +class new_allocator +{ + template + friend bool + operator!=(const new_allocator&, const new_allocator<_Up>&) + noexcept + { return false; } +}; + +new_allocator x; diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-7_b.C w/gcc/testsuite/g++.dg/modules/tpl-friend-7_b.C new file mode 100644 index 00000000000..e6e4461541a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-7_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +new_allocator y; diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1.cc w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1.cc new file mode 100644 index 00000000000..a4a1d211e3a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1.cc @@ -0,0 +1,6 @@ +void __istream_extract (int) +{ + (void)basic_streambuf::field; + (void)basic_streambuf::field; + (void)basic_streambuf::field; +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1.h w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1.h new file mode 100644 index 00000000000..fd455363d9f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1.h @@ -0,0 +1,9 @@ + +template +class basic_streambuf +{ + friend void __istream_extract (int); + + // something private + static constexpr int field = 5; +}; diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_a.H w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_a.H new file mode 100644 index 00000000000..566b8604929 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_a.H @@ -0,0 +1,6 @@ +// { dg-additional-options {-fmodule-header -W} } + +// { dg-module-cmi {} } + +#include "tpl-friend-merge-1.h" +extern template class basic_streambuf; diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_b.H w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_b.H new file mode 100644 index 00000000000..b35d8e1f211 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_b.H @@ -0,0 +1,6 @@ +// { dg-additional-options {-fmodule-header -W} } + +// { dg-module-cmi {} } + +#include "tpl-friend-merge-1.h" +extern template class basic_streambuf; diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_c.H w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_c.H new file mode 100644 index 00000000000..197b8313bb1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_c.H @@ -0,0 +1,5 @@ +// { dg-additional-options -fmodule-header } + +// { dg-module-cmi {} } + +void __istream_extract (int); diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_d.C w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_d.C new file mode 100644 index 00000000000..e6f46ef7ef7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_d.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +import "tpl-friend-merge-1_a.H"; +import "tpl-friend-merge-1_b.H"; +import "tpl-friend-merge-1_c.H"; + +#include "tpl-friend-merge-1.cc" diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_e.C w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_e.C new file mode 100644 index 00000000000..185242bdb0c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_e.C @@ -0,0 +1,7 @@ +// { dg-additional-options {-fmodules-ts -fno-module-lazy -fdump-lang-module-alias} } + +import "tpl-friend-merge-1_a.H"; +import "tpl-friend-merge-1_c.H"; +import "tpl-friend-merge-1_b.H"; + +#include "tpl-friend-merge-1.cc" diff --git c/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_f.C w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_f.C new file mode 100644 index 00000000000..4ec7cde3699 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-friend-merge-1_f.C @@ -0,0 +1,7 @@ +// { dg-additional-options {-fmodules-ts -fno-module-lazy -fdump-lang-module-alias} } + +import "tpl-friend-merge-1_c.H"; +import "tpl-friend-merge-1_a.H"; +import "tpl-friend-merge-1_b.H"; + +#include "tpl-friend-merge-1.cc" diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-1_a.C w/gcc/testsuite/g++.dg/modules/tpl-spec-1_a.C new file mode 100644 index 00000000000..26350f09856 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-1_a.C @@ -0,0 +1,22 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-graph-blocks} } + +export module TPL; +// { dg-module-cmi TPL } + +export template int foo (T x) +{ + return int (x); +} + +// Body is emitted in module-unit itself +template <> int foo (int y) +{ + return 0; +} + +// { dg-final { scan-lang-dump {Dependencies of specialization function_decl:'::foo'} module } } +// { dg-final { scan-lang-dump-not {Depending definition function_decl:'::foo'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization declaration '::foo'} module } } +// { dg-final { scan-lang-dump {Specialization '::foo' entity:[0-9]* keyed to TPL\[0\] '::template foo'} module } } + +// { dg-final { scan-assembler {_Z3fooIiEiT_:} } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-1_b.C w/gcc/testsuite/g++.dg/modules/tpl-spec-1_b.C new file mode 100644 index 00000000000..1f64fbbbcb8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-1_b.C @@ -0,0 +1,20 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module} } + +import TPL; + +int main () +{ + if (foo (1.0f) != 1) + return 1; + + if (foo (1) != 0) + return 2; + + return 0; +} + +// { dg-final { scan-lang-dump-not {Reading definition function_decl '::foo@TPL:.'} module } } +// { dg-final { scan-lang-dump {Specialization keyed to TPL\[0\] entity:1} module } } +// { dg-final { scan-lang-dump {Reading 1 pending specializations keyed to TPL\[0\] '::template foo@TPL:1'} module } } + +// { dg-final { scan-assembler-not {_Z3fooIiEiT_:} } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-2_a.C w/gcc/testsuite/g++.dg/modules/tpl-spec-2_a.C new file mode 100644 index 00000000000..bb136d9c8f6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-2_a.C @@ -0,0 +1,11 @@ +// { dg-additional-options {-fmodules-ts} } + +export module TPL; +// { dg-module-cmi TPL } + +export template int foo (T x) +{ + return int (x); +} + +// { dg-final { scan-assembler-not {^[a-zA-Z0-9_]*:} } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-2_b.C w/gcc/testsuite/g++.dg/modules/tpl-spec-2_b.C new file mode 100644 index 00000000000..d1374819261 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-2_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-graph-blocks} } + +export module SPEC; + +export import TPL; + +// Body is emitted in module-unit itself +template <> int foo (int y) +{ + return 0; +} + +// { dg-final { scan-lang-dump {Dependencies of specialization function_decl:'::foo'} module } } +// { dg-final { scan-lang-dump-not {Depending definition function_decl:'::foo'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization declaration '::foo'} module } } +// { dg-final { scan-lang-dump {Specialization '::foo' entity:[0-9]* keyed to TPL\[.\] '::template foo@TPL:.'} module } } + +// { dg-final { scan-assembler {_Z3fooIiEiT_:} } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-2_c.C w/gcc/testsuite/g++.dg/modules/tpl-spec-2_c.C new file mode 100644 index 00000000000..3b0a7c733e7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-2_c.C @@ -0,0 +1,19 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module} } + +import SPEC; + +int main () +{ + if (foo (1.0f) != 1) + return 1; + + if (foo (1) != 0) + return 2; + + return 0; +} + +// { dg-final { scan-lang-dump {Reading 1 pending specializations keyed to TPL\[0\] '::template foo@TPL:.'} module } } +// { dg-final { scan-lang-dump-not {Reading definition function_decl '::foo@TPL:.'} module } } + +// { dg-final { scan-assembler-not {_Z3fooIiEiT_:} } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-2_d.C w/gcc/testsuite/g++.dg/modules/tpl-spec-2_d.C new file mode 100644 index 00000000000..4095dea021a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-2_d.C @@ -0,0 +1,27 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module} } + +import TPL; + +int one () +{ + if (foo (1.0f) != 1) + return 1; + return 0; +} + + +import SPEC; + +int two () +{ + if (foo (1) != 0) + return 2; + + return 0; +} + +// { dg-final { scan-lang-dump {Reading 1 pending specializations keyed to TPL\[0\] '::template foo@TPL:.'} module } } +// { dg-final { scan-lang-dump-not {Reading definition function_decl '::foo@TPL:.'} module } } + +// { dg-final { scan-assembler-not {_Z3fooIiEiT_:} } } +// { dg-final { scan-assembler {_Z3fooIfEiT_:} } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-3_a.C w/gcc/testsuite/g++.dg/modules/tpl-spec-3_a.C new file mode 100644 index 00000000000..1f3fb4023c8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-3_a.C @@ -0,0 +1,27 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-graph-blocks} } + +export module TPL; +// { dg-module-cmi TPL } + +export struct frob +{ + int i; + + template void store (T i_) + { + i = int (i_); + } +}; + +// Not inline! +template <> void frob::store (int i_) +{ + i = -i_; +} + +// { dg-final { scan-lang-dump {Dependencies of specialization function_decl:'::frob::store'} module } } +// { dg-final { scan-lang-dump-not {Depending definition function_decl:'::frob::store'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization declaration '::frob::store'} module } } +// { dg-final { scan-lang-dump {Specialization '::frob::store' entity:[0-9]* keyed to TPL\[1\] '::frob::template store'} module } } + +// { dg-final { scan-assembler {_ZN4frob5storeIiEEvT_:} } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-3_b.C w/gcc/testsuite/g++.dg/modules/tpl-spec-3_b.C new file mode 100644 index 00000000000..a9cd8d72308 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-3_b.C @@ -0,0 +1,24 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module} } + +import TPL; + +int main () +{ + frob f; + + f.store (1); + if (f.i != -1) + return 1; + + f.store (1.0f); + if (f.i != 1) + return 2; + + return 0; +} + +// { dg-final { scan-lang-dump {Reading 1 pending specializations keyed to TPL\[1\] '::frob@TPL:.::template store@TPL:.'} module } } +// { dg-final { scan-lang-dump-not {Reading definition function_decl '::frob@TPL:.::store@TPL:.'} module } } + +// { dg-final { scan-assembler-not {_ZN4frob5storeIiEEvT_:} } } + diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-4_a.C w/gcc/testsuite/g++.dg/modules/tpl-spec-4_a.C new file mode 100644 index 00000000000..29e09deebd9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-4_a.C @@ -0,0 +1,19 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-graph-blocks} } + +export module TPL; +// { dg-module-cmi TPL } + +export template +struct X +{ + T f; +}; + +template<> struct X +{ + int m; +}; + +// { dg-final { scan-lang-dump {Dependencies of specialization type_decl:'::X'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n( \[.\]=[^\n]*'\n)* \[.\]=specialization definition '::X'} module } } +// { dg-final { scan-lang-dump {Specialization '::X' entity:[0-9]* keyed to TPL\[0\] '::template X'} module } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-4_b.C w/gcc/testsuite/g++.dg/modules/tpl-spec-4_b.C new file mode 100644 index 00000000000..94ced9bed38 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-4_b.C @@ -0,0 +1,17 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-graph-blocks} } + +import TPL; + +int main () +{ + X q; + + q.m = 5; + + X p; + p.f = 4.0f; + + return 0; +} + +// { dg-final { scan-lang-dump {Reading 1 pending specializations keyed to TPL\[0\] '::template X@TPL:.'} module } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-5_a.C w/gcc/testsuite/g++.dg/modules/tpl-spec-5_a.C new file mode 100644 index 00000000000..08bcac2e078 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-5_a.C @@ -0,0 +1,19 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-graph-blocks} } + +export module TPL; +// { dg-module-cmi TPL } + +export template +struct X +{ + T ary[I]; +}; + +template struct X +{ + T scalar; +}; + +// { dg-final { scan-lang-dump {Dependency on partial template_decl:'::template X' found} module } } +// { dg-final { scan-lang-dump {Cluster members:\n( \[.\][^\n]*'\n)* \[.\]=partial definition '::template X'} module } } +// { dg-final { scan-lang-dump {Specialization '::template X' entity:[0-9]* keyed to TPL\[0\] '::template X'} module } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-5_b.C w/gcc/testsuite/g++.dg/modules/tpl-spec-5_b.C new file mode 100644 index 00000000000..8a1a5575f45 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-5_b.C @@ -0,0 +1,17 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-alias} } + +import TPL; + +int main () +{ + X q; + + q.ary[0] = 5; + + X p; + p.scalar = 4.0f; + + return 0; +} + +// { dg-final { scan-lang-dump {Reading 1 pending specializations keyed to TPL\[0\] '::template X@TPL:.'} module } } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-6_a.C w/gcc/testsuite/g++.dg/modules/tpl-spec-6_a.C new file mode 100644 index 00000000000..111c718b10b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-6_a.C @@ -0,0 +1,22 @@ +// { dg-additional-options "-fmodules-ts" } + +export module foo; +// { dg-module-cmi foo } + +template +struct integral_constant; + +template +struct __is_nt_convertible_helper; + +template +class __is_nt_convertible_helper<_From, _To, false> +{ + template + static void __test_aux(_To1) noexcept; + + template + static + integral_constant (_From1 ()))> + __test(int); +}; diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-6_b.C w/gcc/testsuite/g++.dg/modules/tpl-spec-6_b.C new file mode 100644 index 00000000000..3a1142823bb --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-6_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules-ts" } + +module foo; + +__is_nt_convertible_helper ok; +__is_nt_convertible_helper not_ok; // { dg-error "incomplete" } diff --git c/gcc/testsuite/g++.dg/modules/tpl-spec-7.C w/gcc/testsuite/g++.dg/modules/tpl-spec-7.C new file mode 100644 index 00000000000..71f821df0c4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-spec-7.C @@ -0,0 +1,38 @@ +// { dg-additional-options "-fmodules-ts" } + +export module foo; +// { dg-module-cmi foo } + +typedef unsigned long size_t; + +template +class __make_unsigned_selector; + +class __make_unsigned_selector_base +{ +protected: + template struct _List { }; + + template + struct _List<_Tp, _Up...> : _List<_Up...> + { static constexpr size_t __size = sizeof(_Tp); }; + + template + struct __select; +}; + +template +class __make_unsigned_selector<_Tp, false, true> + : __make_unsigned_selector_base +{ + using _UInts = _List; + + using __unsigned_type = typename __select::__type; +}; + + + + + + diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-friend-1_a.C w/gcc/testsuite/g++.dg/modules/tpl-tpl-friend-1_a.C new file mode 100644 index 00000000000..23ebfde701c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-friend-1_a.C @@ -0,0 +1,15 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +template class TPL +{ + template friend void foo (U); +}; + +template class TPL; + +template void foo (V x) +{ +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-friend-1_b.C w/gcc/testsuite/g++.dg/modules/tpl-tpl-friend-1_b.C new file mode 100644 index 00000000000..276a7d2a2a0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-friend-1_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +void m () +{ + foo ('a'); + foo (0); +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-mem-1_a.C w/gcc/testsuite/g++.dg/modules/tpl-tpl-mem-1_a.C new file mode 100644 index 00000000000..2d58465df33 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-mem-1_a.C @@ -0,0 +1,19 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +template +class outer +{ +public: + template + struct inner + { + typedef outer other; + }; + + using type = T; +}; + +template class outer; diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-mem-1_b.C w/gcc/testsuite/g++.dg/modules/tpl-tpl-mem-1_b.C new file mode 100644 index 00000000000..3e90ac8633d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-mem-1_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +static_assert (sizeof (outer::inner::other::type) == 1); +static_assert (sizeof (outer::inner::other::type) == sizeof (int)); diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-1.h w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-1.h new file mode 100644 index 00000000000..71ee1929a01 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-1.h @@ -0,0 +1,22 @@ +typedef long unsigned int size_t; + +template +struct Replace; + +template class _Template> +struct Replace<_Template, char> +{ + using type = _Template; +}; + +template +struct TPL; + +template +struct Traits +{ + template + using Rebind = typename Replace<_Alloc, _Tp>::type; +}; + +using tdef = Traits>::template Rebind; diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-1_a.H w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-1_a.H new file mode 100644 index 00000000000..ccd450838bc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-1_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "tpl-tpl-merge-1.h" diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-1_b.C w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-1_b.C new file mode 100644 index 00000000000..d953ec3a5b0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-1_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } + +#include "tpl-tpl-merge-1.h" +import "tpl-tpl-merge-1_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-2.h w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-2.h new file mode 100644 index 00000000000..005523ee9a8 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-2.h @@ -0,0 +1,65 @@ +typedef long unsigned int size_t; + +template class allocator; + +template +struct __replace_first_arg +{ }; + +template class _Template, typename _Up, + typename _Tp, typename... _Types> +struct __replace_first_arg<_Template<_Tp, _Types...>, _Up> +{ + using type = _Template<_Up, _Types...>; +}; + +template +using __replace_first_arg_t = typename __replace_first_arg<_Tp, _Up>::type; + +template +class new_allocator +{ +public: + typedef _Tp value_type; +}; + +template +using __allocator_base = new_allocator<_Tp>; + +template +class allocator : public __allocator_base<_Tp> +{ +public: +}; + +struct __allocator_traits_base +{ + template + struct __rebind : __replace_first_arg<_Tp, _Up> { }; +}; + +template +using __alloc_rebind += typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type; + +template +struct allocator_traits : __allocator_traits_base +{ +public: + template + using rebind_alloc = __alloc_rebind<_Alloc, _Tp>; +}; + +template +struct __alloc_traits + +{ + template + struct rebind + { + typedef typename allocator_traits<_Alloc>::template rebind_alloc<_Tp> other; + }; +}; + +typedef typename __alloc_traits>::template +rebind::other _Char_alloc_type; diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-2_a.H w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-2_a.H new file mode 100644 index 00000000000..051c19bf175 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-2_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "tpl-tpl-merge-2.h" diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-2_b.C w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-2_b.C new file mode 100644 index 00000000000..54da419b12b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-merge-2_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } + +#include "tpl-tpl-merge-2.h" +import "tpl-tpl-merge-2_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-1_a.H w/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-1_a.H new file mode 100644 index 00000000000..159efc35786 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-1_a.H @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template class _TQual> +struct basic_common_reference; + +template +struct __xref; + +template +using __basic_common_ref += typename basic_common_reference<__xref<_Tp1>::template __type>::type; diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-1_b.C w/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-1_b.C new file mode 100644 index 00000000000..c8918d6466d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-1_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options -fmodules-ts } + +import "tpl-tpl-parm-1_a.H"; + +template<> struct __xref +{ + template struct __type; +}; + +template<> struct basic_common_reference<__xref::__type> +{ + typedef int type; +}; + +__basic_common_ref main () +{ + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-2.h w/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-2.h new file mode 100644 index 00000000000..16832bf8e7f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-2.h @@ -0,0 +1,16 @@ + + + +template +struct allocator_traits +{ + template class _Func> + struct _Ptr {}; + + using rebind_alloc = int; +}; + +inline void frob () +{ + allocator_traits _M_unpooled; +} diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-2_a.H w/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-2_a.H new file mode 100644 index 00000000000..cec1a67454f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-2_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "tpl-tpl-parm-2.h" diff --git c/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-2_b.C w/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-2_b.C new file mode 100644 index 00000000000..3504e502c56 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-2_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } + +#include "tpl-tpl-parm-2.h" +import "tpl-tpl-parm-2_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/tplmem-1_a.C w/gcc/testsuite/g++.dg/modules/tplmem-1_a.C new file mode 100644 index 00000000000..97e228a8385 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tplmem-1_a.C @@ -0,0 +1,32 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +export module frob; +// { dg-module-cmi "frob" } + +export struct A +{ + A () + { + } + + template operator T () const + { + return T(99); + } +}; + +export template struct B +{ + T m; + + B(T t) : m(t) + { + } + + template operator S () const + { + return S (m); + } +}; + diff --git c/gcc/testsuite/g++.dg/modules/tplmem-1_b.C w/gcc/testsuite/g++.dg/modules/tplmem-1_b.C new file mode 100644 index 00000000000..352ad0c813a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tplmem-1_b.C @@ -0,0 +1,28 @@ +// { dg-additional-options "-fmodules-ts" } + +import frob; + +int main () +{ + A a; + + if (int (a) != 99) + return 1; + if (float (a) != 99) + return 2; + if (static_cast (a) != (void *)99) + return 3; + + B bi(1); + B bf(1.25f); + if (int (bi) != 1) + return 4; + if (int (bf) != 1) + return 5; + + // 1.25 is exactly representable + if (float (bf) != 1.25f) + return 6; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/tplmem-3_a.C w/gcc/testsuite/g++.dg/modules/tplmem-3_a.C new file mode 100644 index 00000000000..9d9cc0af5cd --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tplmem-3_a.C @@ -0,0 +1,17 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +export module billy.bob.thornton; +// { dg-module-cmi "billy.bob.thornton" } + +export template struct Outer +{ + template struct Inner + { + static unsigned m () + { + return I * J; + } + }; +}; + diff --git c/gcc/testsuite/g++.dg/modules/tplmem-3_b.C w/gcc/testsuite/g++.dg/modules/tplmem-3_b.C new file mode 100644 index 00000000000..c5225cac089 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/tplmem-3_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } + +import billy.bob.thornton; + +int main () +{ + Outer<4>::Inner<16> v; + + if (v.m () != 64) + return 1; + return 0; +} + diff --git c/gcc/testsuite/g++.dg/modules/ttp-1_a.C w/gcc/testsuite/g++.dg/modules/ttp-1_a.C new file mode 100644 index 00000000000..eb2d939d2ae --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ttp-1_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } +export module bob; + +export template class TPL, typename T> +struct Wrapper +{ + using type = TPL; +}; diff --git c/gcc/testsuite/g++.dg/modules/ttp-1_b.C w/gcc/testsuite/g++.dg/modules/ttp-1_b.C new file mode 100644 index 00000000000..30a73c0a8cc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ttp-1_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options -fmodules-ts } + +import bob; + +template struct X +{ + using type = T; +}; + +template struct same; +template struct same {}; + +void frob () +{ + using type = Wrapper::type::type; + + same v; +} diff --git c/gcc/testsuite/g++.dg/modules/ttp-2_a.C w/gcc/testsuite/g++.dg/modules/ttp-2_a.C new file mode 100644 index 00000000000..c14aeea3a1b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ttp-2_a.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +template class Arg1> +struct TPL1; + +template class Arg2> +struct TPL2; diff --git c/gcc/testsuite/g++.dg/modules/ttp-2_b.C w/gcc/testsuite/g++.dg/modules/ttp-2_b.C new file mode 100644 index 00000000000..bf0242ac800 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ttp-2_b.C @@ -0,0 +1,18 @@ +// { dg-additional-options -fmodules-ts } + +module foo; + +template class Arg4> +struct TPL1 +{ +}; + +template class Arg4> +struct TPL2 +{ +}; + +template class Arg; + + +template struct TPL1; diff --git c/gcc/testsuite/g++.dg/modules/ttp-3_a.C w/gcc/testsuite/g++.dg/modules/ttp-3_a.C new file mode 100644 index 00000000000..d1f5857cfd6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ttp-3_a.C @@ -0,0 +1,17 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +template typename Arg2> +struct TPL +{ + using type = char; +}; + +/// Implementation of the detection idiom (positive case). +template typename Op> +struct TPL , Op> +{ + using type = int; +}; diff --git c/gcc/testsuite/g++.dg/modules/ttp-3_b.C w/gcc/testsuite/g++.dg/modules/ttp-3_b.C new file mode 100644 index 00000000000..7f61b7c437a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/ttp-3_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules-ts } +module foo; + + +template class Y; + +static_assert (sizeof (TPL, Y>::type) == 1); +static_assert (sizeof (TPL, Y>::type) != 1, "where's my specialization?"); diff --git c/gcc/testsuite/g++.dg/modules/typename-1_a.C w/gcc/testsuite/g++.dg/modules/typename-1_a.C new file mode 100644 index 00000000000..e8b5599f81c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/typename-1_a.C @@ -0,0 +1,13 @@ +// { dg-additional-options -fmodules-ts } + +export module foo; +// { dg-module-cmi foo } + +export template +struct TPL +{ + typename T::type m; + using type = typename T::type; + const type cm; +}; + diff --git c/gcc/testsuite/g++.dg/modules/typename-1_b.C w/gcc/testsuite/g++.dg/modules/typename-1_b.C new file mode 100644 index 00000000000..ba7aecf7a56 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/typename-1_b.C @@ -0,0 +1,15 @@ +// { dg-additional-options -fmodules-ts } + +import foo; + +struct X +{ + using type = int; +}; + +int main () +{ + TPL x {0,1}; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/unnamed-1_a.C w/gcc/testsuite/g++.dg/modules/unnamed-1_a.C new file mode 100644 index 00000000000..8c5674a171a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/unnamed-1_a.C @@ -0,0 +1,20 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +export module PiL; +// { dg-module-cmi PiL } + +int counter = 0; + +export inline int get () +{ + return counter++; +} + +export inline int hwm () +{ + return counter; +} + +// { dg-final { scan-lang-dump {Bindings '::counter' section:1} module } } +// { dg-final { scan-lang-dump-not {horcrux} module } } +// { dg-final { scan-lang-dump-not {Unnamed . '::counter'} module } } diff --git c/gcc/testsuite/g++.dg/modules/unnamed-1_b.C w/gcc/testsuite/g++.dg/modules/unnamed-1_b.C new file mode 100644 index 00000000000..847ced6bcf9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/unnamed-1_b.C @@ -0,0 +1,19 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } + +import PiL; + +// Until the linkage is promoted, this won't link. + +int main () +{ + int i = get (); + if (i) + return 1; + int h = hwm (); + if (h != 1) + return 2; + return 0; +} + +// { dg-final { scan-lang-dump {Bindings '::counter'} module } } +// { dg-final { scan-lang-dump {>Loading entity PiL\[0\] section:1} module } } diff --git c/gcc/testsuite/g++.dg/modules/unnamed-2.C w/gcc/testsuite/g++.dg/modules/unnamed-2.C new file mode 100644 index 00000000000..2b589302e5b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/unnamed-2.C @@ -0,0 +1,19 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } +export module PiL; +// { dg-module-cmi PiL } + +static int counter = 0; + +// These are not inlined, so their bodies don't get into the BMI +export int get () +{ + return counter++; +} + +export int hwm () +{ + return counter; +} + +// { dg-final { scan-lang-dump-not {Bindings '::counter' section:} module } } +// { dg-final { scan-lang-dump-not {Unnamed . '::counter'} module } } diff --git c/gcc/testsuite/g++.dg/modules/used-1_a.H w/gcc/testsuite/g++.dg/modules/used-1_a.H new file mode 100644 index 00000000000..39aacf504a3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/used-1_a.H @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +inline int frob (int x) +{ + return x; +} diff --git c/gcc/testsuite/g++.dg/modules/used-1_b.H w/gcc/testsuite/g++.dg/modules/used-1_b.H new file mode 100644 index 00000000000..05f29dbdf36 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/used-1_b.H @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +import "used-1_a.H"; + +inline int wrapper (int x) +{ + return frob (x); +} diff --git c/gcc/testsuite/g++.dg/modules/used-1_c.C w/gcc/testsuite/g++.dg/modules/used-1_c.C new file mode 100644 index 00000000000..0d1514e031c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/used-1_c.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } + +import "used-1_b.H"; + +int main () +{ + return wrapper (0); +} + +// { dg-final { scan-assembler {_Z4frobi:} } } diff --git c/gcc/testsuite/g++.dg/modules/using-1_a.C w/gcc/testsuite/g++.dg/modules/using-1_a.C new file mode 100644 index 00000000000..010c7fa00f9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-1_a.C @@ -0,0 +1,19 @@ +// { dg-module-do link } +// { dg-additional-options "-fmodules-ts" } +export module frob; +// { dg-module-cmi frob } + +namespace details +{ +void foo () +{ +} +} + +using details::foo; +void footle (); +export void bink () +{ + foo (); + footle (); +} diff --git c/gcc/testsuite/g++.dg/modules/using-1_b.C w/gcc/testsuite/g++.dg/modules/using-1_b.C new file mode 100644 index 00000000000..e36caaf1cc1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-1_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options -fmodules-ts } +module frob; + +void footle () +{ + foo (); +} diff --git c/gcc/testsuite/g++.dg/modules/using-1_c.C w/gcc/testsuite/g++.dg/modules/using-1_c.C new file mode 100644 index 00000000000..d9835bc781d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-1_c.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } + +import frob; + +int main () +{ + bink (); + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/using-2_a.C w/gcc/testsuite/g++.dg/modules/using-2_a.C new file mode 100644 index 00000000000..ef6f5e5ff4a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-2_a.C @@ -0,0 +1,19 @@ +// { dg-additional-options -fmodules-ts } + +export module bob; +// { dg-module-cmi bob } + +namespace N { +export int foo (int a) +{ + return -a; +} +int bar (int a) +{ + return -a; +} +} + +export using N::foo; +using N::bar; + diff --git c/gcc/testsuite/g++.dg/modules/using-2_b.C w/gcc/testsuite/g++.dg/modules/using-2_b.C new file mode 100644 index 00000000000..6181073a1b4 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-2_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options -fmodules-ts } + +module bob; + +int a = foo (1); +int b = bar (2); diff --git c/gcc/testsuite/g++.dg/modules/using-2_c.C w/gcc/testsuite/g++.dg/modules/using-2_c.C new file mode 100644 index 00000000000..c3c06703509 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-2_c.C @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodules-ts } +import bob; + +int a = foo (1); diff --git c/gcc/testsuite/g++.dg/modules/using-3.C w/gcc/testsuite/g++.dg/modules/using-3.C new file mode 100644 index 00000000000..d21512fb20a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-3.C @@ -0,0 +1,17 @@ +// { dg-additional-options -fmodules-ts } +export module bad; +// { dg-module-cmi !bad } + +namespace N +{ +static int foo (); +int bar (); +} + +using N::foo; +using N::bar; + +export using N::foo; // { dg-error "does not have external linkage" } +export using N::bar; // { dg-error "does not have external linkage" } + +// { dg-prune-output "not writing module" } diff --git c/gcc/testsuite/g++.dg/modules/using-4_a.C w/gcc/testsuite/g++.dg/modules/using-4_a.C new file mode 100644 index 00000000000..1eba527f1a0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-4_a.C @@ -0,0 +1,17 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } + +export module bob; +// { dg-module-cmi bob } + +namespace N { +export int foo (); +} + +// Only one using decl exported! +using N::foo; +export using N::foo; + +// { dg-final { scan-lang-dump {Writing section:2 2 depsets} module } } +// { dg-final { scan-lang-dump {Depset:0 using overload:'::N::foo'} module } } +// { dg-final { scan-lang-dump {Depset:1 binding namespace_decl:'::foo'} module } } + diff --git c/gcc/testsuite/g++.dg/modules/using-4_b.C w/gcc/testsuite/g++.dg/modules/using-4_b.C new file mode 100644 index 00000000000..f899f505340 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-4_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } + +import bob; + +int a = foo (); + +// { dg-final { scan-lang-dump {Binding of '::foo'} module } } diff --git c/gcc/testsuite/g++.dg/modules/using-5_a.C w/gcc/testsuite/g++.dg/modules/using-5_a.C new file mode 100644 index 00000000000..88cbaf9d89c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-5_a.C @@ -0,0 +1,15 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } +export module foo; +// { dg-module-cmi foo } + +namespace One { +class X; +} + +namespace Two { +using One::X; +} + + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl declaration '::One::X'\n \[1\]=binding '::One::X'} module } } +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=using declaration '::One::X'\n \[1\]=binding '::Two::X'} module } } diff --git c/gcc/testsuite/g++.dg/modules/using-5_b.C w/gcc/testsuite/g++.dg/modules/using-5_b.C new file mode 100644 index 00000000000..9fbe14e5937 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-5_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } +module foo; + +Two::X *p; diff --git c/gcc/testsuite/g++.dg/modules/using-6_a.C w/gcc/testsuite/g++.dg/modules/using-6_a.C new file mode 100644 index 00000000000..40c32b380ae --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-6_a.C @@ -0,0 +1,20 @@ +// { dg-additional-options -fmodules-ts } + +export module bob; +// { dg-module-cmi bob } + +namespace A +{ +export void swap (int &, int &); +void copy (int &); +} + +export template +void Foo (T & a, T &b) +{ + using A::swap; + swap (a, b); + + using A::copy; + copy (b); +} diff --git c/gcc/testsuite/g++.dg/modules/using-6_b.C w/gcc/testsuite/g++.dg/modules/using-6_b.C new file mode 100644 index 00000000000..feac0cab6b7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-6_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } +import bob; + +int main () +{ + int a = 0, b = 1; + Foo (a, b); + + return 0; +} + diff --git c/gcc/testsuite/g++.dg/modules/using-7.C w/gcc/testsuite/g++.dg/modules/using-7.C new file mode 100644 index 00000000000..01a5ad31984 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-7.C @@ -0,0 +1,17 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-blocks" } + +export module foo; +// { dg-module-cmi foo } + +export namespace __gnu_cxx +{ +enum _Lock_policy { _S_single}; +} + +export namespace std +{ + using __gnu_cxx::_S_single; +} + +// { dg-final { scan-lang-dump {Writing section:1 4 depsets\n Cluster members:\n \[0\]=decl definition '::__gnu_cxx::_Lock_policy'\n \[1\]=using declaration '::__gnu_cxx::_Lock_policy::_S_single'\n \[2\]=binding '::__gnu_cxx::_[A-Za-z_]*'\n \[3\]=binding '::__gnu_cxx::_[A-Za-z_]*'\n} module } } +// { dg-final { scan-lang-dump {Writing section:2 2 depsets\n Cluster members:\n \[0\]=using declaration '::__gnu_cxx::_Lock_policy::_S_single'\n \[1\]=binding '::std::_S_single'\n} module } } diff --git c/gcc/testsuite/g++.dg/modules/using-8_a.C w/gcc/testsuite/g++.dg/modules/using-8_a.C new file mode 100644 index 00000000000..1e71d2d8ccc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-8_a.C @@ -0,0 +1,21 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +module; +# 4 __FILE__ 1 +namespace A +{ +void swap (int &, int &); +void copy (int &); +} +# 10 "" 2 +export module bob; +// { dg-module-cmi bob } + +export template +void Foo (T & a, T &b) +{ + using A::swap; + swap (a, b); + + using A::copy; + copy (b); +} diff --git c/gcc/testsuite/g++.dg/modules/using-8_b.C w/gcc/testsuite/g++.dg/modules/using-8_b.C new file mode 100644 index 00000000000..feac0cab6b7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-8_b.C @@ -0,0 +1,11 @@ +// { dg-additional-options -fmodules-ts } +import bob; + +int main () +{ + int a = 0, b = 1; + Foo (a, b); + + return 0; +} + diff --git c/gcc/testsuite/g++.dg/modules/using-enum-1_a.H w/gcc/testsuite/g++.dg/modules/using-enum-1_a.H new file mode 100644 index 00000000000..a4204b4f6be --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-enum-1_a.H @@ -0,0 +1,16 @@ +// { dg-additional-options {-fmodule-header -std=c++2a} } +// { dg-module-cmi {} } + +enum class E {a, b, c}; +struct C +{ + using enum E; +}; + +struct D: C +{ + int foo () + { + return int (a); + } +}; diff --git c/gcc/testsuite/g++.dg/modules/using-enum-1_b.C w/gcc/testsuite/g++.dg/modules/using-enum-1_b.C new file mode 100644 index 00000000000..af0610ab97b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/using-enum-1_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options {-fmodules-ts -fno-module-lazy -std=c++2a } } + +#include "using-enum-1_a.H" +import "using-enum-1_a.H"; diff --git c/gcc/testsuite/g++.dg/modules/var-1_a.C w/gcc/testsuite/g++.dg/modules/var-1_a.C new file mode 100644 index 00000000000..2a5d6bd0a6c --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/var-1_a.C @@ -0,0 +1,9 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +export module Var; +// { dg-module-cmi Var } + +export int counter = 2; +export extern const int limit = 5; + diff --git c/gcc/testsuite/g++.dg/modules/var-1_b.C w/gcc/testsuite/g++.dg/modules/var-1_b.C new file mode 100644 index 00000000000..9a57f6166f5 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/var-1_b.C @@ -0,0 +1,13 @@ +// { dg-additional-options "-fmodules-ts" } + +import Var; + +int main () +{ + if (counter != 2) + return 1; + if (limit != 5) + return 2; + static_assert (limit == 5, "huh?"); + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/var-tpl-1_a.C w/gcc/testsuite/g++.dg/modules/var-tpl-1_a.C new file mode 100644 index 00000000000..f538304f4a3 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/var-tpl-1_a.C @@ -0,0 +1,21 @@ +// { dg-module-do run } +// { dg-additional-options -fmodules-ts } + +export module frob; +// { dg-module-cmi frob } + +export template T sum (T a) +{ + return a; +} + +export template +inline T sum (T a, R... b) +{ + return a + static_cast (sum (b...)); +} + +export inline int add (int a, int b, int c) +{ + return sum (a, b, c); +} diff --git c/gcc/testsuite/g++.dg/modules/var-tpl-1_b.C w/gcc/testsuite/g++.dg/modules/var-tpl-1_b.C new file mode 100644 index 00000000000..a8c85247d7d --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/var-tpl-1_b.C @@ -0,0 +1,14 @@ +// { dg-additional-options -fmodules-ts } + +import frob; + +int main () +{ + if (6 != add (1, 2, 3)) + return 1; + + if (10 != sum (1, unsigned (2), 3.0f, 4.0)) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/var-tpl-concept-1.h w/gcc/testsuite/g++.dg/modules/var-tpl-concept-1.h new file mode 100644 index 00000000000..1dbd07fbd8e --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/var-tpl-concept-1.h @@ -0,0 +1,70 @@ + +template struct char_traits; + +template> +class basic_string; + +typedef basic_string string; + +template struct iterator_traits; + +template struct conditional; + +template +inline constexpr bool disable_sized_sentinel_for = false; + +template +concept sized_sentinel_for = !disable_sized_sentinel_for<_Iter>; + +template +class __normal_iterator +{ + typedef iterator_traits<_Iterator> __traits_type; +}; + +template +class reverse_iterator +{ +public: + using iterator_concept + = typename conditional>::type; +}; + + +template +requires (!sized_sentinel_for<_Iterator>) +bool disable_sized_sentinel_for> = true; + + +template +bool operator==(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y); +template +bool operator==(const __normal_iterator<_Iterator>& __lhs, + const __normal_iterator<_Iterator>& __rhs); + +template +class common_iterator +{ +public: + friend bool operator==(const common_iterator& __x, + const common_iterator& __y) + { + return __x._M_it == __y._M_it; + } + +private: + _It _M_it; +}; + +template +struct iterator_traits> +{ +}; + +template +struct char_traits +{ + static bool eq(const _CharT& __c1, const _CharT& __c2) + { return __c1 == __c2; } +}; diff --git c/gcc/testsuite/g++.dg/modules/var-tpl-concept-1_a.C w/gcc/testsuite/g++.dg/modules/var-tpl-concept-1_a.C new file mode 100644 index 00000000000..4655e396118 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/var-tpl-concept-1_a.C @@ -0,0 +1,8 @@ +// { dg-additional-options {-fmodules-ts -fconcepts} } +module; +#include "var-tpl-concept-1.h" + +export module foo:part1; +// { dg-module-cmi {foo:part1} } + +export void bar (string &); diff --git c/gcc/testsuite/g++.dg/modules/var-tpl-concept-1_b.C w/gcc/testsuite/g++.dg/modules/var-tpl-concept-1_b.C new file mode 100644 index 00000000000..2c44edeba29 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/var-tpl-concept-1_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options {-fmodules-ts -fconcepts} } +module; +#include "var-tpl-concept-1.h" + +export module foo; +// { dg-module-cmi {foo} } + +export import :part1; + +export void baz (string &); diff --git c/gcc/testsuite/g++.dg/modules/virt-1_a.C w/gcc/testsuite/g++.dg/modules/virt-1_a.C new file mode 100644 index 00000000000..7719a287709 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/virt-1_a.C @@ -0,0 +1,25 @@ +// { dg-module-do run } +// { dg-additional-options -fmodules-ts } +export module foo; +// { dg-module-cmi foo } + +export struct Visitor +{ + virtual int Visit (); +}; + +// Key function explicitly not in line (regardless of p1779's state) +// We emit vtables & rtti only in this TU +int Visitor::Visit () +{ + return 0; +} + +export int Visit (Visitor *v) +{ + return v->Visit (); +} + +// { dg-final { scan-assembler {_ZTV7Visitor:} } } +// { dg-final { scan-assembler {_ZTI7Visitor:} } } +// { dg-final { scan-assembler {_ZTS7Visitor:} } } diff --git c/gcc/testsuite/g++.dg/modules/virt-1_b.C w/gcc/testsuite/g++.dg/modules/virt-1_b.C new file mode 100644 index 00000000000..b4372e19f0f --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/virt-1_b.C @@ -0,0 +1,23 @@ +// { dg-additional-options -fmodules-ts } + +import foo; + +struct Mine : Visitor +{ + int Visit () override + { + return 1; + } +}; + +int main () +{ + Mine me; + + return !(Visit (&me) == 1); +} + +// We do not emit Visitor vtable or rtti here +// { dg-final { scan-assembler-not {_ZTV7Visitor:} } } +// { dg-final { scan-assembler-not {_ZTI7Visitor:} } } +// { dg-final { scan-assembler-not {_ZTS7Visitor:} } } diff --git c/gcc/testsuite/g++.dg/modules/virt-2_a.C w/gcc/testsuite/g++.dg/modules/virt-2_a.C new file mode 100644 index 00000000000..9115cc19cc2 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/virt-2_a.C @@ -0,0 +1,27 @@ +// { dg-module-do run } +// { dg-additional-options -fmodules-ts } +export module foo; +// { dg-module-cmi foo } + +export struct Visitor +{ + virtual int Visit (); +}; + +// Key function explicitly inline (regardless of p1779's state) +// We emit vtables & rtti only in this TU +inline // Yoink! + int Visitor::Visit () +{ + return 0; +} + +export int Visit (Visitor *v) +{ + return v->Visit (); +} + +// Emit here +// { dg-final { scan-assembler {_ZTV7Visitor:} } } +// { dg-final { scan-assembler {_ZTI7Visitor:} } } +// { dg-final { scan-assembler {_ZTS7Visitor:} } } diff --git c/gcc/testsuite/g++.dg/modules/virt-2_b.C w/gcc/testsuite/g++.dg/modules/virt-2_b.C new file mode 100644 index 00000000000..543218956e9 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/virt-2_b.C @@ -0,0 +1,28 @@ +// { dg-additional-options -fmodules-ts } + +import foo; + +struct Mine : Visitor +{ + int Visit () override + { + return 1; + } +}; + +extern int Foo (); + +int main () +{ + Mine me; + + if (auto b = Foo ()) + return b; + return !(Visit (&me) == 1); +} + +// We do not emit Visitor vtable +// but we do emit rtti here +// { dg-final { scan-assembler-not {_ZTV7Visitor:} } } +// { dg-final { scan-assembler {_ZTI7Visitor:} } } +// { dg-final { scan-assembler {_ZTS7Visitor:} } } diff --git c/gcc/testsuite/g++.dg/modules/virt-2_c.C w/gcc/testsuite/g++.dg/modules/virt-2_c.C new file mode 100644 index 00000000000..1ac7f994792 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/virt-2_c.C @@ -0,0 +1,16 @@ +// { dg-additional-options -fmodules-ts } + +import foo; + +int Foo () +{ + Visitor v; + + return !(Visit (&v) == 0); +} + +// We do emit Visitor vtable +// andl also we do emit rtti here +// { dg-final { scan-assembler {_ZTV7Visitor:} } } +// { dg-final { scan-assembler {_ZTI7Visitor:} } } +// { dg-final { scan-assembler {_ZTS7Visitor:} } } diff --git c/gcc/testsuite/g++.dg/modules/vmort-1_a.C w/gcc/testsuite/g++.dg/modules/vmort-1_a.C new file mode 100644 index 00000000000..aa404dda11a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vmort-1_a.C @@ -0,0 +1,34 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts" } + +export module tom.riddle; +// { dg-module-cmi tom.riddle } + +export inline auto One (int a) +{ + struct X { + int x; + // p1779 makes these things not-inline, which is a surprise. + // Asking CWG + inline X(int a) :x(a){} + inline operator int () const {return x;} + }; + + return X(a); +} + +// Look Ma! this isn't inline! +export auto Two (int a) +{ + struct Y { + int x; + // In this case we do manage to emit these fns (if not marked as + // inline), but we give them internal linkage, so they are not + // nameable from elsewhere. Workaround for now. + inline Y(int a) :x(a){} + inline operator int () const {return x;} + }; + + return Y(a); +} + diff --git c/gcc/testsuite/g++.dg/modules/vmort-1_b.C w/gcc/testsuite/g++.dg/modules/vmort-1_b.C new file mode 100644 index 00000000000..9ba49f130cc --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vmort-1_b.C @@ -0,0 +1,17 @@ +// { dg-additional-options "-fmodules-ts" } + +import tom.riddle; + +int main () +{ + auto one = One (2); + + if (int (one) != 2) + return 1; + + int two = Two (3); + if (two != 3) + return 2; + + return 0; +} diff --git c/gcc/testsuite/g++.dg/modules/vmort-2_a.C w/gcc/testsuite/g++.dg/modules/vmort-2_a.C new file mode 100644 index 00000000000..27d114d86d0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vmort-2_a.C @@ -0,0 +1,15 @@ +// { dg-module-do run } +// { dg-additional-options "-fmodules-ts -fdump-lang-module-graph-blocks" } + +export module voldy; +// { dg-module-cmi voldy } + +export auto frobber (int i) +{ + return [=] (int j) { return i + j; }; +} + +// { dg-final { scan-lang-dump {Connecting definition decl type_decl:'::frobber::._anon_0'} module } } +// { dg-final { scan-lang-dump {Entities 5} module } } + +// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=decl declaration '::frobber'\n \[1\]=decl definition '::frobber::._anon_0'\n( \[.\]=decl [^\n]*'\n)* \[.\]=binding '::frobber'} module } } diff --git c/gcc/testsuite/g++.dg/modules/vmort-2_b.C w/gcc/testsuite/g++.dg/modules/vmort-2_b.C new file mode 100644 index 00000000000..e7376cc4fd7 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vmort-2_b.C @@ -0,0 +1,20 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-graph-blocks" } + +export module malfoy; +// { dg-module-cmi malfoy } + +import voldy; + +void interpose () +{ + // Force renumber of anon vars + auto lambda = [] () {}; +} + +export auto conduit (int i) +{ + return frobber (i); +} + +// { dg-final { scan-lang-dump-not {Cluster import } module } } +// { dg-final { scan-lang-dump-not {onnecting definition decl type_decl:'::frobber@voldy:.::._anon_1@voldy:.'} module } } diff --git c/gcc/testsuite/g++.dg/modules/vmort-2_c.C w/gcc/testsuite/g++.dg/modules/vmort-2_c.C new file mode 100644 index 00000000000..f50c40732fe --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vmort-2_c.C @@ -0,0 +1,21 @@ +// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" } + +import malfoy; + +void interpose () +{ + // Force renumber of anon vars + auto lambda0 = [] () {}; + auto lambda1 = [] () {}; + auto lambda2 = [] () {}; +} + +int main () +{ + auto widget = conduit (2); + + return !(widget (8) == 10); +} + +// { dg-final { scan-lang-dump {Loading entity voldy\[1\] section:1} module } } +// { dg-final { scan-lang-dump {Indirect:-[0-9]* decl's type record_type:'::frobber@voldy:.::._anon_3@voldy:.'} module } } diff --git c/gcc/testsuite/g++.dg/modules/vtt-1_a.C w/gcc/testsuite/g++.dg/modules/vtt-1_a.C new file mode 100644 index 00000000000..11a1f6fb161 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vtt-1_a.C @@ -0,0 +1,36 @@ +// { dg-additional-options "-fmodules-ts -O2 -fno-inline" } + +export module foo; +// { dg-module-cmi foo } + +export struct base +{ + base () {} + virtual ~base (); + int m; +}; + +base::~base () +{ +} + +export struct derived : virtual base +{ + derived () {} + virtual ~derived (); + int m2; +}; + +derived::~derived () +{ +} + +export void make_foo () +{ + base b; + derived d; +} + +// { dg-final {scan-assembler "_ZTV4base:" } } +// { dg-final {scan-assembler "_ZTV7derived:" } } +// { dg-final {scan-assembler "_ZTT7derived:" } } diff --git c/gcc/testsuite/g++.dg/modules/vtt-1_b.C w/gcc/testsuite/g++.dg/modules/vtt-1_b.C new file mode 100644 index 00000000000..2f1b9659a56 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vtt-1_b.C @@ -0,0 +1,28 @@ +// { dg-additional-options "-fmodules-ts -O2 -fno-inline" } + +export module bar; +// { dg-module-cmi bar } + +export import foo; + +export struct mine : derived +{ + mine () {} + ~mine (); + int mm; +}; + +mine::~mine () +{ +} + +export inline void make_bar () +{ + mine m; +} + +// { dg-final {scan-assembler-not "_ZTV4base:" } } +// { dg-final {scan-assembler-not "_ZTV7derived:" } } +// { dg-final {scan-assembler-not "_ZTT7derived:" } } +// { dg-final {scan-assembler "_ZTV4mine:" } } +// { dg-final {scan-assembler "_ZTT4mine:" } } diff --git c/gcc/testsuite/g++.dg/modules/vtt-1_c.C w/gcc/testsuite/g++.dg/modules/vtt-1_c.C new file mode 100644 index 00000000000..9acdd32f03b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vtt-1_c.C @@ -0,0 +1,19 @@ +// { dg-additional-options "-fmodules-ts -O2 -fno-inline" } + +import bar; + +int main () +{ + make_foo (); + make_bar (); + + mine m0; + + return 0; +} + +// { dg-final {scan-assembler-not "_ZTV4base:" } } +// { dg-final {scan-assembler-not "_ZTV7derived:" } } +// { dg-final {scan-assembler-not "_ZTT7derived:" } } +// { dg-final {scan-assembler-not "_ZTV4mine:" } } +// { dg-final {scan-assembler-not "_ZTT4mine:" } } diff --git c/gcc/testsuite/g++.dg/modules/vtt-2.h w/gcc/testsuite/g++.dg/modules/vtt-2.h new file mode 100644 index 00000000000..5ae0db0cb7b --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vtt-2.h @@ -0,0 +1,14 @@ + +class basic_ios +{ +public: + virtual ~basic_ios(); + basic_ios(); +}; + +class basic_ostream : virtual public basic_ios +{ +public: + basic_ostream(); + virtual ~basic_ostream(); +}; diff --git c/gcc/testsuite/g++.dg/modules/vtt-2_a.H w/gcc/testsuite/g++.dg/modules/vtt-2_a.H new file mode 100644 index 00000000000..0e018726fa6 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vtt-2_a.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "vtt-2.h" diff --git c/gcc/testsuite/g++.dg/modules/vtt-2_b.C w/gcc/testsuite/g++.dg/modules/vtt-2_b.C new file mode 100644 index 00000000000..c1ed3d53741 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/vtt-2_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" } + +#include "vtt-2.h" +import "vtt-2_a.H"; + +// { dg-final { scan-lang-dump-not {merge key \(new\)} module } } +// { dg-final { scan-lang-dump-times {merge key \(unique\)} 2 module } }