diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 3f5467c8283..2ea32101f07 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1231,12 +1231,14 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) case CALL_EXPR: /* We have a special meaning for volatile void fn(). */ /* cdtors may return this or void, depending on targetm.cxx.cdtor_returns_this, but this shouldn't affect our - decisions here: neither nodiscard warnings (nodiscard cdtors - are nonsensical), nor should any constexpr or template - instantiations be affected by an ABI property that is, or at - least ought to be transparent to the language. */ + decisions here: neither nodiscard warnings (nodiscard dtors + are nonsensical and ctors have a different behavior with that + attribute that is handled in the TARGET_EXPR case), nor should + any constexpr or template instantiations be affected by an ABI + property that is, or at least ought to be transparent to the + language. */ if (tree fn = cp_get_callee_fndecl_nofold (expr)) - if (DECL_DESTRUCTOR_P (fn)) + if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn)) return expr; if (complain & tf_warning) diff --git a/gcc/testsuite/g++.dg/cpp2a/nodiscard-constructor.c b/gcc/testsuite/g++.dg/cpp2a/nodiscard-constructor1.C similarity index 54% rename from gcc/testsuite/g++.dg/cpp2a/nodiscard-constructor.c rename to gcc/testsuite/g++.dg/cpp2a/nodiscard-constructor1.C index 9af4e59c3dc..6aa33149a0f 100644 --- a/gcc/testsuite/g++.dg/cpp2a/nodiscard-constructor.c +++ b/gcc/testsuite/g++.dg/cpp2a/nodiscard-constructor1.C @@ -1,6 +1,6 @@ /* nodiscard attribute tests */ /* { dg-do compile { target c++20 } } */ -/* { dg-options "-O -ftrack-macro-expansion=0" } */ +/* { dg-options "-O" } */ struct A { [[nodiscard("bad constructor")]] A() {} }; struct B { [[nodiscard]] B() {} }; @@ -8,6 +8,6 @@ struct B { [[nodiscard]] B() {} }; void test (void) { - A{}; /* { dg-warning "(?n)nodiscard.*bad constructor" } */ - B{}; /* { dg-warning "(?n)nodiscard" } */ + A{}; /* { dg-warning "nodiscard\[^\n\r]*bad constructor" } */ + B{}; /* { dg-warning "nodiscard" } */ } diff --git a/gcc/testsuite/g++.dg/cpp2a/nodiscard-constructor2.C b/gcc/testsuite/g++.dg/cpp2a/nodiscard-constructor2.C new file mode 100644 index 00000000000..3abb11847d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nodiscard-constructor2.C @@ -0,0 +1,17 @@ +// PR c++/99362 +// { dg-do compile { target c++20 } } + +struct S { + [[nodiscard]] S() {} + S(int) {} +}; + +int main() +{ + S s; + S(); // { dg-warning "ignoring return value" } + (void)(S()); + S t = 1; + S(1); + (void)(S(1)); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/nodiscard-once.C b/gcc/testsuite/g++.dg/cpp2a/nodiscard-once.C index c95fa1b0741..c533f9cf7d0 100644 --- a/gcc/testsuite/g++.dg/cpp2a/nodiscard-once.C +++ b/gcc/testsuite/g++.dg/cpp2a/nodiscard-once.C @@ -1,6 +1,6 @@ /* nodiscard attribute tests */ /* { dg-do compile { target c++20 } } */ -/* { dg-options "-O -ftrack-macro-expansion=0" } */ +/* { dg-options "-O" } */ [[nodiscard, nodiscard]] int check1 (void); // { dg-warning "specified multiple times" } diff --git a/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason-nonstring.C b/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason-nonstring.C index d81baf0ebcd..091c3e56bd2 100644 --- a/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason-nonstring.C +++ b/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason-nonstring.C @@ -1,6 +1,6 @@ /* nodiscard attribute tests */ /* { dg-do compile { target c++20 } } */ -/* { dg-options "-O -ftrack-macro-expansion=0" } */ +/* { dg-options "-O" } */ [[nodiscard(123)]] int check1 (void); /* { dg-error "nodiscard\[^\n\r]*must be a string constant" } */ diff --git a/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason-only-one.C b/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason-only-one.C index 6104a5ffa08..01fbb37436f 100644 --- a/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason-only-one.C +++ b/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason-only-one.C @@ -1,6 +1,6 @@ /* nodiscard attribute tests */ /* { dg-do compile { target c++20 } } */ -/* { dg-options "-O -ftrack-macro-expansion=0" } */ +/* { dg-options "-O" } */ [[nodiscard("not", "allowed")]] int check1 (void); /* { dg-error "wrong number of arguments.\[^\n\r]*nodiscard" } */